On-demand email newsletter summaries from Gmail to Telegram with GPT-4.1-mini
Summary Send a number to your Telegram bot (e.g., 2) and get a neatly formatted digest of all Gmail newsletters received since that date. Each email is summarized by an LLM into concise topics, merged into a single Te...
Template notes
Summary Send a number to your Telegram bot (e.g., 2) and get a neatly formatted digest of all Gmail newsletters received since that date. Each email is summarized by an LLM into concise topics, merged into a single Telegram message, automatically split into chunks to fit Telegram limits, and safely formatted as HTML.
What this workflow does - Triggers on your Telegram message containing a number of days, e.g., 1, 2, 7 - Fetches all Gmail messages since that date using a custom search query, optionally filtered by senders - Retrieves and decodes each email’s HTML, subject, sender name, date - Prompts an LLM (GPT‑4.1‑mini) to produce a consistent JSON summary of topics per email - Merges topics from all emails into a single digest - Builds a readable, enumerated message (with bold titles) - Splits it into 3 500‑char parts and sanitizes Markdown to Telegram‑safe HTML - Sends the digest to your Telegram chat with preview disabled
Apps and credentials - Gmail OAuth2: Gmail account - Telegram: Telegram account (bot) - OpenAI: OpenAi account
Typical use cases - Personal or team daily/weekly newsletter digests in Telegram - Curated feeds from selected senders compiled on demand - Lightweight knowledge briefings without leaving Telegram
How it works (node-by-node) - Telegram Trigger - Waits for your message (e.g., "2"). Chat ID is restricted to your Telegram ID for safety. - Get days (Code) - Takes the numeric daysAgo from the Telegram message text - Computes YYYY/MM/DD for Gmail’s after: filter - Get many messages (Gmail → getAll, returnAll: true) - Uses a custom q filter like: =(from:@.com) OR (from:@.com) OR (from:@.com -"") after:{{ $json.dateString }} - Returns a list of message IDs - Loop Over Items (Split in Batches) - Iterates through each message ID - Get a message (Gmail → get) - Retrieves the full message/payload for the current email - Get message data (Code) - Extracts HTML from Gmail’s payload (body/parts) - Normalizes sender to just the name - Formats the date as DD.MM.YYYY - Passes html, subject, from, date forward - Clean (Code) - Converts DD.MM.YYYY → MM.DD (for prompt brevity) - Passes html, subject, from, date to the LLM - Message a model (OpenAI, model: gpt‑4.1‑mini, JSON output) - Prompt instructs: - Produce JSON: { "topics": [ { "title", "descr", "subject", "from", "date" } ] } - Split multi-news blocks into separate topics - Combine or ignore specific blocks for particular senders (placeholders ) - Keep subject untranslated; other values in language - Injects subject/from/date/html from the current email - Loop Over Items (continues) - After all iterations complete, the aggregated per-email results are available - Merge (Code) - Flattens the topics arrays from all processed emails into one combined topics list - Create TG message (Code) - Renders an enumerated list: - 1. Title (bold) - Short description - Original subject - From — Date - Split (Code) - Splits into 3 500‑character chunks to stay below Telegram’s 4 096 limit with HTML overhead - Sanitize (Code) - Escapes &, <, > - Fixes unbalanced and - Converts basic Markdown markers to Telegram HTML - Send a message (Telegram) - Sends each part with parsemode=HTML, previews disabled
Node map | Node | Type | Purpose | |---|---|---| | Telegram Trigger | Trigger | Receive daysAgo command from Telegram | | Get days | Code | Compute Gmail after:YYYY/MM/DD from daysAgo | | Get many messages | Gmail (getAll) | Search emails since date with custom from: filters | | Loop Over Items | Split in Batches | Iterate messages one-by-one | | Get a message | Gmail (get) | Fetch full message payload | | Get message data | Code | Extract HTML/subject/from/date; normalize sender and date | | Clean | Code | Reformat date and forward fields to LLM | | Message a model | OpenAI | Summarize email into JSON topics | | Merge | Code | Merge topics from all emails | | Create TG message | Code | Build human-friendly digest text | | Split | Code | Chunk into 3 500‑char parts | | Sanitize | Code | Escape HTML and map Markdown to Telegram HTML | | Send a message | Telegram | Deliver digest to Telegram chat |
Before you start - Create a Telegram bot and get its token (via @BotFather) - Get your Telegram user ID to restrict access - Connect Gmail OAuth2 in n8n - Add your OpenAI API key - Import the provided workflow JSON into n8n
Setup instructions 1) Telegram - Telegram Trigger node: - additionalFields.chatIds = your Telegram user ID - Send a message node: - chatId = your Telegram user ID - parsemode = HTML - disablewebpagepreview = true