Blog
Export a Telegram chat to JSON and turn it into a NotebookLM (Gemini Notebook) knowledge base
A long group chat is a knowledge base nobody can read. Somewhere in three years of an expat group is the answer to how long the tax office took, which form replaced the old one, which accountant people stopped recommending. Telegram search finds a word you already know. It cannot answer a question.
NotebookLM can — once the chat is inside it as sources. This post walks through getting a whole Telegram chat in, and keeping it current, with source-lm.
Export a Telegram chat to JSON in Telegram Desktop
Export exists only in Telegram Desktop (Windows, macOS, Linux) — the application, not the web version, and the phone apps do not have it. Telegram describes the feature in its export announcement.
- Open the chat in Telegram Desktop.
- Open the ⋮ menu in the chat and choose Export chat history.
- Under Media export settings, untick Photos, Videos, Voice messages, Video messages, Stickers, GIFs and Files — the extension takes text only, and media makes the export slow and large for nothing.
- Under Location and format, open the format picker and choose Machine-readable JSON.
- Leave the From: … to: … row at its defaults — the oldest message to present — for the first export.
- Click Export. Telegram writes a folder with a single
result.jsonin it.
If you signed in to Telegram Desktop just now, the export waits 24 hours unless you confirm the request from another device — Telegram’s note on it.
That file has the chat’s name at the root and a messages array — one object
per message with id, date, from, text, and for formatted messages a
text_entities list.
What source-lm does with it
Open the notebook in NotebookLM or Gemini Notebook, open the source-lm popup on
the JSON tab, pick result.json. Before anything uploads, Preview shows the
files it will create:
- It finds the
messagesarray and uses the chat’snameas the filename prefix, slugified. - Each message’s
datebecomes the file’s cursor;textbecomes the body; sender, ids and reply links go under a Metadata heading after it. - Messages are packed in order into Markdown files, budgeted at 400,000 words of rendered Markdown each — a margin under NotebookLM’s 500,000-word limit per source. A message is never split across two files.
The first file of the run below is named like this:
nomad-001-2023-06-05t15-33-12-1.md
Prefix, file index, the date of the last message in the file, the first message’s id. The index and the date are what make the next run possible.
The whole conversion happens inside the popup. The files are built in memory and sent to the notebook’s own origin — the same host you are signed into. Nothing is written to disk and nothing goes to a server of ours; there is none.
A real run
One chat, exported with the steps above: result.json, 19.78 MB. The popup
packed it into four Markdown files, 10.54 MB in total, and uploaded them in one
go — “uploaded 4, failed 0”.

nomad-001-2023-06-05t15-33-12-1.md— 2.88 MB, 399,476 words, 1133 messagesnomad-002-2024-06-27t14-16-23-1313.md— 2.75 MB, 399,532 words, 914 messagesnomad-003-2025-06-30t14-31-49-…nomad-004-2026-08-20t19-45-24-…
Two things to read off the names. The word counts land just under the 400,000 budget while the message counts differ — the budget is words, and a file closes at the last whole message that fits. And the dates run from 2023-06-05 to 2026-08-20: about three years of chat, four sources.

Next month: export again, run again
Chats grow. Re-export the same chat, pick the new result.json, run the same
notebook again. The popup reads the file names already in the Sources panel,
finds the last cursor, and uploads only the messages after it.
You do not have to re-export the whole history every time. The export dialog in Telegram Desktop has a From: … to: … row — set From to roughly the date of your last export and the file stays small. Overlap is fine: the cursor is a date, so anything already in the notebook is skipped either way.
In a test run on a fixture chat: four files in the notebook, ten new messages
in the export → one new file, …-005-…. Nothing re-uploaded, no duplicates to
delete.
One rule: do not rename the files in the notebook. The prefix and the date in the name are the state — there is no local watermark to fall back on.
What to ask
Questions that a word search cannot answer and a notebook over the full history can:
- “What did people say about registering as autónomo, in order, and what changed over time?”
- “Which providers were recommended more than once, and by whom?”
- “Summarise every thread about health insurance, with the dates.”
- “What questions came up repeatedly that never got a clear answer?”
The citations point back into the Markdown, where the sender and the reply chain sit in the Metadata block under each message.
Limits
- Text only. A photo, voice message or sticker with no caption becomes an empty entry with the media file’s path in its metadata. Captions come through.
- Formatting is flattened. A link, a bold run or a code span comes through as its plain words; a hyperlink on a word keeps the word, not the URL.
- Service messages — joins, pins, title changes — come through as near-empty entries with the action in metadata.
- Sender and time are in the Metadata block under each message, not on the line itself; the date there is the Unix timestamp from the export.
- NotebookLM’s own caps apply — sources per notebook on your plan, and 500,000 words per source. The 400,000-word budget keeps each file under the latter; the former is on Google’s side. See NotebookLM (Gemini Notebook) limits for the per-plan numbers.
- Free tier: 5 bulk uploads a calendar month. One chat export is one. After that it is $29, once.
Not affiliated with Google. NotebookLM and Gemini are Google trademarks; this is an independent extension that automates a signed-in session.
Get source-lm — the free tier covers a chat a month.