Skip to main content

Installation

npm install @chat-adapter/github

Environment Variables

Create a GitHub App or use a Personal Access Token. GitHub Apps are recommended for team/organization bots.
VariableRequiredDescription
GITHUB_TOKENPAT modePersonal Access Token with repo scope
GITHUB_APP_IDApp modeGitHub App ID
GITHUB_PRIVATE_KEYApp modePrivate key (PEM format)
GITHUB_INSTALLATION_IDSingle-tenant appInstallation ID for single org
GITHUB_WEBHOOK_SECRETYesWebhook secret for signature verification
GITHUB_BOT_USERNAMEOptionalBot username (e.g., my-bot[bot])

Configuration Options

type GitHubAdapterConfig = 
  | GitHubAdapterPATConfig
  | GitHubAdapterAppConfig
  | GitHubAdapterMultiTenantAppConfig;

// Personal Access Token
interface GitHubAdapterPATConfig {
  token: string;
  webhookSecret: string;
  userName: string;
  botUserId?: number;
  logger: Logger;
}

// Single-tenant GitHub App
interface GitHubAdapterAppConfig {
  appId: string;
  privateKey: string;
  installationId: number;
  webhookSecret: string;
  userName: string;
  botUserId?: number;
  logger: Logger;
}

// Multi-tenant GitHub App
interface GitHubAdapterMultiTenantAppConfig {
  appId: string;
  privateKey: string;
  // No installationId - resolved per-repository from webhooks
  webhookSecret: string;
  userName: string;
  botUserId?: number;
  logger: Logger;
}

Setup

For personal projects or testing:
import { Chat } from 'chat';
import { createGitHubAdapter } from '@chat-adapter/github';
import { MemoryState } from '@chat-adapter/state-memory';

const chat = new Chat({
  userName: 'my-bot',
  adapters: {
    github: createGitHubAdapter({
      token: process.env.GITHUB_TOKEN!,
      webhookSecret: process.env.GITHUB_WEBHOOK_SECRET!,
      userName: 'my-bot',
    }),
  },
  state: new MemoryState(),
});

await chat.initialize();
PAT mode uses your personal account. GitHub Apps are recommended for organization bots.

Webhook Handler

app.post('/webhooks/github', async (req, res) => {
  const response = await github.handleWebhook(req, {
    waitUntil: (promise) => {/* handle async work */},
  });
  res.status(response.status).send(await response.text());
});
Configure webhook in your GitHub repository or app settings:
  • Payload URL: https://your-app.com/webhooks/github
  • Content type: application/json
  • Secret: Your webhook secret
  • Events: Issue comments, Pull request review comments

Features

Supported Events

  • issue_comment (created) - Comments on PR Conversation tab
  • pull_request_review_comment (created) - Line-specific comments on Files Changed tab

Thread Types

GitHub adapter supports two thread types: 1. PR-level threads (Conversation tab)
github:{owner}/{repo}:{prNumber}
All comments on the PR’s main conversation. 2. Review comment threads (Files Changed tab)
github:{owner}/{repo}:{prNumber}:rc:{reviewCommentId}
Line-specific discussion threads on code changes.

Posting Comments

Post to PR conversation:
// Thread ID: github:vercel/next.js:12345
await thread.post('LGTM! Approving this PR.');
Reply to a review comment thread:
// Thread ID: github:vercel/next.js:12345:rc:98765
await thread.post('Fixed in the latest commit.');

Markdown Support

GitHub supports full GitHub Flavored Markdown:
await thread.post(`
## Code Review

- [✓] Tests pass
- [✓] No lint errors
- [ ] Documentation updated

```typescript
const foo = 'bar';
`);

### Reactions

Add/remove reactions to comments:

```typescript
// GitHub reaction types: +1, -1, laugh, confused, heart, hooray, rocket, eyes
await thread.addReaction(messageId, { name: 'thumbs_up' });
await thread.removeReaction(messageId, { name: 'thumbs_up' });

Cards

Cards are converted to GitHub Flavored Markdown tables:
import { Card, Section, Button } from 'chat/cards';

await thread.post(
  <Card title="Build Status">
    <Section text="Build #42 completed successfully" />
    <Button actionId="deploy">Deploy</Button>
  </Card>
);
// Renders as formatted markdown table
GitHub doesn’t support interactive components. Buttons are rendered as markdown links.

Thread IDs

GitHub thread IDs encode repository and PR information:
github:{owner}/{repo}:{prNumber}[:rc:{commentId}]
Examples:
  • PR conversation: github:vercel/next.js:12345
  • Review thread: github:vercel/next.js:12345:rc:98765

Message History

Fetch comments from a thread:
const { messages } = await thread.fetchMessages({
  limit: 100,
  direction: 'backward',
});

Listing Threads

List all open PRs (threads) in a repository:
const { threads, nextCursor } = await github.listThreads(
  'github:vercel/next.js',
  { limit: 30 }
);

for (const thread of threads) {
  console.log(thread.rootMessage.text); // PR title
}

Platform Limits

  • Comment length: 65,536 characters
  • File size: 25 MB per file in PR
  • Rate limits: 5,000 requests/hour (authenticated), 60 requests/hour (unauthenticated)
See GitHub rate limits for details.

Code Examples

chat.onNewMessage(async (event) => {
  if (event.message.text.includes('/deploy')) {
    await event.thread.post('Deploying to staging...');
  }
});

Troubleshooting

  • Verify GITHUB_WEBHOOK_SECRET matches the secret in GitHub settings
  • Ensure webhook Content-Type is application/json
  • Check that request body is raw (not parsed)
  • Enable “Issue comments” and “Pull request review comments” events
  • Verify webhook URL is publicly accessible (HTTPS required)
  • Check that app/PAT has repo scope
  • Use a persistent StateAdapter (Redis, not Memory)
  • Ensure webhooks include installation field
  • Check that installation IDs are being cached (debug logs)
  • Use the correct thread ID format: github:owner/repo:123:rc:456
  • Review comment ID is the ROOT comment, not the reply
  • Ensure bot has write access to the repository

Required Permissions

GitHub App Permissions:
  • Pull requests: Read & write (post comments, read PRs)
  • Issues: Read & write (for PR conversations)
  • Metadata: Read (repository metadata)
Personal Access Token Scopes:
  • repo - Full repository access

Creating a GitHub App

1

Create app

Go to GitHub Developer Settings and create a new GitHub App.
2

Configure permissions

  • Pull requests: Read & write
  • Issues: Read & write
  • Metadata: Read
3

Subscribe to events

  • Issue comments
  • Pull request review comments
4

Generate private key

Generate and download the private key PEM file.
5

Install app

Install the app on your account or organization to get the installation ID.

Next Steps

Message Handling

Process comments and build review flows

GitHub Apps

Learn about GitHub Apps

Code Review Bots

Build automated code review assistants

State Management

Persist data across PR comments