source-integrations
Set up and maintain GitHub OAuth2 and Slack Bot Token integrations for notification-hub.
Best use case
source-integrations is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Set up and maintain GitHub OAuth2 and Slack Bot Token integrations for notification-hub.
Teams using source-integrations should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/source-integrations/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How source-integrations Compares
| Feature / Agent | source-integrations | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Set up and maintain GitHub OAuth2 and Slack Bot Token integrations for notification-hub.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# source-integrations skill
This skill covers setting up the GitHub and Slack integrations from scratch, including creating the OAuth2 app, configuring credentials, and troubleshooting common sync failures.
## GitHub integration
### Create the GitHub OAuth App
1. Go to GitHub > Settings > Developer settings > OAuth Apps > New OAuth App.
2. Fill in:
- Application name: `notification-hub` (or any name)
- Homepage URL: `http://localhost:3000`
- Authorization callback URL: `http://localhost:3000/auth/github/callback`
3. Click "Register application".
4. Copy the **Client ID** and generate a **Client Secret**.
5. Set in your environment:
```bash
GITHUB_CLIENT_ID=Ov23liXXXXXXXXXX
GITHUB_CLIENT_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
GITHUB_CALLBACK_URL=http://localhost:3000/auth/github/callback
```
For production replace `localhost:3000` with your public URL.
### OAuth2 flow (passport-github2)
The flow is handled by `src/integrations/github/oauth.ts`. The strategy is registered at startup:
```
GET /auth/github - redirect to GitHub
GET /auth/github/callback - exchange code for token, store encrypted, redirect to /sources
```
The access token is encrypted with AES-256-GCM before writing to the `sources.access_token_enc` column:
```
NOTIFICATION_HUB_ENCRYPTION_KEY must be exactly 64 hex characters (32 bytes)
```
Generate a key:
```bash
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
```
### GitHub sync
After connection, the poller in `src/integrations/github/sync.ts` runs on the `SYNC_INTERVAL_MS` schedule. It calls:
```
GET /notifications?all=false&participating=false&since=<last_sync>
```
Each notification is upserted into the `notifications` table using the GitHub `id` field as the external ID to prevent duplicates. Mute rules are evaluated at ingest time.
### Configuring watched repositories
After OAuth, the user selects repos in the UI. Only notifications from those repos are stored. Update via API:
```bash
curl -X PATCH http://localhost:3000/api/sources/:id \
-H 'Content-Type: application/json' \
-d '{"config": {"repos": ["owner/repo1","owner/repo2"]}}'
```
Pass an empty array to watch all repos:
```bash
curl -X PATCH http://localhost:3000/api/sources/:id \
-H 'Content-Type: application/json' \
-d '{"config": {"repos": []}}'
```
### GitHub notification types
| GitHub reason | Displayed as |
|---------------------|---------------------------|
| `review_requested` | PR review |
| `mention` | Mention |
| `assign` | Issue assignment |
| `ci_activity` | CI status |
| `subscribed` | Subscribed |
| `team_mention` | Team mention |
### GitHub troubleshooting
**Token expired or revoked**
The source status will show `error`. Disconnect and reconnect via OAuth.
**Rate limit hit**
GitHub REST API allows 5000 requests/hour for authenticated users. The poller backs off automatically when the `X-RateLimit-Remaining` header is below 100.
**Callback URL mismatch**
If GitHub returns `redirect_uri_mismatch`, the `GITHUB_CALLBACK_URL` env var must exactly match the callback URL registered in the OAuth App settings.
---
## Slack integration
### Create the Slack App
1. Go to https://api.slack.com/apps > Create New App > From scratch.
2. Name: `notification-hub`. Pick your workspace.
3. Under **OAuth and Permissions** > **Scopes** > **Bot Token Scopes**, add:
- `channels:history`
- `channels:read`
- `groups:history`
- `groups:read`
- `users:read`
4. Click **Install to Workspace**. Copy the **Bot User OAuth Token** (`xoxb-...`).
5. Do NOT set `SLACK_CLIENT_ID`/`SLACK_CLIENT_SECRET` unless you want the full OAuth flow. For a single-workspace personal setup, only the bot token is required.
### Connecting with a bot token
In the notification-hub web UI:
1. Sources > Add Source > Slack.
2. Paste the `xoxb-...` token.
3. The server calls `auth.test` to validate and fetch the workspace info.
4. Select channels to watch from the list returned by `conversations.list`.
The token is stored encrypted at rest (same AES-256-GCM scheme as GitHub).
### Slack sync
`src/integrations/slack/sync.ts` polls each watched channel using `conversations.history` with a `oldest` cursor equal to the last sync timestamp. New messages are stored as notifications. Direct mentions (`<@UXXXXXXXX>`) are given higher priority automatically.
### Configuring watched channels
```bash
# Get channel IDs
curl http://localhost:3000/api/sources/:id/channels
# Update watched channels (use Slack channel IDs, not names)
curl -X PATCH http://localhost:3000/api/sources/:id \
-H 'Content-Type: application/json' \
-d '{"config": {"channels": ["C012ABCDE","C999FGHIJ"]}}'
```
### Slack troubleshooting
**`invalid_auth` error**
The token has been revoked or the app was uninstalled. Generate a new bot token in the Slack app settings and update via disconnect/reconnect.
**`not_in_channel` error**
The bot must be invited to private channels. In Slack: `/invite @notification-hub` in the channel.
**Missing messages**
`conversations.history` only returns messages from public channels and private channels where the bot is a member. Threads are fetched separately with `conversations.replies` if `thread_ts` is present.
**Rate limits**
Slack Tier 3 methods (conversations.history) allow ~50 requests/minute. The poller automatically adds delays between channel polls when multiple channels are watched.
---
## Encryption key rotation
If you need to rotate the `NOTIFICATION_HUB_ENCRYPTION_KEY`:
1. Set the new key as `NOTIFICATION_HUB_ENCRYPTION_KEY_NEW`.
2. Run the migration script:
```bash
pnpm run migrate:rotate-keys
```
This re-encrypts all stored tokens with the new key. After the script completes, rename `ENCRYPTION_KEY_NEW` to `ENCRYPTION_KEY` and restart the server.
---
## Testing integrations locally
Use ngrok or a similar tunnel to expose `localhost:3000` for OAuth callbacks during development:
```bash
ngrok http 3000
# Copy the https URL, e.g. https://abc123.ngrok.io
```
Set `GITHUB_CALLBACK_URL=https://abc123.ngrok.io/auth/github/callback` and update the GitHub OAuth App callback URL to match.Related Skills
Skill: Uptime Monitoring
## Overview
Skill: Status Page
## Overview
Skill: unit-conversion
## Overview
Skill: recipe-scaler
## Overview
reading-list
Operate the reading-list API to save, manage, tag, search, and export articles.
email-digest
Configure, test, and troubleshoot the reading-list daily email digest delivered via nodemailer.
websocket-realtime
Use the WebSocket connection in poll-builder to receive live vote updates. Use when you need to stream real-time poll results, monitor a poll for new votes, or build a live dashboard. Triggers include "live results", "real-time updates", "stream votes", "watch poll", or "WebSocket".
poll-builder
Self-hosted poll creation tool with real-time results. Use when you need to create a poll, check vote counts, close a poll, export results, or get the shareable link for a poll. Triggers include "create poll", "vote", "poll results", "survey", "collect votes", "share poll", or any task involving polling or voting.
Skill: personal-finance
## Overview
Skill: csv-import
## Overview
Skill: Syntax Highlighting
## Purpose
Skill: Pastebin Core
## Purpose