Skip to content

GitHub Notification Routing

Daniel Ellison edited this page Mar 26, 2026 · 1 revision

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.

What gets routed

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.

What stays in the DM

Only GitHub events are rerouted. Everything else stays in your direct conversation:

  • Interactive chat messages
  • Scheduled job output (reminders, Claude jobs)
  • Generic webhook notifications (/webhook endpoint)
  • Voice message responses
  • File/photo responses

Setup

1. Create a Telegram group

Open Telegram and create a new group:

  1. Tap the compose/pencil icon (bottom-right on mobile, top-left on desktop)
  2. Select New Group
  3. Add your Kai bot as a member - search by its @username
  4. Name it something descriptive (e.g., "Kai GitHub", "Dev Notifications")
  5. 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.

2. Get the group's chat ID

Telegram groups have negative integer chat IDs (e.g., -5241088228). Individual users have positive IDs.

Option A: Send a message and check the logs

  1. Send /start in the new group (bot commands are always visible to bots, even with privacy mode)
  2. 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 webhook

Option 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.

3. Configure the setting

Interactive installer:

make config

The 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=-5241088228

The value must be a valid integer. Empty or missing means the feature is disabled.

4. Restart Kai

# 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.

5. Test it

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.

How it works

The routing happens early in the GitHub event handler (webhook.py:_process_github_event), before any event-specific logic:

  1. Check if GITHUB_NOTIFY_CHAT_ID is configured
  2. If yes: set chat_id and notify_chat_id to the group ID
  3. 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_id passed to review.review_pr(), which includes it in the POST /api/send-message body
  • Issue triage agent - notify_chat_id passed to triage.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.

Multi-user interaction

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.

Disabling

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.

Troubleshooting

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_ID warnings
  • 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/hooks and 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

Clone this wiki locally