* 1 * 2 * cs * 3
9.5 KiB
@chat-adapter/github
GitHub adapter for Chat SDK. Respond to @mentions in PR and issue comment threads.
The GitHub adapter treats issue and pull request comments as messages, and issues/PRs as threads.
Installation
pnpm add @chat-adapter/github
Usage
The adapter auto-detects credentials from GITHUB_TOKEN (or GITHUB_APP_ID/GITHUB_PRIVATE_KEY), GITHUB_WEBHOOK_SECRET, and GITHUB_BOT_USERNAME environment variables:
import { Chat } from "chat";
import { createGitHubAdapter } from "@chat-adapter/github";
const bot = new Chat({
userName: "my-bot",
adapters: {
github: createGitHubAdapter(),
},
});
bot.onNewMention(async (thread, message) => {
await thread.post("Hello from GitHub!");
});
Authentication
Option A: Personal Access Token
Best for personal projects, testing, or single-repo bots.
- Go to Settings > Developer settings > Personal access tokens
- Create a new token with
reposcope - Set
GITHUB_TOKENenvironment variable
createGitHubAdapter({
token: process.env.GITHUB_TOKEN!,
});
Option B: GitHub App (recommended)
Better rate limits, security, and supports multiple installations.
1. Create the app:
- Go to Settings > Developer settings > GitHub Apps > New GitHub App
- Set Webhook URL to
https://your-domain.com/api/webhooks/github - Generate and set a Webhook secret
- Set permissions:
- Repository > Issues: Read & write
- Repository > Pull requests: Read & write
- Repository > Metadata: Read-only
- Subscribe to events: Issue comment, Pull request review comment
- Click Create GitHub App
- Note the App ID and click Generate a private key
2. Install the app:
- Go to your app's settings then Install App
- Click Install and choose repositories
- Note the Installation ID from the URL:
https://github.com/settings/installations/12345678 ^^^^^^^^
Single-tenant:
createGitHubAdapter({
appId: process.env.GITHUB_APP_ID!,
privateKey: process.env.GITHUB_PRIVATE_KEY!,
installationId: parseInt(process.env.GITHUB_INSTALLATION_ID!),
});
Multi-tenant (omit installationId):
createGitHubAdapter({
appId: process.env.GITHUB_APP_ID!,
privateKey: process.env.GITHUB_PRIVATE_KEY!,
});
The adapter automatically extracts installation IDs from webhooks and caches API clients per-installation.
Installation lookup
You can resolve the GitHub App installation ID associated with a Thread or Message:
import { Chat } from "chat";
import { createGitHubAdapter } from "@chat-adapter/github";
const github = createGitHubAdapter({
appId: process.env.GITHUB_APP_ID!,
privateKey: process.env.GITHUB_PRIVATE_KEY!,
webhookSecret: process.env.GITHUB_WEBHOOK_SECRET!,
});
const bot = new Chat({
adapters: { github },
});
bot.onNewMention(async (thread, message) => {
const installationIdFromThread = await github.getInstallationId(thread);
const installationIdFromMessage = await github.getInstallationId(message.threadId);
await thread.post(
`Thread install: ${installationIdFromThread}, message install: ${installationIdFromMessage}`
);
});
- Single-tenant GitHub App mode returns the fixed configured installation ID.
- PAT mode returns
undefined. - Multi-tenant mode only succeeds after the adapter has received a webhook for that repository and cached the installation mapping. Use a persistent state adapter so the mapping survives restarts.
Direct API client
For anything beyond the unified SDK, access the underlying Octokit instance via .client:
const github = bot.getAdapter("github").client;
const { data: pulls } = await github.rest.pulls.list({
owner: "vercel",
repo: "chat",
state: "open",
});
PAT and single-tenant GitHub App modes (with a fixed installationId) return the same client anywhere. Multi-tenant mode requires webhook handler context to resolve the right installation — calling .client outside a handler throws.
Webhook setup
For repository or organization webhooks:
- Go to repository/org Settings then Webhooks then Add webhook
- Set Payload URL to
https://your-domain.com/api/webhooks/github - Set Content type to
application/json(required — the defaultapplication/x-www-form-urlencodeddoes not work) - Set Secret to match your
webhookSecret - Select events: Issue comments, Pull request review comments
Warning: GitHub App webhooks are configured during app creation. Make sure to select
application/jsonas the content type.
Thread model
GitHub has three types of comment threads:
| Type | Context | Thread ID format |
|---|---|---|
| PR-level | PR Conversation tab | github:{owner}/{repo}:{prNumber} |
| Review comments | PR Files Changed tab | github:{owner}/{repo}:{prNumber}:rc:{commentId} |
| Issue comments | Issue thread | github:{owner}/{repo}:issue:{issueNumber} |
Reactions
Supports GitHub's reaction emoji:
| SDK emoji | GitHub reaction |
|---|---|
thumbs_up |
+1 |
thumbs_down |
-1 |
laugh |
laugh |
confused |
confused |
heart |
heart |
hooray |
hooray |
rocket |
rocket |
eyes |
eyes |
Configuration
All options are auto-detected from environment variables when not provided.
| Option | Required | Description |
|---|---|---|
token |
No* | Personal Access Token. Auto-detected from GITHUB_TOKEN |
appId |
No* | GitHub App ID. Auto-detected from GITHUB_APP_ID |
privateKey |
No | GitHub App private key (PEM). Auto-detected from GITHUB_PRIVATE_KEY |
installationId |
No | Installation ID (omit for multi-tenant). Auto-detected from GITHUB_INSTALLATION_ID |
webhookSecret |
No** | Webhook secret. Auto-detected from GITHUB_WEBHOOK_SECRET |
userName |
No | Bot username for @mention detection. Auto-detected from GITHUB_BOT_USERNAME (default: "github-bot") |
botUserId |
No | Bot's numeric user ID (auto-detected if not provided) |
apiUrl |
No | Override the GitHub API base URL (e.g. for GitHub Enterprise Server). Auto-detected from GITHUB_API_URL |
logger |
No | Logger instance (defaults to ConsoleLogger("info")) |
*Either token/GITHUB_TOKEN or appId+privateKey/GITHUB_APP_ID+GITHUB_PRIVATE_KEY is required.
**webhookSecret is required — either via config or GITHUB_WEBHOOK_SECRET env var.
Environment variables
# Personal Access Token auth
GITHUB_TOKEN=ghp_xxxxxxxxxxxx
# OR GitHub App auth
GITHUB_APP_ID=123456
GITHUB_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----..."
GITHUB_INSTALLATION_ID=12345678 # Optional for multi-tenant
# Required
GITHUB_WEBHOOK_SECRET=your-webhook-secret
# Optional: GitHub Enterprise Server
GITHUB_API_URL=https://github.example.com/api/v3
Features
Messaging
| Feature | Supported |
|---|---|
| Post message | Yes |
| Edit message | Yes |
| Delete message | Yes |
| File uploads | No |
| Streaming | Buffered (accumulates then sends) |
Rich content
| Feature | Supported |
|---|---|
| Card format | GFM Markdown |
| Buttons | No |
| Link buttons | No |
| Select menus | No |
| Tables | GFM |
| Fields | Yes |
| Images in cards | Yes |
| Modals | No |
Conversations
| Feature | Supported |
|---|---|
| Slash commands | No |
| Mentions | Yes |
| Add reactions | Yes |
| Remove reactions | Partial |
| Typing indicator | No |
| DMs | No |
| Ephemeral messages | No |
Message history
| Feature | Supported |
|---|---|
| Fetch messages | Yes |
| Fetch single message | No |
| Fetch thread info | Yes |
| Fetch channel messages | Yes |
| List threads | Yes |
| Fetch channel info | Yes |
| Post channel message | No |
Platform-specific
| Feature | Supported |
|---|---|
| Multi-tenant | Yes (GitHub App) |
Limitations
- No typing indicators — GitHub doesn't support typing indicators
- No streaming — Messages posted in full (editing supported for updates)
- No DMs — GitHub doesn't have direct messages
- No modals — GitHub doesn't support interactive modals
- Action buttons — Rendered as text; use link buttons for clickable actions
Troubleshooting
"Invalid signature" error
- Verify
GITHUB_WEBHOOK_SECRETmatches your webhook configuration - Ensure the request body isn't modified before verification
"Invalid JSON" error
- Change webhook Content type to
application/json
Bot not responding to mentions
- Verify webhook events are configured (issue_comment, pull_request_review_comment)
- Check the webhook URL is correct and accessible
- Ensure the
userNameconfig matches your bot's GitHub username
"Installation ID required" error
- This occurs when making API calls outside webhook context in multi-tenant mode
- Use a persistent state adapter (Redis) to store installation mappings
- The first interaction must come from a webhook to establish the mapping
Rate limiting
- PATs have lower rate limits than GitHub Apps
- Consider switching to a GitHub App for production use
License
MIT