Skip to main content
В этом гайде собирается полноценный курс, который проходит внутри вашего Telegram-бота: уроки с видео и картинками, материалы для печати, квизы, вопросы и задания. Курс ждёт подписчика на каждом шаге и идёт дальше только после того, как он нажмёт кнопку, ответит на вопрос или сдаст задание. Порядок действий:
  1. Создайте продукт
  2. Загрузите файлы в Telegram и зарегистрируйте их
  3. Создайте шаги
  4. Настройте, когда отправляется каждый шаг
  5. Включите продукт

Перед началом

Понадобится:
  • API-токен — см. Авторизация.
  • ID бота — из Список ботов.
  • Токен бота из @BotFather — только для загрузки файлов из скрипта. API его никогда не возвращает (только token_hint).
  • Вы запустили бота — Telegram-аккаунт, привязанный к вашему пользователю Zenedu (владельцу API-токена), должен хотя бы раз нажать Start в боте. Эндпоинты файлов проверяют файл, отправляя его в этот чат, и иначе возвращают 409.
  • Для файлов больше 50 МБ — либо api_id и api_hash с my.telegram.org, чтобы загружать их из скрипта, либо человек, который один раз отправит каждый такой файл боту. См. Загрузите файлы.
Примеры — это команды для терминала. Сначала задайте переменные; дальше в шагах сказано, какие из полученных ID сохранить в новые переменные (PRODUCT_ID, OFFER_ID, …):
Отправляйте из скриптов обычный User-Agent. Запросы со стандартным user agent Python urllib блокируются Cloudflare с 403 (error 1010) ещё до API. curl и большинство HTTP-библиотек работают как есть.

1. Создайте продукт

Сохраните data.id как PRODUCT_ID. platform должен быть bot — шаги есть только у продуктов для бота. Новый продукт выключен, вы включите его на шаге 5, когда контент будет готов.

2. Загрузите файлы

Вложения шагов хранятся на серверах Telegram. API не принимает загрузку файлов — он принимает Telegram file_id файла, загруженного этим ботом. Файлы прикрепляются к шагам в два этапа: загрузите файл в Telegram, затем зарегистрируйте его через Зарегистрировать или запросить файл, чтобы получить ID для telegram_file_ids. Загрузить файл в Telegram можно тремя способами. Выбирайте по размеру файла и по тому, что у вас есть:
50 МБ — это лимит только загрузки через Bot API. К шагу можно прикрепить файлы до 2 ГБ. Не сжимайте и не перекодируйте медиа, чтобы уложиться в 50 МБ: для больших файлов используйте MTProto или отправьте файл боту. Если у вас нет ни api_id и api_hash, ни человека, который отправит файл, запросите что-то одно из этого.
Чтобы видео воспроизводились как видео, они должны быть в MPEG4 (.mp4, например видео H.264 со звуком AAC). Другие форматы Telegram может сохранить как document, и регистрация такого файла как video завершится ошибкой type_mismatch.
Отправьте файл через Bot API в свой чат с ботом, возьмите его file_id и удалите сообщение:
Для картинок используйте sendPhoto, для PDF и других файлов — sendDocument. Для видео передавайте width, height, duration и supports_streaming, иначе Telegram может сохранить файл как document, и регистрация его как video завершится ошибкой type_mismatch.У документов подписчики видят имя загруженного файла. Используйте понятное имя: -F "document=@sheet.pdf;filename=Coloring page.pdf".
Не знаете свой CHAT_ID? Один раз вызовите Зарегистрировать или запросить файл с пустым телом — в ответе будет chat_id. Бот заодно попросит прислать файл, это сообщение можно проигнорировать.
Зарегистрируйте каждый file_id:
Сохраните data.id каждого файла, например как VIDEO_FILE_ID и IMAGE_FILE_ID. API проверяет файл: отправляет его в ваш чат и сразу удаляет сообщение, поэтому в чате может что-то мелькнуть. Зарегистрированные файлы остаются в Список Telegram-файлов, пока вы их не прикрепите. Файлы привязаны к пользователю: вы видите и прикрепляете только свои. Ненужный файл удаляется через Удалить Telegram-файл.

3. Создайте шаги

Шаги создаются через Создать шаг продукта. Каждый новый шаг добавляется в конец продукта. Все типы шагов: Урок с видео и картинкой:
В ответе — созданный шаг. Сохраните его data.id (здесь как LESSON_STEP_ID): ID шагов понадобятся для кнопок и sending_time.
Всегда передавайте sending_time. Если его не передать, шаг получит never и никогда не будет отправлен автоматически — в курсе он пропускается. Все варианты — на шаге 4.

Текст

text — это HTML, такой же, как выдаёт редактор в личном кабинете. <p> и <br> превращаются в переносы строк. Теги форматирования передаются в Telegram: <b>/<strong>, <i>/<em>, <u>, <s>, <a href="…">, <code>, <pre>, <blockquote>, <tg-spoiler>. Остальные теги удаляются, а их текст остаётся — например, списки (<ul>, <li>) превращаются в обычные строки. Ограничения длины:
  • 4096 символов — обычное сообщение.
  • 1024 символа — когда у шага есть вложения и settings.attach_file равен true (текст отправляется как подпись к медиа). С attach_file: false (по умолчанию) текст идёт отдельным сообщением после медиа, и действует лимит 4096.
  • 300 символов — poll и quiz (вопрос).

Вложения

telegram_file_ids принимает ID из шага 2. Несколько вложений отправляются вместе альбомом. Переданный набор заменяет вложения шага; чтобы убрать один файл, используйте Удалить вложение шага.

Вопросы

subtype — одно из text, number, email, phone, name. Ответ проверяется по нему; при неверном формате подписчик получает question_error_message и может попробовать снова. Если его не задать, используется стандартное сообщение на языке бота. save_profile: true сохраняет ответ name, email или phone в профиль подписчика.

Опросы и квизы

  • 2–12 вариантов, каждый до 100 символов.
  • У quiz должен быть ровно один is_correct: true, иначе 422 options.
  • quiz_explanation (до 200 символов) показывается после ответа.
  • У poll нет правильного ответа.

Задания

Кнопка сдачи создаётся автоматически с названием на языке бота — не добавляйте её сами. Подписчик нажимает её и отправляет работу в чат.
  • task_autocheck: true — задание принимается при сдаче, и курс сразу идёт дальше.
  • task_autocheck: false — задание ждёт проверки в Список заданий; курс продолжится после того, как вы примете его.

4. Настройте, когда отправляется каждый шаг

У каждого шага есть sending_time. Шаг планируется, когда отправлен предыдущий; первый шаг — когда подписчик получает доступ к продукту. Когда именно, решает sending_time.option: Задайте его при создании шага или позже через Обновить время отправки:
Подписчика ждёт только stop. С любым другим вариантом следующий шаг планируется сразу после отправки предыдущего — даже если подписчик ещё не ответил на вопрос и не сдал задание. Если у всех шагов immediately, весь курс придёт сразу.

Ждать подписчика: stop

Что считается действием на предыдущем шаге: У message и lesson своего действия нет — добавьте им кнопку:
stop принимается, только если у предыдущего шага уже есть действие. Иначе запрос завершится ошибкой 422 sending_time — «Select the action in the previous step». Первый шаг продукта не может быть stop.
Поэтому порядок важен. Либо:
  • создавайте шаги по одному: после каждого message или lesson добавьте ему кнопку, затем создайте следующий шаг со stop; либо
  • создайте все шаги с immediately, добавьте кнопки, затем переключите шаги 2…N на stop через Обновить время отправки.
Типичный курс:

Через время: duration

Задержка отсчитывается от момента отправки предыдущего шага, а для первого шага — от момента получения доступа. delay_type — seconds, minutes, hours или days. После текстового question есть одно исключение: если подписчик отвечает до окончания задержки, отсчёт начинается заново с момента ответа. Ответы на опросы и квизы и сданные задания на задержку не влияют. Чтобы сообщения не приходили ночью или в выходные, добавьте окно отправки (delay_limit, см. ниже).

В заданное время суток: time

  • Из delay_time берётся только время суток, дата игнорируется. Передавайте его со смещением — см. Часовой пояс.
  • delay_number — через сколько дней после отправки предыдущего шага: 0 — в тот же день в это время или на следующий день, если это время уже прошло; 1 — на следующий день; и так далее.
  • delay_limit.weekdays ограничивает дни: в неразрешённый день шаг переносится на ближайший разрешённый день в то же время. time_from и time_to для этого варианта игнорируются.
Например, «каждый урок на следующее утро в 10:00» — это time с delay_number: 1 на каждом уроке.

В дату: date

Шаг отправляется всем подписчикам в один и тот же момент — используйте это для запусков и живых событий. Передавайте delay_at со смещением — см. Часовой пояс.
  • При сохранении активного шага delay_at должен быть в будущем, иначе 422 sending_time — «Change the sending time to a date in the future».
  • Подписчик, который дошёл до шага после этой даты, получает его сразу. С skip_past_date: true шаг вместо этого пропускается, и подписчик переходит к следующему.

Окно отправки: delay_limit

Ограничивает duration определёнными часами и днями (для time применяются только дни):
  • time_from и time_to — минуты от полуночи в часовом поясе проекта: 540 — это 09:00, 1260 — 21:00. Учитываются только целые часы: 570 (09:30) работает как 09:00.
  • time_from больше time_to — ночное окно, например 1320–360 (22:00–06:00).
  • time_from, равный time_to, означает любое время суток; тогда действуют только weekdays.
  • weekdays: mon, tue, wed, thu, fri, sat, sun — хотя бы один.
  • Если шаг выпадает за пределы окна, он переносится на ближайший момент, когда окно открыто в разрешённый день.
  • Окно «любое время во все семь дней» равнозначно отсутствию окна и не сохраняется.

Не отправлять автоматически: never

Шаг в курсе пропускается: подписчики не получают его после предыдущего шага, и следующий шаг идёт сразу за предыдущим. Это значение по умолчанию, если sending_time не передан.

Часовой пояс

Расписание считается в часовом поясе вашего проекта (в личном кабинете: Настройки → Проект → Основное → Часовой пояс; если не задан — UTC): время суток для time, а также часы и дни delay_limit. delay_at и delay_time — значения даты и времени. Значение без смещения читается как UTC, поэтому передавайте смещение часового пояса проекта — например, 10:00:00+02:00 для 10:00 по Киеву зимой. Для time время суток остаётся фиксированным в часовом поясе проекта круглый год.

5. Включите продукт

Когда продукт включён, выдайте подписчикам доступ — см. Выдать доступ к продукту.

Что нужно помнить

  • Язык стандартных текстов. Кнопка задания, её сообщения и стандартные ошибки вопросов создаются на языке бота. Ответы API и сообщения об ошибках всегда на английском.
  • Файлы привязаны к пользователю. Файлы, зарегистрированные с одним API-токеном, нельзя прикрепить токеном другого пользователя.