docs/users/features/channels/github.md
This guide covers setting up a Qwen Code channel that monitors GitHub notifications and responds to mentions, review requests, assignments, and followed-thread activity.
notifications and public_repo (or repo) scopesAdd the channel to ~/.qwen/settings.json:
{
"channels": {
"my-github": {
"type": "github",
"token": "$GITHUB_TOKEN",
"pollInterval": 60000,
"senderPolicy": "allowlist",
"allowedUsers": ["your-github-username"],
"sessionScope": "chat_thread",
"cwd": "/path/to/your/project",
"groupPolicy": "open",
"groups": {
"*": { "requireMention": true }
}
}
}
}
Set the token as an environment variable:
export GITHUB_TOKEN="ghp_your_token_here"
For GitHub Enterprise Server, set baseUrl:
{
"baseUrl": "https://github.example.com/api/v3"
}
| Option | Default | Description |
|---|---|---|
token | (required) | Classic PAT with notifications scope |
pollInterval | 60000 | Poll interval in ms |
baseUrl | https://api.github.com | API base URL (for GHE) |
groupPolicy | "disabled" | Must be "open" for notifications to flow |
senderPolicy | "allowlist" | Who can trigger the bot |
groups.*.requireMention | true | Require @mentions for ordinary comments; directed notification reasons still run |
On a public repository, setting senderPolicy: "open" allows any GitHub user who triggers a supported notification reason to submit prompts that drive the agent in your cwd. This includes reading code, spending tokens, posting comments, and (subject to permission policy) running tools.
Always use senderPolicy: "allowlist" with explicit allowedUsers on public repos.
Allowlist and pairing entries follow the username, not the immutable account ID. If an allowlisted user renames their GitHub account, remove the stale entry — GitHub releases the old username for anyone else to claim, and the new holder would inherit the allowlist/pairing authorization.
The adapter detects mentions by scanning comment text and first-contact issue or PR bodies for @bot-username using a case-insensitive regex. It does not trust reason: "mention" alone because that value is sticky at the thread level. Other reasons select review, triage, followed-thread, or fallback prompts.
The adapter uses GitHub's Notifications API as a wake-up signal:
GET /notifications for unread threadsmarkNotificationsAsRead (best-effort cleanup, before processing)listComments within a cursor-based time windowThe comment window is (previousCursor, currentMaxUpdatedAt] — comments already eligible in a previous poll cycle are excluded by the cursor, preventing duplicate replies even when the async mark-read has not taken effect. If the process crashes mid-processing, the user can re-mention the bot to retry.
Non-comment activity (push, label changes) bumps the notification's updated_at but produces zero new comments in the window, so re-fetched threads are skipped without triggering the agent.
author and comment notifications may aggregate up to 20 comments from that window.notifications scope. Fine-grained PATs do not support the notifications API.qwen channel start my-github