Skip to main content
Продукт приложения — это курс из уроков, а не из шагов бота. Подписчики проходят его в приложении вашего бота (Telegram Mini App, открывается внутри Telegram), на веб-платформе или и там и там. На обеих платформах одни и те же продукты и уроки, а публикуется каждая платформа отдельно (см. Опубликуйте приложение и веб-платформу). Порядок действий:
  1. Создайте продукт
  2. Создайте уроки
  3. Настройте, когда открываются уроки
  4. Добавьте картинки
  5. Добавьте материалы
  6. Добавьте видео
  7. Сгруппируйте уроки в модули
  8. Включите продукт
  9. Опубликуйте приложение и веб-платформу

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

Понадобится:
  • API-токен — см. Авторизация.
  • ID бота — из Список ботов. Приложение и веб-платформа принадлежат боту.
  • Ваши файлы:
    • картинки (обложки, картинки уведомлений) — JPG, PNG или WebP, до 20 МБ;
    • материалы уроков — до 50 МБ: PDF, DOC, DOCX, XLS, XLSX, PPT, PPTX, TXT, CSV, MP3, MP4, WAV, OGG, ZIP, RAR, JPG, JPEG, PNG, WebP;
    • видео — файлы MP4 для загрузки или ссылки на видео YouTube, Vimeo или Bunny.
В отличие от курса в боте, здесь не нужны токен бота и загрузка в Telegram: картинки и материалы отправляются прямо в API, видео — на видеохостинг. Примеры — это команды для терминала. Сначала задайте переменные; дальше в шагах сказано, какие из полученных ID сохранить в новые переменные:
Отправляйте из скриптов обычный User-Agent. Запросы со стандартным user agent Python urllib блокируются Cloudflare с 403 (error 1010) ещё до API. curl и большинство HTTP-библиотек работают как есть.

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

Сохраните data.id как PRODUCT_ID. platform должен быть miniApp — это продукт приложения (тот же продукт работает и на веб-платформе). Названия продуктов уникальны в пределах бота: на повторяющееся название вернётся 422 name. Новый продукт выключен, вы включите его на шаге 8. Необязательные настройки продукта:

2. Создайте уроки

Уроки создаются через Создать урок. Каждый новый урок добавляется в конец продукта.
Сохраните data.id как LESSON_ID.
Передавайте "active": true. По умолчанию урок создаётся выключенным, а выключенные уроки подписчики не видят — приложение и веб-платформа показывают «0 уроков». Включить урок можно и позже через Включить урок.
  • name — до 255 символов, показывается в списке уроков.
  • text — содержимое урока в HTML: абзацы, жирный, курсив, ссылки, списки. До 4000 символов текста без учёта тегов.
  • access_time — когда открывается урок, см. шаг 3. Если не передать, урок открывается сразу.
  • settings — уведомление, которое отправляется при открытии урока, см. Уведомление об открытии урока.
Изменить урок можно через Обновить урок — меняются только переданные поля. Другие операции с уроками: Изменить порядок уроков (lesson_ids в новом порядке), Дублировать урок, Выключить урок, Удалить урок.

3. Настройте, когда открываются уроки

У каждого подписчика своё расписание. Оно начинается, когда подписчик получает доступ к продукту. Когда для него открывается каждый урок, решает access_time.type:

По порядку: after_previous

Подписчик проходит урок в приложении или на веб-платформе, после этого открывается следующий. Поставьте immediately первому уроку и after_previous остальным, чтобы курс шёл по одному уроку.

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

Отсчитывается от момента получения доступа, а не от предыдущего урока. delay_type — seconds, minutes, hours или days. Для «одного урока в день» дайте уроку N задержку N − 1 дней.

В дату: date

Открывается для всех в этот момент — используйте для запусков. Подписчик, получивший доступ после этой даты, получает урок сразу. Значение без смещения читается как UTC, поэтому передавайте смещение.

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

Открывается в ближайшее после получения доступа время суток из delay_time: сегодня, если это время ещё не прошло, иначе завтра. Используется только время суток; передавайте его со смещением (без него оно читается как UTC). delay_number для этого типа обязателен — передайте 0.

Вручную: never

Урок сам не открывается. Откройте его подписчику через Открыть уроки продукта:
ids — это полный список уроков, открытых этому подписчику: уроки из списка открываются сейчас, а все остальные уроки продукта для него закрываются. Чтобы открыть все уроки, передайте {"ids": [], "all": true}.
Это работает с любым типом access_time — например, чтобы выдать одному подписчику все уроки сразу.

Изменение расписания

Когда вы меняете access_time или включаете и выключаете урок, расписание пересчитывается для подписчиков, у которых уже есть доступ. В идущий курс можно добавлять уроки и менять их порядок. Когда подписчик проходит все уроки, продукт для него завершается.

Уведомление об открытии урока

Бот может отправлять сообщение, когда урок открывается подписчику. Передайте settings при создании или обновлении урока:
  • lesson_open_text — Telegram HTML; {{lesson_name}} и {{product_name}} заменяются названиями урока и продукта. Если пусто, используется стандартный текст на языке бота.
  • lesson_open_button открывает приложение. lesson_open_web_button добавляется, только пока веб-платформа опубликована.
  • lesson_open_button_style, lesson_open_web_button_style — primary, success или danger.
  • Картинка для сообщения — картинка уведомления урока, см. шаг 4.
Сообщение отправляется примерно в течение минуты после открытия урока. Не включайте его для урока, который открывается сразу вместе с доступом: подписчик и так получает сообщение-приглашение.

4. Добавьте картинки

Обе загружаются как multipart с одним file: JPG, PNG или WebP до 20 МБ.
Новая загрузка заменяет предыдущую картинку. Удалить можно через Удалить обложку урока или Удалить картинку открытия урока.

5. Добавьте материалы

Материалы — это файлы или ссылки, которые показываются под уроком. Добавляйте их через Добавить материал урока, по одному за запрос. Файл — multipart file с необязательным отображаемым name (без него показывается имя файла):
Ссылка — name и url (http или https), без файла:
Управляйте ими через Список, Обновить (name, а для ссылок и url), Изменить порядок (media_ids в новом порядке) и Удалить.

6. Добавьте видео

У урока может быть не больше одного видео. Новое видео заменяет текущее.
Файл загружается напрямую на видеохостинг по tus — протоколу загрузки с докачкой, а не через Zenedu API.1. Запросите загрузку через Создать загрузку видео. file_size — точный размер файла в байтах:
Загрузка должна завершиться до expires_at.2. Создайте tus-загрузку. Отправляйте все заголовки из upload.headers в каждом запросе:
Ответ — 201 с заголовком Location. Это может быть путь (/tusupload/…) — тогда он относительно хоста из endpoint. Значения Upload-Metadata закодированы в base64 (filetype video/mp4, title).3. Отправьте файл:
204 означает, что файл загружен. Любая tus-библиотека работает так же: передайте ей endpoint, заголовки и файл.4. Сообщите, что загрузка завершена, через Завершить загрузку видео:
Видео переходит из uploading в processing.
Не пропускайте этот вызов. Без него видео остаётся в uploading и может быть удалено как брошенная загрузка.
5. Дождитесь обработки. Видео само проходит uploading → processing → ready, обычно за несколько минут. Проверяйте через Получить видео урока. ready — видео обработано и воспроизводится; failed — хостинг не смог обработать файл, загрузите его снова.
Удалить видео можно через Удалить видео урока.

7. Сгруппируйте уроки в модули

Модули — необязательные заголовки, которые группируют уроки в приложении и на веб-платформе. Создайте модуль через Создать модуль продукта:

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

Подписчики видят только включённые продукты. Затем выдайте подписчикам доступ — см. Выдать доступ к продукту. С этого момента начинается расписание из шага 3, и подписчик получает сообщение-приглашение.

9. Опубликуйте приложение и веб-платформу

Продукты и уроки показываются на двух платформах: На обеих платформах одни и те же продукты и уроки, и добавлять в них продукты не нужно: в разделе Контент каждой платформы есть все включённые продукты приложения, к которым у подписчика есть доступ. Продукты для бота показываются там, только если в настройках платформы включён show_bot_products. Каждая платформа настраивается и публикуется отдельно: можно запустить только приложение, только веб-платформу или обе.

Черновик и опубликованная версия

У каждой платформы есть черновик и опубликованная версия. Изменения настроек, меню, профиля, логотипа и онбординга попадают в черновик, и подписчики видят их только после публикации. Продукты, уроки и их содержимое в черновик не входят — у подписчиков они меняются сразу.
  1. Сначала вызовите Получить приложение или Получить веб-платформу: вызов подготавливает платформу, если она ещё не настроена, и возвращает is_published, has_changes (черновик отличается от опубликованной версии), app_url и настройки.
  2. Измените черновик.
  3. Опубликуйте: Опубликовать приложение или Опубликовать веб-платформу.
Выключить платформу можно через Снять с публикации приложение или Снять с публикации веб-платформу (DELETE …/publish). Черновик остаётся; подписчики, которые открывают неопубликованную платформу, видят её выключенной.
Публикация приложения меняет бота: меню команд бота выключается, а кнопка меню бота открывает приложение. Снятие приложения с публикации возвращает стандартную кнопку меню. Публикация веб-платформы бота не меняет.

Настройки

Обновить настройки приложения и веб-платформы принимают одни и те же поля, которые задаются для каждой платформы отдельно:
  • brand_name, open_button_name, appearance (system, light, dark), brand_color (#RRGGBB), disable_branding;
  • show_bot_products — показывать в Контенте и продукты для бота;
  • support_type (bot или link) и support_text — пункт «Поддержка»;
  • phone_login_enabled — только для веб-платформы: вход по номеру телефона.
Логотип задаётся для каждой платформы отдельно (логотип приложения, логотип веб-платформы), фавикон — только для веб-платформы (Загрузить фавикон).

Меню и профиль

У каждой платформы свои пункты меню и профиля: Контент, Магазин, Подписки, Поддержка и другие. Можно добавлять свои ссылки и пункт Магазин (создать пункт меню, создать пункт профиля, то же самое под /web), менять порядок, обновлять, переносить между меню и профилем и удалять ссылки. Подписчик без продуктов сначала попадает в Магазин, если в нём есть тарифы, иначе — в Контент.

Онбординг

Экраны онбординга показываются при первом открытии только приложения — см. Создать экран онбординга. У веб-платформы онбординга нет.

Веб-адрес

У веб-платформы есть адрес на поддомене Zenedu. Изменить его можно через Обновить адрес:
  • web_handle — 3–32 символа: строчные латинские буквы, цифры и дефисы, но не в начале и не в конце. Должен быть уникальным; некоторые имена зарезервированы.
  • custom_domain_enabled — открывать веб-платформу на своём домене. Нужна платная подписка Pro, иначе запрос завершится ошибкой. Сам домен подключает поддержка: напишите в @zenedusupportbot.
Текущая ссылка — app_url в Получить веб-платформу.

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

  • Уроки создаются выключенными. Передавайте "active": true или включайте их — иначе подписчики увидят пустой продукт.
  • Расписание начинается с получения доступа. duration и time отсчитываются от момента получения доступа, а не от предыдущего урока. Чтобы уроки шли один за другим, используйте after_previous.
  • Видео готово не сразу. Загруженное видео сначала в uploading, потом в processing, и воспроизводится, когда перейдёт в ready.