Developers · Python

Make a meeting bot speak, from Python

A Python program that says something in the meeting, with what it printed when it was run.

Ran on 10 November 2026Language PythonJob Speak

What it does

The script waits for agent-ready, sends one say, and prints the server's agent-said confirmation before leaving. What it says comes from the command line.

It needs a key and a meeting code in MEETFUL_KEY and MEETING. Two curl requests make both. MEETFUL_URL is optional and defaults to https://meetful.com.

Python 3.9 or later. The socket scripts use the websockets package (pip install websockets; this ran with 13.1); the transcript script uses only the standard library.

The code

# Say something in a Meetful meeting from Python. pip install websockets
# MEETFUL_KEY=tmk_… MEETING=abc-defg-hij python speak.py "Noted: the launch moves to the third of March."
import asyncio, json, os, sys
import websockets

BASE = os.environ.get("MEETFUL_URL", "https://meetful.com")
TEXT = sys.argv[1] if len(sys.argv) > 1 else "Hello from Python."

async def main():
    async with websockets.connect(BASE.replace("http", "ws", 1)) as ws:
        await ws.send(json.dumps({"type": "agent-hello", "key": os.environ["MEETFUL_KEY"], "meeting": os.environ["MEETING"]}))
        async for raw in ws:
            m = json.loads(raw)
            if m["type"] == "agent-ready":
                await ws.send(json.dumps({"type": "say", "text": TEXT}))
            elif m["type"] == "agent-said":
                print(f"{m['by']} said: {m['text']}" + (" (read aloud)" if m.get("audio") else ""))
                return
            elif m["type"] in ("agent-error", "agent-refused"):
                raise SystemExit(f"{m['type']}: {m.get('why')}")

asyncio.run(main())

Run it

MEETFUL_KEY=tmk_… MEETING=abc-defg-hij python speak.py "Noted: the launch moves to the third of March, and Sam owns the docs."

What it printed

🤖 python bot said: Noted: the launch moves to the third of March, and Sam owns the docs.

Run on 10 November 2026 against a Meetful server built from the same code as meetful.com, with two people — Dana and Sam — in the meeting saying three lines. Nothing above was edited.

How it works

Sending inside the async for loop is fine with websockets: the loop is waiting for the next message, and send is awaited on the same connection.

agent-said reports the text exactly as it was added to the transcript. The audio field is filled on a server that can speak; the server this ran on had no voice key, so it stayed empty.

What can go wrong

Refused: no such key — mint one with POST /api/keys

The key is wrong, or was never minted on this server. A key from one Meetful server does not work on another.

agent-error: …

Too many says in a row, or text the room will not take. The why says which.

Next

In Python: join a meeting · live transcript · get the transcript

The same in Node.js · Go · curl

The whole API · Every socket message and webhook · All guides

Try Meetful

Meetings that take their own notes

Free video meetings in the browser: every line of the transcript under the name of who said it, and the summary and action items when you hang up. Nothing to install — guests just open the link.