Виджет Meeto: документация для разработчиков
Виджет — это iframe meeto.me с типизированным postMessage-мостом. Всё, что нужно, — публичный ключ встраивания: создайте его в кабинете.
Быстрый старт
Выберите свой стек, замените YOUR_KEY на свой ключ и задайте контейнеру высоту — виджет заполняет его на 100%.
<div id="meeto-call" style="height: 520px"></div>
<script src="https://meeto.me/widget.js" data-key="YOUR_KEY" data-target="#meeto-call"></script>npm-пакеты: @meeto/embed-core (без зависимостей), @meeto/embed-react, @meeto/embed-vue, @meeto/embed-angular. Обычный скрипт widget.js работает вовсе без сборки.
Параметры скрипта
Атрибуты тега <script src="https://meeto.me/widget.js"> (* — обязательный). Те же опции есть в JavaScript API (key, container, room, name, lang, accent, autoJoin, baseUrl) и как атрибуты веб-компонента <meeto-room>.
| Параметр | Описание |
|---|---|
| data-key* | Публичный ключ встраивания (mk_live_…) из кабинета. |
| data-mode | inline (по умолчанию, iframe в вашем контейнере) или bubble — плавающая кнопка звонка в углу страницы; контейнер не нужен. |
| data-target | CSS-селектор контейнера. Без него сразу после тега скрипта создаётся блок высотой 520px. |
| data-room-name | Именованная постоянная комната: все с этим сниппетом встречаются в одной комнате («support»). Владелец ключа входит организатором из кабинета. |
| data-position | Угол кнопки bubble: bottom-right (по умолчанию) или bottom-left. |
| data-label | aria-label кнопки bubble (виджет не знает язык вашего сайта). |
| data-room | Код существующей комнаты (meeto.me/<код>). Без него виджет сам создаёт комнату и переиспользует её в рамках вкладки. |
| data-name | Имя участника, подставляемое в лобби. |
| data-lang | Язык интерфейса виджета (ru, en, de, …). По умолчанию — язык браузера посетителя. |
| data-accent | Акцентный цвет, hex (например #27D6AA). |
| data-auto-join | Пропустить лобби и войти сразу (только комнаты с открытой дверью; камера и микрофон включены). |
| data-base-url | Адрес Meeto для self-host инсталляций. |
| data-accelerated | Встраивание с домена call.meeto.me, готовое к изоляции: эффекты камеры работают быстрее, если ваша страница изолирована от сторонних источников (заголовки COOP/COEP). Без этих заголовков виджет работает точно так же, как обычное встраивание. |
Ссылки на комнаты остаются рабочими: любую комнату виджета можно открыть и по адресу meeto.me/<код>.
События и методы
Подписка — через widget.on(type, handler) (возвращает функцию отписки), опцию onEvent, пропсы компонентов фреймворков или CustomEvent meeto:* элемента <meeto-room>.
const widget = new MeetoWidget({ key: "mk_live_…", container: "#call" });
const off = widget.on("joined", (e) => console.log(e.room));
widget.on("participants", (e) => console.log("in call:", e.count));| Событие | Данные |
|---|---|
| ready | — — виджет загрузился и связался со страницей |
| phase | { phase: "prejoin" | "room" | "finished" | "error" } — сменился экран (лобби, звонок, финал, ошибка) |
| joined | { room, identity } — посетитель вошёл в звонок |
| left | { reason, durationSec } — посетитель вышел из звонка (reason: left, ended, kicked, connection) |
| participants | { count } — изменилось число участников |
| error | { code, message } — виджет не может запуститься (неверный ключ, незарегистрированный домен, …) |
Методы экземпляра виджета:
| Метод | Описание |
|---|---|
| join(name?) | Войти в звонок из лобби программно (комнаты с открытой дверью). |
| leave() | Выйти из звонка. |
| setMicrophone(on) | Включить/выключить микрофон в звонке. |
| setCamera(on) | Включить/выключить камеру в звонке. |
| destroy() | Удалить iframe и все подписки. |
В комнате со входом по стуку, по паролю или с закрытым входом join() оставляет посетителя в лобби, а виджет присылает событие error с кодом join_not_allowed — пусть посетитель войдёт из лобби сам.
Серверный API
Для серверных сценариев (создавать комнаты со своего бэкенда, рассылать ссылки, решать, кто станет организатором) используйте секретный ключ mk_secret_… — он показывается один раз при создании встраивания:
curl -X POST https://api.meeto.me/api/embed/rooms \
-H "Authorization: Bearer mk_secret_…"
# → 201 { "slug": "misty-fox-42", "hostSecret": "…" }curl -X POST https://api.meeto.me/api/v1/meetings \
-H "Authorization: Bearer mk_secret_…" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: appointment-872" \
-d '{
"title": "Project review",
"startsAt": "2027-03-22T10:00:00+02:00",
"durationMin": 45,
"timezone": "Europe/Tallinn"
}'
# → 201 { "meeting": { "id": "…", "joinUrl": "https://meeto.me/…?k=…" }, "hostSecret": "…" }
curl https://api.meeto.me/api/v1/meetings \
-H "Authorization: Bearer mk_secret_…"hostSecret делает своего обладателя организатором комнаты: передайте комнату виджету через data-room, а hostSecret выдавайте только своим сотрудникам. Запросы с секретным ключом не проверяются по доменам — никогда не публикуйте его в браузерном коде.
Версионный API (/api/v1) доступен на тарифе Pro: запросы с ключом бесплатного аккаунта получают 402 plan_required. Сам виджет работает на любом тарифе.
Мобильные SDK (iOS / Android)
Нативные обёртки встраивают тот же виджет в ваше приложение: WebView с типизированным мостом событий и команд. Зарегистрируйте origin приложения app://<bundle-id> в доменах ключа.
iOS (Swift Package, iOS 14+)
// Xcode → File → Add Package Dependencies…
https://github.com/meeto-app/meeto-widget-ios.git // from: 0.1.2import MeetoWidget
MeetoWidget(config: .init(key: "mk_live_…", roomName: "support")) { event in
if event.type == "left" { /* close the screen */ }
}Swift Package; добавьте NSCameraUsageDescription и NSMicrophoneUsageDescription в Info.plist.
Android (Kotlin, minSdk 24)
// settings.gradle.kts
dependencyResolutionManagement { repositories { maven("https://jitpack.io") } }
// module's build.gradle.kts
dependencies { implementation("com.github.meeto-app:meeto-widget-android:0.1.3") }val widget = MeetoWidgetView(this)
widget.onEvent = { event -> if (event.type == "left") finish() }
container.addView(widget)
widget.load(MeetoWidgetConfig(key = "mk_live_…", roomName = "support"))Gradle-модуль; объявите CAMERA / RECORD_AUDIO / INTERNET и запросите runtime-разрешения до показа виджета.
События (ready, joined, left, participants, error) и команды (join, leave, setMicrophone, setCamera) идентичны веб-SDK.
Исходный код и релизы: meeto-app/meeto-widget-ios ↗meeto-app/meeto-widget-android ↗
Плагин для WordPress
Добавьте виджет на сайт WordPress без единой строчки кода: плавающая кнопка звонка на каждой странице или встроенный звонок через шорткод.
Скачать meeto-widget.zip- В админке WordPress откройте «Плагины → Добавить → Загрузить плагин» и загрузите zip-файл.
- Активируйте плагин и откройте «Настройки → Meeto Widget».
- Вставьте ключ встраивания (с добавленным в него доменом сайта) — кнопка звонка заработает.
Для встроенного виджета отключите авто-вставку в настройках и добавьте шорткод на любую страницу: [meeto_widget room_name="support" height="600"]
Лимиты
Комнаты виджета живут по тарифу владельца ключа:
- Бесплатно — до 10 участников, групповые звонки до 60 минут, до 1080p.
- Pro — до 25 участников, без лимита времени для 2 одновременных встреч и до 4K на поддерживаемых десктопах. Брендирование Meeto остаётся видимым.
Безопасность
- Публичный ключ — не секрет: он виден в исходнике вашей страницы, так и задумано.
- Виджет работает только на доменах, зарегистрированных для ключа. Браузер сообщает origin встраивающего сайта неподделываемо (event.origin postMessage), и бэкенд Meeto его проверяет.
- Секретный ключ mk_secret_… хранится хэшем и показывается один раз. Используйте его только server-to-server.
- Утёкший или ненужный ключ можно отозвать в кабинете в любой момент — виджет мгновенно перестанет работать.
Вопросы и ответы
Какие фреймворки поддерживаются?
Любые. Чистый HTML — через widget.js, React/Next.js, Vue/Nuxt и Angular — через npm-пакеты, всё остальное — через веб-компонент <meeto-room>.
Работает ли с self-host Meeto?
Да: укажите data-base-url (или опцию baseUrl) на вашу инсталляцию.
Можно ли убрать «Powered by Meeto»?
Нет. Бейдж «Powered by Meeto» показывается на всех тарифах, включая Pro и Team.
Какие размеры поддерживает виджет?
Любые: iframe заполняет свой контейнер. В узких контейнерах интерфейс автоматически переключается на компактную раскладку.