Your Telegram AI Assistant Can Email Anyone as You: 6 Checks to Run Before the Model Does
Picture the assistant: you hold the mic in Telegram, say "find 30 minutes with Sara on Thursday and email her the options", and a minute later the email is in her inbox. n8n makes that easy. A Telegram Trigger, a Whisper transcription, an AI Agent with Gmail and Calendar tools, and you're most of t

Picture the assistant: you hold the mic in Telegram, say "find 30 minutes with Sara on Thursday and email her the options", and a minute later the email is in her inbox. n8n makes that easy. A Telegram Trigger, a Whisper transcription, an AI Agent with Gmail and Calendar tools, and you're most of the way there.
Notice what you just built, though: a bot that can send email as you, triggered by anyone who can reach a webhook. The model is the least interesting risk here. The interesting ones happen before the model runs.
I built this with n8n plus a small ASP.NET Core API (.NET 10) that makes the decisions I don't want a model to make. The general steps below are the ones that matter. Code is trimmed to the shape.
Tech Skill Builder is $5/month for a very limited time (normally $10) — grab it now before it goes back to $10. Complete, tested.NET + AI projects with full source and PDF guides. 👉 Join Tech Skill Builder
Telegram Trigger -> guard API (allowed?) -> voice or text? voice -> download -> Whisper -> prompt text ----------------------> prompt prompt -> AI Agent (tools: contacts, calendar, free slots, email) -> reply on Telegram Enter fullscreen mode Exit fullscreen mode The first node after the trigger asks the API one question: may this update run at all? Everything that costs money or has side effects sits behind the answer. Here are six checks, in roughly the order a message meets them. The first four live in that guard; the last two protect the tools the agent calls.
The Telegram Trigger already checks the secret token, and in my local run the webhook was registered with it. That proves the request came from Telegram. It does not prove you wrote the message. Anyone on Telegram can message your bot.
So: an allowlist of chat IDs, and everyone else is ignored without a reply. A reply tells a stranger the bot exists and is listening.
Telegram retries a delivery when it doesn't get a fast 2xx (a restart, a slow node, a proxy hiccup). A retried "email Sara the report" is two emails.
Remember each update_id for a window and let only the first one through. Two retries can land at the same moment, so a "check, then add" pair isn't enough. It needs one atomic operation:
// one atomic step, not "if (!seen.Contains(id)) seen.Add(id)" if (! _seen. TryAdd ( updateId, now )) { // already there: duplicate inside the window, or expired and re-added (omitted) } Enter fullscreen mode Exit fullscreen mode The test I trust here fires the same update many times in parallel and expects exactly one to pass.
After an hour of downtime you don't want ten queued commands to fire at once. n8n's trigger can drop pending updates when you re-publish (in my local run it registered the webhook with drop_pending_updates ), but I still compare the message date with the clock and refuse anything older than ten minutes (a setting).
A 20-minute voice note isn't a command, it's a transcription bill. Read the duration from the update and refuse before downloading anything. In my setup the limit is 120 seconds, and the bot answers "please keep it under 2 minutes".
public GuardDecision Evaluate ( TelegramUpdate update ) { //... bot check, allowlist, duplicate, age (the checks above, in this order) if ( m. Voice is { } voice && voice. Duration > o. MaxVoiceSeconds ) return new ( false, "voice_too_long", m. Chat. Id ); //... allowed: return kind, text or voice file id } Enter fullscreen mode Exit fullscreen mode The order matters: cheap checks first, anything that costs money last.
Ask a model to email Omar and it may produce omar@company.com with total confidence. Make the contact lookup a tool, and make its answer one of three: found, ambiguous, not_found. The system prompt then says: never guess an address; on anything but found, ask which person and stop.
In my run, a voice note saying "book 30 minutes with Omar" ended with the bot asking which of the two Omars I meant, and nothing was sent.
Models send "2026-10-29T10:00:00", no offset. Deserialize that into a DateTimeOffset and you get the server's offset. I checked: on a box with TZ=UTC it parsed as 10:00+00:00, three hours off for an assistant living in Cairo.
So the API takes the time as a string, and treats an offset-less value as the assistant's own zone:
local = DateTime. SpecifyKind ( local, DateTimeKind. Unspecified ); // handle a time that doesn't exist (spring-forward gap): omitted var utc = TimeZoneInfo. ConvertTimeToUtc ( local, zone ); Enter fullscreen mode Exit fullscreen mode The same goes for working hours: convert them to UTC per day, not once from the first day's offset. A clock change between two days is where the shortcut breaks. When I swapped the per-day conversion for the shortcut, exactly two tests failed, which is how I know the tests cover it.
The API has 43 passing xUnit tests. I also ran the whole n8n workflow locally (n8n 2.43.8) against the real API, with a fake Telegram, OpenAI and Google. It covered a text request, a Telegram retry (ignored), a voice note about an ambiguous contact, a voice note that was too long, a stranger's chat (ignored) and a missing or wrong secret token (HTTP 403).
What I didn't check: real Telegram, real Whisper, real Gmail and Calendar (no credentials, so those nodes were only validated against n8n's node schemas), and how well a real model picks tools. The dedup store is in memory, so with more than one instance you'd move it to Redis or a database key.
If you'd rather start from a finished Telegram assistant than wire the nodes yourself, the n8n Workflow Vault is $29 one-time: the AI Phone-Calling Personal Assistant for Telegram (voice and text, Whisper, Google Sheets contacts, phone, email and calendar agents), the Ultimate n8n Workflow Pack with 2,000+ templates, the multi-agent orchestration workflow and the UGC ad video generator. You bring your own API keys. The guard API from this post is a separate demo and is not part of the Vault.
And if you learn best from complete code you can run, Tech Skill Builder is $5/month for a very limited time (normally $10) — grab it now before it goes back to $10. You get complete, working, tested.NET + AI projects with full source code and step-by-step PDF guides, and new ones are added regularly. 👉 Join Tech Skill Builder
Which of these six would your bot fail first?