Developers · Python

Live meeting transcript in Python, with who said each line

A Python program that prints each line as it is said, with the speaker, with what it printed when it was run.

Ran on 10 November 2026Language PythonJob Live transcript

What it does

This script prints each line of a meeting as it is said, under the name of the person who said it, for as long as LISTEN_FOR allows — then asyncio.wait_for ends it.

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

# Print every line said in a Meetful meeting, with its speaker, as it is said. pip install websockets
# MEETFUL_KEY=tmk_… MEETING=abc-defg-hij LISTEN_FOR=60 python listen.py
import asyncio, json, os
from datetime import datetime, timezone
import websockets

BASE = os.environ.get("MEETFUL_URL", "https://meetful.com")
LISTEN_FOR = float(os.environ.get("LISTEN_FOR", "60"))

async def listen():
    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":
                print(f"listening in {m['meeting']}…", flush=True)
            elif m["type"] == "transcript":
                line = m["line"]
                at = datetime.fromtimestamp(line["at"] / 1000, timezone.utc).strftime("%H:%M:%S")
                # The speaker is whose microphone the words came from, not a guess.
                print(f"{at}  {line['speaker']}: {line['text']}", flush=True)
            elif m["type"] == "agent-refused":
                raise SystemExit("Refused: " + m["why"])

async def main():
    try:
        await asyncio.wait_for(listen(), LISTEN_FOR)
    except asyncio.TimeoutError:
        pass

asyncio.run(main())

Run it

MEETFUL_KEY=tmk_… MEETING=abc-defg-hij python listen.py

What it printed

listening in jho-bwva-mia…
14:17:03  Dana: Can we move the launch to the third of March?
14:17:04  Sam: Yes, if the docs are ready by the twentieth.
14:17:05  Dana: Then 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

print(..., flush=True) matters when the output goes to a file or a pipe: without it Python holds the lines in a buffer and you see nothing until the script ends.

Each speaker name comes from the microphone the line was spoken into, so a line is never filed under the wrong person. That is the reason to use a meeting's own transcript rather than a recording run through a speaker-guessing model.

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.

Lines appear all at once at the end

Output is buffered. Keep flush=True, or run python -u.

Next

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

The same in Node.js · Go

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.