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.
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/keysThe 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.