Skip to main content
Add Telegram as a messaging channel for NanoClaw. Telegram can run alongside existing channels or replace them entirely.

Overview

The Telegram integration uses the grammy library to connect to Telegram’s Bot API. It supports all core NanoClaw features including group chats, isolated contexts, scheduled tasks, and typing indicators.

Features

  • Full channel support - Direct messages, group chats, and channels
  • Bot commands - Built-in /chatid command for registration
  • Typing indicators - Shows when the assistant is working
  • Concurrent chats - Handle multiple conversations simultaneously
  • Flexible deployment - Run alongside existing channels or as the only channel

Adding Telegram

Use the /add-telegram skill to add Telegram support:
1

Run the skill

claude
/add-telegram
2

Choose deployment mode

  • Replace existing channels - Telegram becomes the only channel
  • Alongside - Add Telegram alongside existing channels
3

Apply code changes

The skill merges the skill/telegram branch which adds:
  • src/channels/telegram.ts (TelegramChannel implementation)
  • src/channels/telegram.test.ts (46 unit tests)
  • Multi-channel support in src/index.ts
  • Telegram config in src/config.ts
  • The grammy NPM package
4

Create Telegram bot

If you don’t have a bot token yet, create one through @BotFather
5

Configure environment

Add bot token to .env and sync to container
6

Register chats

Use the /chatid command to get chat IDs and register them

Creating a Telegram bot

If you don’t already have a Telegram bot:
1

Open Telegram

Search for @BotFather and start a conversation
2

Create the bot

Send /newbot and follow the prompts:
  • Bot name: Something friendly (e.g., “Andy Assistant”)
  • Bot username: Must end with “bot” (e.g., “andy_ai_bot”)
3

Save the token

Copy the bot token. It looks like:
123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11

Configuration

Environment variables

Add to .env:
TELEGRAM_BOT_TOKEN=<your-bot-token>
If you chose to replace existing channels:
TELEGRAM_ONLY=true

Sync to container

The container reads environment from data/env/env:
mkdir -p data/env && cp .env data/env/env

Group privacy settings

By default, Telegram bots only see messages that @mention them or start with / in group chats. To let the bot see all messages in groups:
1

Open @BotFather

Search for @BotFather in Telegram
2

Select your bot

Send /mybots and select your bot from the list
3

Disable group privacy

Go to Bot SettingsGroup PrivacyTurn off
This is optional. If you only want trigger-based responses (via @mentions), leave group privacy enabled.

Build and restart

After configuration:
npm run build
launchctl kickstart -k gui/$(id -u)/com.nanoclaw

Registering chats

Get chat ID

1

Start conversation

Open your bot in Telegram (search for its username)
2

Get the chat ID

Send /chatid to the bot. It will reply with the chat ID:
Your chat ID: tg:123456789
3

For group chats

  1. Add the bot to the group
  2. Send /chatid in the group
  3. The bot will reply with the group’s chat ID (format: tg:-1001234567890)

Register the chat

For your main chat (responds to all messages):
registerGroup("tg:<chat-id>", {
  name: "Main",
  folder: "main",
  trigger: `@${ASSISTANT_NAME}`,
  added_at: new Date().toISOString(),
  requiresTrigger: false,
});
For additional chats (trigger-only):
registerGroup("tg:<chat-id>", {
  name: "Team Chat",
  folder: "team-chat",
  trigger: `@${ASSISTANT_NAME}`,
  added_at: new Date().toISOString(),
  requiresTrigger: true,
});
Set requiresTrigger: true for group chats so the assistant only responds when explicitly mentioned.

Testing the connection

Send a message to your registered Telegram chat:
  • For main chat: Any message works
  • For non-main chats: @Andy hello or @mention the bot
The bot should respond within a few seconds.

Check logs

tail -f logs/nanoclaw.log
Look for:
Connected to Telegram
Received message from tg:123456789
Agent response queued

JID format

Telegram chats use the tg: prefix:
  • Individual chat: tg:123456789
  • Group chat: tg:-1001234567890
  • Channel: tg:-1001234567890

Implementation details

The Telegram channel implements the Channel interface:
export class TelegramChannel implements Channel {
  name = 'telegram';
  
  async connect(): Promise<void> {
    this.bot = new Bot(process.env.TELEGRAM_BOT_TOKEN!);
    
    // Handle text messages
    this.bot.on('message:text', async (ctx) => {
      const chatId = `tg:${ctx.chat.id}`;
      this.opts.onMessage(chatId, {
        id: ctx.message.message_id.toString(),
        chat_jid: chatId,
        sender: `${ctx.from.id}`,
        sender_name: ctx.from.first_name,
        content: ctx.message.text,
        timestamp: new Date(ctx.message.date * 1000).toISOString(),
        is_from_me: ctx.from.is_bot,
        is_bot_message: ctx.from.id === this.bot.botInfo?.id,
      });
    });
    
    await this.bot.start();
  }
  
  async sendMessage(jid: string, text: string): Promise<void> {
    const chatId = jid.replace('tg:', '');
    await this.bot.api.sendMessage(chatId, text);
  }
}

Troubleshooting

Bot not responding

Check these common issues:
Verify TELEGRAM_BOT_TOKEN is set in .env and synced to data/env/env:
grep TELEGRAM_BOT_TOKEN .env
grep TELEGRAM_BOT_TOKEN data/env/env
Check if the chat is in the database:
sqlite3 store/messages.db "SELECT * FROM registered_groups WHERE jid LIKE 'tg:%'"
Check if NanoClaw is running:
# macOS
launchctl list | grep nanoclaw

# Linux
systemctl --user status nanoclaw
For non-main chats with requiresTrigger: true, messages must include the trigger pattern (e.g., @Andy).

Bot only responds to @mentions in groups

This is the default Telegram behavior. To change:
  1. Open @BotFather
  2. Send /mybots and select your bot
  3. Bot SettingsGroup PrivacyTurn off
  4. Remove and re-add the bot to the group (required for change to take effect)

Getting chat ID fails

If /chatid doesn’t work:
  1. Verify the bot token:
    curl -s "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/getMe"
    
  2. Check that NanoClaw is running:
    tail -f logs/nanoclaw.log
    
  3. Make sure the bot is started (it should connect on launch)

Agent swarms (teams)

The /add-telegram-swarm skill extends the Telegram integration with specialized agent swarm support. Each subagent appears as a different Telegram bot in the group, making it clear which agent is speaking.

How it works

  • Each swarm agent gets its own Telegram bot token and identity
  • When the orchestrator delegates to a subagent, that agent’s responses come from its own bot
  • Users can see which agent is working on what, and interact with specific agents directly
  • The orchestrator coordinates the team and routes tasks

Installation

The swarm skill depends on the base Telegram integration. If you already have /add-telegram applied:
# On your nanoclaw-telegram fork
git fetch telegram skill/telegram-swarm
git merge telegram/skill/telegram-swarm
Or via Claude Code:
/add-telegram-swarm

Configuration

Each swarm agent needs its own bot token. Create additional bots via @BotFather and add their tokens to .env:
TELEGRAM_BOT_TOKEN=<orchestrator-bot-token>
TELEGRAM_SWARM_BOT_TOKENS=<agent1-token>,<agent2-token>,<agent3-token>
The swarm skill has a 14KB SKILL.md with detailed setup instructions. Running /add-telegram-swarm in Claude Code walks you through the full configuration interactively.
See Agent swarms for general swarm concepts.

Removing Telegram

Since Telegram was added via a git merge, you remove it by reverting the merge commit:
1

Find the merge commit

git log --merges --oneline | grep telegram
Look for a commit like abc1234 Merge remote-tracking branch 'upstream/skill/telegram'.
2

Revert the merge

git revert -m 1 <merge-commit>
This creates a new commit that undoes all of Telegram’s code changes.
3

Remove registrations

sqlite3 store/messages.db "DELETE FROM registered_groups WHERE jid LIKE 'tg:%'"
4

Rebuild and restart

npm install
npm run build
launchctl kickstart -k gui/$(id -u)/com.nanoclaw  # macOS
# or: systemctl --user restart nanoclaw (Linux)
If you later want to re-apply Telegram after reverting, you must revert the revert first — git treats reverted changes as “already applied and undone”. Claude handles this automatically when you run /add-telegram again.

Next steps

Add Discord

Add Discord support to your installation

Add Slack

Add Slack support to your installation

Skills system

Learn more about how skills work
Last modified on March 24, 2026