Виджет 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-modeinline (по умолчанию, iframe в вашем контейнере) или bubble — плавающая кнопка звонка в углу страницы; контейнер не нужен.
data-targetCSS-селектор контейнера. Без него сразу после тега скрипта создаётся блок высотой 520px.
data-room-nameИменованная постоянная комната: все с этим сниппетом встречаются в одной комнате («support»). Владелец ключа входит организатором из кабинета.
data-positionУгол кнопки bubble: bottom-right (по умолчанию) или bottom-left.
data-labelaria-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.2
import 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
  1. В админке WordPress откройте «Плагины → Добавить → Загрузить плагин» и загрузите zip-файл.
  2. Активируйте плагин и откройте «Настройки → Meeto Widget».
  3. Вставьте ключ встраивания (с добавленным в него доменом сайта) — кнопка звонка заработает.

Для встроенного виджета отключите авто-вставку в настройках и добавьте шорткод на любую страницу: [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 заполняет свой контейнер. В узких контейнерах интерфейс автоматически переключается на компактную раскладку.