Discord & Slack Bots
Discord & Slack Bots
BizTech runs bot integrations on both Discord (member-facing) and Slack (internal team). This page covers what each bot does, how the endpoints work, and the external services involved.
Discord Bot
The Discord bot handles membership verification — linking a Discord account to a BizTech member record and assigning a "verified" role.
Verification Flow
User types /verify in Discord
│
▼
Discord sends interaction to POST /discord/interactions
│ (Ed25519 signature verified first)
│
▼
Bot responds with a button linking to the BizTech app
│
▼
User clicks button → opens BizTech app → logs in
│
▼
Frontend calls POST /discord/account/mapping
{ discordId, discordUsername }
│
▼
Backend:
1. Looks up user's email from Cognito claims
2. Finds member in biztechMembers2026
3. Saves discordId + discordUsername on member record
4. Calls Discord API to assign "verified" role to the user
│
▼
User gets the verified role in the BizTech Discord server
Discord Endpoints
| Method | Path | Auth | Handler |
|---|---|---|---|
POST | /discord/interactions | Ed25519 signature | discordInteraction |
POST | /discord/account/mapping | Cognito | discordAccountMapping |
POST | /discord/webhook | — | discordWebhook (stub, unused) |
Signature verification: The discordInteraction handler verifies every incoming request using Ed25519 with the Discord application public key. This prevents spoofed interaction requests. The verification uses the tweetnacl library.
Environment variables:
| Variable | Purpose |
|---|---|
DISCORD_APP_PUBLIC_KEY | Ed25519 public key for verifying interaction requests |
DISCORD_BOT_TOKEN | Bot token for Discord API calls |
DISCORD_GUILD_ID | The BizTech Discord server ID |
DISCORD_VERIFIED_ROLE_ID | ID of the "verified" role to assign |
Slack Bot
The Slack bot provides several features for the BizTech internal team.
Feature 1: BizWiki
When someone asks a question in Slack, the bot searches the BizTech documentation and answers using AI.
How it works:
- User posts a message in Slack
- Slack fires a shortcut event →
POST /slack/shortcut/events - Handler matches the
callback_idfor BizWiki - Loads a TF-IDF index from a JSON file (pre-generated by
scripts/generateSlackDocsIndex.js) - Ranks documents by relevance to the question
- Sends the top-matching docs + the question to OpenAI (
gpt-5.4-mini) - Posts the AI-generated answer as a threaded reply in Slack
Model: gpt-5.4-mini with a system prompt that instructs it to answer only from the provided documentation context.
Feature 2: Thread Summarization
Summarizes long Slack threads on demand.
- User triggers the summarize shortcut on a thread
- Handler fetches all messages in the thread via the Slack API (
conversations.replies) - Sends the full thread to OpenAI (
gpt-4o-mini) with a summarization prompt - Posts the summary as a reply in the thread
Feature 3: GitHub Project Reminders
A scheduled cron job that reminds team members about their assigned GitHub project board issues.
Schedule: Monday and Friday at 17:00 UTC
How it works:
POST /slack/githubfires on the cron schedule- Fetches all project items from the GitHub project board via GraphQL API
- Filters for items assigned to team members with status "In Progress" or "Todo"
- Formats a summary message with assignees, issue titles, and statuses
- Posts to the designated Slack channel
GitHub API: Uses the GraphQL API with a personal access token to query project V2 board items.
Feature 4: Team Ping Modal
A Slack shortcut that opens a modal for pinging specific BizTech teams (e.g., "@dev-team", "@design-team"). Rather than managing Slack user groups, this uses a custom modal that sends a formatted message mentioning the selected team members.
Slack Endpoints
| Method | Path | Auth | Handler |
|---|---|---|---|
POST | /slack/shortcut/events | Slack signing secret | slackShortcutHandler |
POST | /slack/github | None (cron) | slackGithubReminder |
The slackShortcutHandler is a router that dispatches to different features based on the callback_id in the Slack payload.
Slack Environment Variables
| Variable | Purpose |
|---|---|
SLACK_SIGNING_SECRET | Verifies incoming Slack requests |
SLACK_BOT_TOKEN | Bot token for posting messages |
SLACK_CHANNEL_ID | Default channel for bot messages |
OPENAI_API_KEY | For BizWiki QA and thread summarization |
GITHUB_TOKEN | Personal access token for GitHub GraphQL API |
GITHUB_PROJECT_NUMBER | GitHub project board number to track |
DynamoDB Tables
| Table | Usage |
|---|---|
biztechMembers2026 | Discord account mapping — read member by email, write discordId and discordUsername |
The Slack bot doesn't use any DynamoDB tables — it reads from a static TF-IDF index file and external APIs.
External Services
| Service | Used by | Purpose |
|---|---|---|
| Discord API | Discord bot | Assign roles, respond to interactions |
| Slack API | Slack bot | Post messages, fetch threads, open modals |
| OpenAI API | BizWiki, Summarizer | gpt-5.4-mini for QA, gpt-4o-mini for summaries |
| GitHub GraphQL API | GitHub reminders | Query project board items |
Key Files
| File | Purpose |
|---|---|
services/bots/handler.js | All bot endpoint handlers |
services/bots/serverless.yml | Endpoint definitions, env vars, cron schedule |
scripts/generateSlackDocsIndex.js | Pre-generates the TF-IDF index for BizWiki search |
Related Pages
- Docs & Bot Sync — how the docs index is rebuilt and deployed
- Membership Flow — Discord verification requires membership
- Companion System — another user-facing feature that integrates with profiles