-
Notifications
You must be signed in to change notification settings - Fork 8
GitHub Notification Routing
By default, all GitHub event notifications (pushes, PRs, issues, comments, reviews) land in your direct message with Kai. During active development, this buries your interactive conversation in noise.
The GITHUB_NOTIFY_CHAT_ID setting routes all GitHub notifications to a separate Telegram group, keeping your DM clean for actual conversation.
When GITHUB_NOTIFY_CHAT_ID is set, all GitHub event notifications go to the configured group:
| Event | Normal notification | Agent output |
|---|---|---|
| Push | Commit summary with branch and author | - |
| Pull request | Open/close/merge/reopen summary | PR review agent posts its review summary here |
| Issues | Open/close/reopen summary | Issue triage agent posts its triage summary here |
| Issue comments | Comment text with author and link | - |
| PR reviews | Review submitted/approved/changes requested | - |
Both the standard event formatters and the agent outputs (PR review, issue triage) route to the same group. There is no way to split them - it is all or nothing.
When GITHUB_NOTIFY_CHAT_ID is not set, everything goes to the user's DM as before. Zero behavior change.
Only GitHub events are rerouted. Everything else stays in your direct conversation:
- Interactive chat messages
- Scheduled job output (reminders, Claude jobs)
- Generic webhook notifications (
/webhookendpoint) - Voice message responses
- File/photo responses
Open Telegram and create a new group:
- Tap the compose/pencil icon (bottom-right on mobile, top-left on desktop)
- Select New Group
-
Add your Kai bot as a member - search by its
@username - Name it something descriptive (e.g., "Kai GitHub", "Dev Notifications")
- Tap Create
The bot needs to be a member of the group to send messages there. You can make the group private - the bot does not need admin privileges to send messages.
Telegram groups have negative integer chat IDs (e.g., -5241088228). Individual users have positive IDs.
Option A: Send a message and check the logs
- Send
/startin the new group (bot commands are always visible to bots, even with privacy mode) - Check Kai's logs for the chat ID:
# Production grep "chat_id" /var/lib/kai/logs/kai.log | tail -5 # Development grep "chat_id" logs/kai.log | tail -5
Option B: Temporarily use getUpdates
If the webhook is consuming updates so they don't appear in getUpdates, you can temporarily disable the webhook, send a message, poll for it, then restore the webhook:
# Remove webhook temporarily
curl -s "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/deleteWebhook"
# Send a message in the group, then:
curl -s "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/getUpdates" | python3 -m json.tool
# Look for "chat": {"id": -XXXXXXXXXX, "title": "Your Group Name"}
# Then restart Kai to re-register the webhookOption C: Use @userinfobot (may have duplicates)
Add @userinfobot to the group. It replies with the chat ID immediately. Note that there may be multiple bots with similar names - look for the verified one.
Interactive installer:
make configThe installer prompts for "GitHub notification chat ID" under the GitHub notifications section. Paste the negative integer (including the dash).
Manual configuration:
Add to your .env (development) or /etc/kai/env (production):
GITHUB_NOTIFY_CHAT_ID=-5241088228The value must be a valid integer. Empty or missing means the feature is disabled.
# Development
make run
# Production (launchd will auto-restart)
kill $(ps aux | grep 'python.*-m kai' | grep -v grep | awk '{print $2}')On startup, the webhook server parses GITHUB_NOTIFY_CHAT_ID and stores it in the app dict. If the value is invalid (not an integer), a warning is logged and the feature is treated as disabled.
Push a commit, open an issue, or comment on a PR in a repo with a GitHub webhook configured. The notification should appear in the group instead of your DM.
The routing happens early in the GitHub event handler (webhook.py:_process_github_event), before any event-specific logic:
- Check if
GITHUB_NOTIFY_CHAT_IDis configured - If yes: set
chat_idandnotify_chat_idto the group ID - If no: fall through to per-user resolution (match GitHub login to Telegram user, or default to admin DM)
The chat_id variable flows to:
-
Standard notifications -
bot.send_message(chat_id, ...)for push/PR/issue/comment/review formatters -
PR review agent -
notify_chat_idpassed toreview.review_pr(), which includes it in thePOST /api/send-messagebody -
Issue triage agent -
notify_chat_idpassed totriage.triage_issue(), same pattern
The group chat ID is also added to allowed_user_ids in the app dict so that _resolve_chat_id() accepts it when the review and triage agents POST to /api/send-message.
In a multi-user setup, the per-user GitHub routing (matching GitHub login to Telegram user via config) is bypassed when GITHUB_NOTIFY_CHAT_ID is set. All users' GitHub events go to the same group. This is intentional - the group acts as a shared notification feed.
If you need per-user group routing (different users' events going to different groups), that would require extending the user config. This is not currently supported.
Remove or comment out GITHUB_NOTIFY_CHAT_ID from your .env / /etc/kai/env and restart. Notifications revert to the DM immediately. You can leave the Telegram group in place for when you want to re-enable it.
Notifications still going to DM:
- Check that the env var is set and the service was restarted
- Check the logs for
Invalid GITHUB_NOTIFY_CHAT_IDwarnings - Verify the value is a valid integer (including the leading dash)
Bot can't send to the group:
- Make sure the bot is still a member of the group
- If the group was deleted or the bot was removed, send failures are logged but don't crash the service - the notification is simply lost
No notifications at all:
- This feature only affects GitHub notifications. Confirm your GitHub webhook is working by checking
gh api repos/OWNER/REPO/hooksand the recent deliveries on the GitHub webhook settings page - Check that Kai's webhook server is reachable (see Exposing Kai to the Internet)
Group chat ID looks wrong:
- Group IDs are always negative integers. If yours is positive, it is a user ID, not a group ID
- Supergroups (large groups, or groups upgraded by Telegram) may have different IDs than regular groups. Use whatever ID Telegram returns - both formats work