You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Star2 (2)You must be signed in to star a repository
About
Runnable sample apps for the MeetStream meeting bot API: record, transcribe and stream Zoom, Google Meet and Microsoft Teams meetings, webhooks, calendar auto-join, voice agents, CRM and Slack sync.
MeetStream Labs: meeting bot sample apps for Zoom, Google Meet and Microsoft Teams
Open source, runnable Node.js templates for the MeetStream API, the meeting bot API that joins Zoom, Google Meet and Microsoft Teams calls to record, transcribe, stream and act on them. Every template is a small, complete app: an AI notetaker, a real-time transcription server, a webhook handler, a calendar auto-join, a voice agent that talks in the meeting, a CRM or Slack sync, and so on.
64 templates plus three agent integrations covering every endpoint in the API. Each folder stands alone: clone it, add your API key, run it.
git clone https://github.com/meetstream-ai/labs.git
cd labs/quickstart-first-bot
npm install
cp .env.example .env # add your MEETSTREAM_API_KEY
node index.js
An OpenClaw skill for operating MeetStream bots from the OpenClaw agent
Things every template gets right
These are the details that most commonly go wrong when integrating. Every template here handles them the same way:
Auth is Authorization: Token <key> - the literal word Token, not Bearer.
Every webhook carries event, and most also carry bot_event with the specific name.
Terminals are two-layer. Every ending arrives once as event: "bot.stopped", and bot_event says why: bot.stopped, bot.kicked, bot.notallowed (waiting room timeout), bot.denied (host refused), bot.failed. Lobby timeouts, denials and failures carry status_code: 500. Branch on bot_event: a kick and a clean exit both report bot_status: "Stopped".
Over REST, transcripts are fetched by transcript_id, not bot_id. Segments carry speaker and transcript (not text).
HTTP 202 means "not ready, poll again" - and streaming-only providers return 202 forever, so every poll loop is capped.
HTTP 507 is an idempotent replay and should be treated as success, not an error.
Streaming-only providers produce no post-call transcript (no transcription.processed), but bot.done still fires. bot.done is the final event on every path.
Recording defaults are product policy, not API defaults. Video is off unless you ask for it: every template sends video_required: false explicitly, because the REST API treats an omitted video_required as true. When video is on, the payload also carries recording_config.video_layout: "speaker_view", because grid_view is the API default and speaker view is what people want for review and clipping; grid is used only when you ask for it. And no template sets video_separate_streams unless per-participant video is the point of it, which today means only per-participant-video-recorder (per-participant audio is a separate switch and is unaffected). The exceptions that keep video on by design are video-recording-downloader, per-participant-video-recorder and screenshot-capture, whose screenshots are cut from the video capture.
MIA needs only agent_config_id.socket_connection_url and live_audio_required are for bring-your-own-bridge templates and point at your server.
Prerequisites
Node.js 18 or newer (templates use built-in fetch and ESM)
Have a use case to share? Open a pull request. Templates follow a consistent layout: README.md, .env.example, package.json, .gitignore, index.js, and src/*.js.
Runnable sample apps for the MeetStream meeting bot API: record, transcribe and stream Zoom, Google Meet and Microsoft Teams meetings, webhooks, calendar auto-join, voice agents, CRM and Slack sync.