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).
This skill adds Telegram support to NanoClaw, then walks through interactive setup.
Check if src/channels/telegram.ts exists. If it does, skip to Phase 3 (Setup). The code changes are already in place.
Use AskUserQuestion to collect configuration:
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.
git remote -v
If telegram is missing, add it:
git remote add telegram https://github.com/qwibitai/nanoclaw-telegram.git
git fetch telegram main
git merge telegram/main || {
git checkout --theirs package-lock.json
git add package-lock.json
git merge --continue
}
This merges in:
src/channels/telegram.ts (TelegramChannel class with self-registration via registerChannel)src/channels/telegram.test.ts (unit tests with grammy mock)import './telegram.js' appended to the channel barrel file src/channels/index.tsgrammy npm dependency in package.jsonTELEGRAM_BOT_TOKEN in .env.exampleIf the merge reports conflicts, resolve them by reading the conflicted files and understanding the intent of both sides.
npm install
npm run build
npx vitest run src/channels/telegram.test.ts
All tests must pass (including the new Telegram tests) and build must be clean before proceeding.
If the user doesn't have a bot token, tell them:
I need you to create a Telegram bot:
- Open Telegram and search for
@BotFather- Send
/newbotand follow prompts:
- Bot name: Something friendly (e.g., "Andy Assistant")
- Bot username: Must end with "bot" (e.g., "andy_ai_bot")
- Copy the bot token (looks like
123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11)
Wait for the user to provide the token.
Add to .env:
TELEGRAM_BOT_TOKEN=<their-token>
Channels auto-enable when their credentials are present — no extra configuration needed.
Sync to container environment:
mkdir -p data/env && cp .env data/env/env
The container reads environment from data/env/env, not .env directly.
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:
- Open Telegram and search for
@BotFather- Send
/mybotsand select your bot- Go to Bot Settings > Group Privacy > Turn off
This is optional if you only want trigger-based responses via @mentioning the bot.
npm run build
launchctl kickstart -k gui/$(id -u)/com.nanoclaw # macOS
# Linux: systemctl --user restart nanoclaw
Tell the user:
- Open your bot in Telegram (search for its username)
- Send
/chatid— it will reply with the chat ID- For groups: add the bot to the group first, then send
/chatidin the group
Wait for the user to provide the chat ID (format: tg:123456789 or tg:-1001234567890).
The chat ID, name, and folder name are needed. Use npx tsx setup/index.ts --step register with the appropriate flags.
For a main chat (responds to all messages):
npx tsx setup/index.ts --step register -- --jid "tg:<chat-id>" --name "<chat-name>" --folder "telegram_main" --trigger "@${ASSISTANT_NAME}" --channel telegram --no-trigger-required --is-main
For additional chats (trigger-only):
npx tsx setup/index.ts --step register -- --jid "tg:<chat-id>" --name "<chat-name>" --folder "telegram_<group-name>" --trigger "@${ASSISTANT_NAME}" --channel telegram
Tell the user:
Send a message to your registered Telegram chat:
- For main chat: Any message works
- For non-main:
@Andy helloor @mention the botThe bot should respond within a few seconds.
tail -f logs/nanoclaw.log
Check:
TELEGRAM_BOT_TOKEN is set in .env AND synced to data/env/envsqlite3 store/messages.db "SELECT * FROM registered_groups WHERE jid LIKE 'tg:%'")launchctl list | grep nanoclaw (macOS) or systemctl --user status nanoclaw (Linux)Group Privacy is enabled (default). Fix:
@BotFather > /mybots > select bot > Bot Settings > Group Privacy > Turn offIf /chatid doesn't work:
curl -s "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/getMe"tail -f logs/nanoclaw.logIf 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
To remove Telegram integration:
src/channels/telegram.ts and src/channels/telegram.test.tsimport './telegram.js' from src/channels/index.tsTELEGRAM_BOT_TOKEN from .envsqlite3 store/messages.db "DELETE FROM registered_groups WHERE jid LIKE 'tg:%'"npm uninstall grammynpm run build && launchctl kickstart -k gui/$(id -u)/com.nanoclaw (macOS) or npm run build && systemctl --user restart nanoclaw (Linux)