Meeto Widget: documentación para desarrolladores
El widget es un iframe de meeto.me con un puente postMessage tipado. Solo necesitas una clave pública de integración — crea una en el panel.
Inicio rápido
Elige tu stack, reemplaza YOUR_KEY por tu clave y dale una altura al contenedor — el widget la llena al 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>Paquetes npm: @meeto/embed-core (sin dependencias), @meeto/embed-react, @meeto/embed-vue, @meeto/embed-angular. El script simple widget.js funciona sin ningún paso de compilación.
Parámetros del script
Atributos de la etiqueta <script src="https://meeto.me/widget.js"> (* — obligatorio). Las mismas opciones existen en la API de JavaScript (key, container, room, name, lang, accent, autoJoin, baseUrl) y como atributos del componente web <meeto-room>.
| Parámetro | Descripción |
|---|---|
| data-key* | Clave pública de integración (mk_live_…) del panel. |
| data-mode | inline (predeterminado, iframe en tu contenedor) o bubble: un botón de llamada flotante en la esquina de la página; no se necesita contenedor. |
| data-target | Selector CSS del contenedor. Sin él se crea un bloque de 520 px de alto justo después de la etiqueta del script. |
| data-room-name | Sala con nombre permanente: todos los que tengan este fragmento se reúnen en la misma sala («support»). El propietario de la clave se une como anfitrión desde el panel. |
| data-position | Esquina del botón flotante: bottom-right (predeterminado) o bottom-left. |
| data-label | aria-label del botón flotante (el widget no conoce el idioma de tu sitio). |
| data-room | Código de una sala existente (meeto.me/<code>). Sin él el widget crea una sala por sí mismo y la reutiliza dentro de la pestaña. |
| data-name | Nombre del participante precargado en la sala de espera. |
| data-lang | Idioma de la interfaz del widget (en, ru, de, …). Por defecto — el idioma del navegador del visitante. |
| data-accent | Color de acento, hex (p. ej. #27D6AA). |
| data-auto-join | Omitir la sala de espera y entrar de inmediato (solo salas de puerta abierta; la cámara y el micrófono se activan al empezar). |
| data-base-url | Dirección de Meeto para instalaciones autoalojadas. |
| data-accelerated | Integración preparada para el aislamiento, servida desde call.meeto.me: efectos de cámara más rápidos cuando tu página está aislada de otros orígenes (cabeceras COOP/COEP). Sin esas cabeceras, el widget funciona exactamente igual que la integración predeterminada. |
Los enlaces de sala siguen siendo válidos: cualquier sala del widget también se puede abrir en meeto.me/<code>.
Eventos y métodos
Suscríbete con widget.on(type, handler) (devuelve una función para cancelar la suscripción), la opción onEvent, los props del componente del framework o los CustomEvents meeto:* del elemento <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));| Evento | Payload |
|---|---|
| ready | — — el widget se cargó y se conectó a la página |
| phase | { phase: "prejoin" | "room" | "finished" | "error" } — cambió la pantalla (lobby, call, finished, error) |
| joined | { room, identity } — el visitante se unió a la llamada |
| left | { reason, durationSec } — el visitante salió de la llamada (reason: left, ended, kicked, connection) |
| participants | { count } — cambió el número de participantes |
| error | { code, message } — el widget no puede iniciarse (clave incorrecta, dominio no registrado, …) |
Métodos de la instancia del widget:
| Método | Descripción |
|---|---|
| join(name?) | Unirse a la llamada desde la sala de espera de forma programática (salas de puerta abierta). |
| leave() | Salir de la llamada. |
| setMicrophone(on) | Activar o desactivar el micrófono durante la llamada. |
| setCamera(on) | Activar o desactivar la cámara durante la llamada. |
| destroy() | Eliminar el iframe y todas las suscripciones. |
En una sala donde hay que llamar para entrar, con contraseña o bloqueada, join() deja al visitante en la sala de espera y el widget emite error con el código join_not_allowed — en su lugar, deja que el visitante entre desde la sala de espera.
API de servidor
Para flujos del lado del servidor (crear salas desde tu backend, enviar enlaces por correo, decidir quién será el anfitrión) usa la clave secreta mk_secret_… — se muestra una vez al crear la integración:
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 convierte a quien la posee en anfitrión de la sala: pasa la sala al widget mediante data-room y entrega hostSecret solo a tu propio personal. Las solicitudes con la clave secreta omiten la comprobación de dominio — nunca la expongas en el código del navegador.
La API versionada (/api/v1) está disponible en el plan Pro: las solicitudes con la clave de una cuenta Free reciben 402 plan_required. El widget en sí funciona en todos los planes.
SDK móviles (iOS / Android)
Los wrappers nativos incrustan el mismo widget en tu app: un WebView con un puente tipado de eventos/comandos. Registra el origen de la app app://<bundle-id> en los dominios de la clave.
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; añade NSCameraUsageDescription y NSMicrophoneUsageDescription a 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"))Módulo de Gradle; declara CAMERA / RECORD_AUDIO / INTERNET y solicita los permisos en tiempo de ejecución antes de mostrar el widget.
Los eventos (ready, joined, left, participants, error) y los comandos (join, leave, setMicrophone, setCamera) son idénticos a los del SDK web.
Código fuente y versiones: meeto-app/meeto-widget-ios ↗meeto-app/meeto-widget-android ↗
Plugin de WordPress
Añade el widget a un sitio WordPress sin escribir código: un botón de llamada flotante en cada página o una llamada insertada mediante un shortcode.
Descargar meeto-widget.zip- En la administración de WordPress, abre Plugins → Añadir nuevo → Subir plugin y sube el zip.
- Activa el plugin y abre Ajustes → Meeto Widget.
- Pega tu clave de integración (con el dominio de tu sitio añadido) — el botón de llamada queda activo.
Para un widget insertado, desactiva la inserción automática en los ajustes y coloca el shortcode en cualquier página: [meeto_widget room_name="support" height="600"]
Límites
Las salas del widget siguen el plan del propietario de la clave:
- Gratis — hasta 10 participantes, llamadas grupales de hasta 60 minutos, hasta 1080p.
- Pro — hasta 25 participantes, sin límite de tiempo para 2 reuniones simultáneas y hasta 4K en equipos de escritorio compatibles. La marca de Meeto sigue visible.
Seguridad
- La clave pública no es un secreto: es visible en el código fuente de tu página, y así está diseñado.
- El widget solo funciona en los dominios registrados para la clave. El navegador informa del origen del sitio que lo incrusta de una forma que las páginas no pueden falsificar (postMessage event.origin), y el backend de Meeto lo comprueba.
- La clave secreta mk_secret_… se almacena con hash y se muestra solo una vez. Úsala exclusivamente de servidor a servidor.
- Una clave filtrada o sin uso puede revocarse en el panel en cualquier momento — el widget se detiene al instante.
Preguntas frecuentes
¿Qué frameworks son compatibles?
Cualquiera. HTML puro con widget.js, React/Next.js, Vue/Nuxt y Angular con paquetes npm, y todo lo demás con el componente web <meeto-room>.
¿Funciona con un Meeto autoalojado?
Sí: apunta data-base-url (o la opción baseUrl) a tu instalación.
¿Puedo quitar «Powered by Meeto»?
No. La insignia «Powered by Meeto» sigue visible en todos los planes, incluidos Pro y Team.
¿Qué tamaños admite el widget?
Cualquiera: el iframe llena su contenedor. En contenedores estrechos la interfaz cambia automáticamente al diseño compacto.