EasyTeamClaw add-telegram

Add Telegram as a channel. Can replace WhatsApp entirely or run alongside it. Also configurable as a control-only channel (triggers actions) or passive channel (receives notifications only).

install
source · Clone the upstream repo
git clone https://github.com/XDongiang/EasyTeamClaw
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/XDongiang/EasyTeamClaw "$T" && mkdir -p ~/.claude/skills && cp -r "$T/.claude/skills/add-telegram" ~/.claude/skills/xdongiang-easyteamclaw-add-telegram && rm -rf "$T"
manifest: .claude/skills/add-telegram/SKILL.md
source content

Add Telegram Channel

This skill adds Telegram support to NanoClaw using the skills engine for deterministic code changes, then walks through interactive setup.

Phase 1: Pre-flight

Check if already applied

Read

.nanoclaw/state.yaml
. If
telegram
is in
applied_skills
, skip to Phase 3 (Setup). The code changes are already in place.

Ask the user

Use

AskUserQuestion
to collect configuration:

AskUserQuestion: Should Telegram replace WhatsApp or run alongside it?

  • Replace WhatsApp - Telegram will be the only channel (sets TELEGRAM_ONLY=true)
  • Alongside - Both Telegram and WhatsApp channels active

AskUserQuestion: Do you have a Telegram bot token, or do you need to create one?

If they have one, collect it now. If not, we'll create one in Phase 3.

Phase 2: Apply Code Changes

Run the skills engine to apply this skill's code package. The package files are in this directory alongside this SKILL.md.

Initialize skills system (if needed)

If

.nanoclaw/
directory doesn't exist yet:

npx tsx scripts/apply-skill.ts --init

Or call

initSkillsSystem()
from
skills-engine/migrate.ts
.

Apply the skill

npx tsx scripts/apply-skill.ts .claude/skills/add-telegram

This deterministically:

  • Adds
    src/channels/telegram.ts
    (TelegramChannel class implementing Channel interface)
  • Adds
    src/channels/telegram.test.ts
    (46 unit tests)
  • Three-way merges Telegram support into
    src/index.ts
    (multi-channel support, findChannel routing)
  • Three-way merges Telegram config into
    src/config.ts
    (TELEGRAM_BOT_TOKEN, TELEGRAM_ONLY exports)
  • Three-way merges updated routing tests into
    src/routing.test.ts
  • Installs the
    grammy
    npm dependency
  • Updates
    .env.example
    with
    TELEGRAM_BOT_TOKEN
    and
    TELEGRAM_ONLY
  • Records the application in
    .nanoclaw/state.yaml

If the apply reports merge conflicts, read the intent files:

  • modify/src/index.ts.intent.md
    — what changed and invariants for index.ts
  • modify/src/config.ts.intent.md
    — what changed for config.ts

Validate code changes

npm test
npm run build

All tests must pass (including the new telegram tests) and build must be clean before proceeding.

Phase 3: Setup

Create Telegram Bot (if needed)

If the user doesn't have a bot token, tell them:

I need you to create a Telegram bot:

  1. Open Telegram and search for
    @BotFather
  2. Send
    /newbot
    and follow prompts:
    • Bot name: Something friendly (e.g., "Andy Assistant")
    • Bot username: Must end with "bot" (e.g., "andy_ai_bot")
  3. Copy the bot token (looks like
    123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11
    )

Wait for the user to provide the token.

Configure environment

Add to

.env
:

TELEGRAM_BOT_TOKEN=<their-token>

If they chose to replace WhatsApp:

TELEGRAM_ONLY=true

Sync to container environment:

mkdir -p data/env && cp .env data/env/env

The container reads environment from

data/env/env
, not
.env
directly.

Disable Group Privacy (for group chats)

Tell the user:

Important for group chats: By default, Telegram bots only see @mentions and commands in groups. To let the bot see all messages:

  1. Open Telegram and search for
    @BotFather
  2. Send
    /mybots
    and select your bot
  3. Go to Bot Settings > Group Privacy > Turn off

This is optional if you only want trigger-based responses via @mentioning the bot.

Build and restart

npm run build
launchctl kickstart -k gui/$(id -u)/com.nanoclaw  # macOS
# Linux: systemctl --user restart nanoclaw

Phase 4: Registration

Get Chat ID

Tell the user:

  1. Open your bot in Telegram (search for its username)
  2. Send
    /chatid
    — it will reply with the chat ID
  3. For groups: add the bot to the group first, then send
    /chatid
    in the group

Wait for the user to provide the chat ID (format:

tg:123456789
or
tg:-1001234567890
).

Register the chat

Use the IPC register flow or register directly. The chat ID, name, and folder name are needed.

For a main chat (responds to all messages, uses the

main
folder):

registerGroup("tg:<chat-id>", {
  name: "<chat-name>",
  folder: "main",
  trigger: `@${ASSISTANT_NAME}`,
  added_at: new Date().toISOString(),
  requiresTrigger: false,
});

For additional chats (trigger-only):

registerGroup("tg:<chat-id>", {
  name: "<chat-name>",
  folder: "<folder-name>",
  trigger: `@${ASSISTANT_NAME}`,
  added_at: new Date().toISOString(),
  requiresTrigger: true,
});

Phase 5: Verify

Test the connection

Tell the user:

Send a message to your registered Telegram chat:

  • For main chat: Any message works
  • For non-main:
    @Andy hello
    or @mention the bot

The bot should respond within a few seconds.

Check logs if needed

tail -f logs/nanoclaw.log

Troubleshooting

Bot not responding

Check:

  1. TELEGRAM_BOT_TOKEN
    is set in
    .env
    AND synced to
    data/env/env
  2. Chat is registered in SQLite (check with:
    sqlite3 store/messages.db "SELECT * FROM registered_groups WHERE jid LIKE 'tg:%'"
    )
  3. For non-main chats: message includes trigger pattern
  4. Service is running:
    launchctl list | grep nanoclaw
    (macOS) or
    systemctl --user status nanoclaw
    (Linux)

Bot only responds to @mentions in groups

Group Privacy is enabled (default). Fix:

  1. @BotFather
    >
    /mybots
    > select bot > Bot Settings > Group Privacy > Turn off
  2. Remove and re-add the bot to the group (required for the change to take effect)

Getting chat ID

If

/chatid
doesn't work:

  • Verify token:
    curl -s "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/getMe"
  • Check bot is started:
    tail -f logs/nanoclaw.log

After Setup

If running

npm run dev
while the service is active:

# macOS:
launchctl unload ~/Library/LaunchAgents/com.nanoclaw.plist
npm run dev
# When done testing:
launchctl load ~/Library/LaunchAgents/com.nanoclaw.plist
# Linux:
# systemctl --user stop nanoclaw
# npm run dev
# systemctl --user start nanoclaw

Agent Swarms (Teams)

After completing the Telegram setup, use

AskUserQuestion
:

AskUserQuestion: Would you like to add Agent Swarm support? Without it, Agent Teams still work — they just operate behind the scenes. With Swarm support, each subagent appears as a different bot in the Telegram group so you can see who's saying what and have interactive team sessions.

If they say yes, invoke the

/add-telegram-swarm
skill.

Removal

To remove Telegram integration:

  1. Delete
    src/channels/telegram.ts
  2. Remove
    TelegramChannel
    import and creation from
    src/index.ts
  3. Remove
    channels
    array and revert to using
    whatsapp
    directly in
    processGroupMessages
    , scheduler deps, and IPC deps
  4. Revert
    getAvailableGroups()
    filter to only include
    @g.us
    chats
  5. Remove Telegram config (
    TELEGRAM_BOT_TOKEN
    ,
    TELEGRAM_ONLY
    ) from
    src/config.ts
  6. Remove Telegram registrations from SQLite:
    sqlite3 store/messages.db "DELETE FROM registered_groups WHERE jid LIKE 'tg:%'"
  7. Uninstall:
    npm uninstall grammy
  8. Rebuild:
    npm run build && launchctl kickstart -k gui/$(id -u)/com.nanoclaw
    (macOS) or
    npm run build && systemctl --user restart nanoclaw
    (Linux)