How to Build a Telegram Bot with n8n

How to Build a Telegram Bot with n8n: Commands, Notifications, and Interactive Menus

I use Telegram for almost everything. Talking to clients, coordinating with teams, quick file sharing. So when I wanted to build a bot that could pull live data, send automated alerts, and respond to custom commands, I did not want to write a Python script and host it on some server I would forget about. I wanted something visual, maintainable, and powerful.

That is exactly what n8n gave me. In this tutorial, I am going to show you how I built a fully functional Telegram bot using n8n that handles commands, sends rich notifications, and even has interactive inline menus. No traditional coding required.

Why Build a Telegram Bot with n8n?

Telegram bots are incredibly versatile. They can serve as personal assistants, team notification systems, customer support interfaces, or data lookup tools. But building one traditionally means writing code, setting up a server, and managing deployment.

With n8n, you get a visual workflow builder that handles all the Telegram API complexity for you. Here is why I prefer this approach:

Visual logic flow. You can see exactly how your bot processes messages and commands.
Built-in Telegram nodes. n8n has native Telegram support for sending messages, handling updates, and managing inline keyboards.
Easy integration. Your bot can pull data from any API, database, or service that n8n connects to, which is hundreds of tools.
No server management. n8n handles the webhook and message routing.

I explored the full range of n8n’s capabilities in my complete n8n review, and if you are new to the platform, my beginner guide covers the fundamentals.

Prerequisites

Before we start building, gather these:

1. An n8n instance. Cloud or self-hosted. Sign up for n8n here if you do not have an account yet.
2. A Telegram account. You will need this to create your bot.
3. BotFather access. This is Telegram’s built-in bot for creating new bots.

That is it. No coding environment, no deployment pipeline, no server configuration.

Step 1: Create Your Telegram Bot with BotFather

Open Telegram and search for @BotFather. Start a conversation and send the command /newbot. BotFather will ask you for:

1. A display name for your bot (e.g., “My n8n Assistant”).
2. A username that must end in “bot” (e.g., “my_n8n_assistant_bot”).

After you confirm, BotFather will give you a bot token that looks something like 7123456789:AAH-abc123def456ghi789jkl012mno345. Copy this token. You will need it in the next step.

While you are still talking to BotFather, set up a description and about text:

/setdescription - Add a short description of what your bot does
/setabouttext - Add text shown on your bot's profile
/setuserpic - Upload a profile picture for your bot

Step 2: Connect Telegram to n8n

Open your n8n instance and go to Credentials. Click "Add Credential" and search for Telegram. Paste the bot token you got from BotFather. Save and test the connection.

Now create a new workflow. Your first node will be a Telegram Trigger. This node listens for incoming messages and commands sent to your bot. Set it to receive "All Updates" so you can handle messages, commands, and callback queries (for inline buttons).

Node: Telegram Trigger
Updates: message, callback_query

Step 3: Build a Command Handler

The core of any Telegram bot is its command system. Users type /command and the bot responds. Here is how to structure this in n8n.

Route Commands with a Switch Node

After the Telegram Trigger, add a Switch node. This routes messages based on the command text. Configure the following routes:

Node: Switch
Rules:
Route 1: {{ $json.message.text }} starts with "/start"
Route 2: {{ $json.message.text }} starts with "/help"
Route 3: {{ $json.message.text }} starts with "/status"
Route 4: {{ $json.message.text }} starts with "/report"
Fallback: Everything else

The /start Command

For the /start command, add a Telegram node (Send Message operation) that sends a welcome message:

Node: Telegram - Send Message
Chat ID: {{ $json.message.chat.id }}
Text: |
Welcome to the n8n Assistant Bot!

Here is what I can do:
/status - Check system status
/report - Get today's report
/help - Show available commands

Just type a command to get started.

The /status Command

This is where things get interesting. The /status command in my bot checks the health of several services. Add an HTTP Request node that calls your monitoring API, then format the response.

Node: HTTP Request
URL: https://your-api.com/status
Method: GET

→ Then format with a Set node:

Node: Telegram - Send Message
Chat ID: {{ $json.message.chat.id }}
Parse Mode: Markdown
Text: |
*System Status Report*

API Server: {{ $json.apiStatus }}
Database: {{ $json.dbStatus }}
Queue: {{ $json.queueStatus }}

Last checked: {{ $now.format('HH:mm') }}

The /report Command

For the /report command, I pull data from Google Sheets and a PostgreSQL database, then combine them into a formatted message. The workflow looks like this:

1. Google Sheets node: Read today's sales data.
2. Function node: Calculate totals and format numbers.
3. Telegram node: Send a rich summary.

Node: Telegram - Send Message
Chat ID: {{ $json.message.chat.id }}
Parse Mode: Markdown
Text: |
*Daily Report - {{ $now.format('MMM dd, yyyy') }}*

New leads: {{ $json.newLeads }}
Deals closed: {{ $json.dealsClosed }}
Revenue: ${{ $json.revenue }}

Top performer: {{ $json.topRep }}

Step 4: Add Interactive Inline Menus

Inline keyboards are one of Telegram's best features. They let users tap buttons instead of typing commands. Here is how to implement them.

Sending a Menu

When someone types /menu, send a message with inline buttons:

Node: Telegram - Send Message
Chat ID: {{ $json.message.chat.id }}
Text: "What would you like to do?"
Reply Markup:
Inline Keyboard:
Row 1: [{"text": "View Sales", "callback_data": "sales"}]
[{"text": "View Tasks", "callback_data": "tasks"}]
Row 2: [{"text": "System Health", "callback_data": "health"}]
[{"text": "Team Stats", "callback_data": "team"}]


In n8n, you set the reply markup using the "Reply Markup" field in the Telegram node. Select "Inline Keyboard" and define your buttons.

Handling Button Presses

Button presses come in as callback_query updates. Back in your Switch node, add a route that checks for callback data:

Route: {{ $json.callback_query.data }} exists


Then add another Switch node to route based on the callback data value:

Switch on: {{ $json.callback_query.data }}
"sales" → Fetch sales data → Send response
"tasks" → Fetch tasks → Send response
"health" → Check health → Send response
"team" → Fetch team stats → Send response


After processing the callback, always answer the callback query to remove the loading indicator:

Node: Telegram - Answer Callback Query
Callback Query ID: {{ $json.callback_query.id }}

Step 5: Send Proactive Notifications

A bot is not just about responding to commands. You can also send proactive notifications triggered by events in other systems.

Alert on Critical Events

Create a separate workflow with a Webhook node as the trigger. When your monitoring system detects an issue, it calls this webhook, and the workflow sends a Telegram message:

Node: Webhook (receives alert data)
→ Node: Telegram - Send Message
Chat ID: YOUR_CHAT_ID (or a group chat ID)
Text: |
:red_circle: *ALERT*
Service: {{ $json.service }}
Issue: {{ $json.message }}
Severity: {{ $json.severity }}
Time: {{ $now.format('HH:mm:ss') }}

Scheduled Daily Summaries

Use a Schedule Trigger node to send a daily summary every morning at 9 AM. The workflow fetches data from your various sources and compiles a morning briefing.

Node: Schedule Trigger
Cron: 0 9 * * 1-5

→ Fetch data from multiple sources
→ Compile summary
→ Telegram - Send Message

Step 6: Handle Natural Language Messages

Not every message will be a command. Users might type free-form questions. Here is how to handle that.

In your main Switch node's fallback route, add a Function node that does basic keyword matching:

const text = $input.first().json.message.text.toLowerCase();

if (text.includes('price') || text.includes('cost')) {
return [{ json: { intent: 'pricing', chatId: $input.first().json.message.chat.id } }];
} else if (text.includes('help') || text.includes('support')) {
return [{ json: { intent: 'support', chatId: $input.first().json.message.chat.id } }];
} else {
return [{ json: { intent: 'unknown', chatId: $input.first().json.message.chat.id } }];
}


For the "unknown" intent, send a helpful fallback message:

I did not quite understand that. Here are some things I can help with:

/status - Check system status
/report - Get today's report
/menu - Browse options

Or just type what you need and I will try to help!

Step 7: Add User Authentication

If your bot handles sensitive data, you want to restrict access. Add a Function node right after the Telegram Trigger that checks the sender's user ID against an allowed list:

const allowedUsers = [123456789, 987654321]; // Telegram user IDs
const userId = $input.first().json.message?.from?.id ||
$input.first().json.callback_query?.from?.id;

if (!allowedUsers.includes(userId)) {
return []; // Empty output stops the workflow
}
return $input.all();

Tips from Running Bots in Production

After running Telegram bots with n8n for over a year, here is what I have learned.

Keep response times fast. Telegram users expect near-instant replies. If your workflow needs to call slow APIs, send an initial "Processing..." message immediately, then edit it with the final result using the "Edit Message" operation.

Use error handling. Wrap your main logic in a try-catch by using n8n's error workflow feature. If something fails, the user should get a "Sorry, something went wrong" message instead of radio silence.

Log conversations. Add a Google Sheets or database node at the end of each route to log commands, user IDs, and timestamps. This helps you understand usage patterns and debug issues.

Test with a private chat first. Before deploying to a group, test every command and button in a direct conversation with the bot. Group dynamics (permissions, mentions) add complexity.

FAQ

Can my n8n Telegram bot work in group chats?

Yes, but you need to configure it properly. By default, bots in groups only receive messages that start with a slash command or mention the bot directly. You need to disable "privacy mode" via BotFather using the /setprivacy command if you want the bot to see all messages in a group. In n8n, the chat ID for groups is a negative number, so make sure your workflow handles that correctly.

How do I send images or documents through the Telegram bot?

The n8n Telegram node supports sending photos, documents, audio, and video. Use the "Send Photo" or "Send Document" operation instead of "Send Message." You can send files by URL (the easiest method) or by binary data. For example, if your workflow generates a PDF report, you can pass the binary data directly to the Telegram node and it will send it as a document attachment.

What happens if my n8n instance goes down? Will the bot miss messages?

If you are using webhooks (the default Telegram Trigger behavior), messages sent while n8n is down will be lost because Telegram stops retrying after a while. To mitigate this, you can use polling mode instead of webhooks, which fetches pending updates when n8n comes back online. Alternatively, use n8n Cloud for better uptime. I discussed the reliability differences between self-hosted and cloud in my n8n review.

Conclusion

Building a Telegram bot with n8n is one of the most satisfying automation projects you can take on. In just an afternoon, you go from nothing to a fully functional bot that handles commands, sends notifications, and presents interactive menus.

What I love about this approach is the maintainability. When I need to add a new command, I just add a route to the Switch node and build the logic visually. No redeploying code, no SSH sessions, no dependency management.

If you have not tried n8n yet, start here. The Telegram integration is one of the best ways to experience how powerful visual automation can be.

For more workflow ideas and tutorials, check out my n8n vs Zapier comparison to see why I chose n8n as my daily driver, and my beginner guide to get your foundations right.

Happy building.

🚀 Ready to automate?

Start your free n8n trial today.

Try n8n Free →

Deja un comentario