18 KiB

Discord Bot Startup Guide

Overview

The GooseFactory Discord Bot bridges factory events into Discord with rich embeds and interactive buttons. It provides real-time notifications, approval workflows, and pipeline management via slash commands.


📋 Command Inventory (7 Commands)

All commands are under the /factory command group:

1. /factory status

  • Purpose: Quick dashboard summary of the factory
  • Returns: Embed showing pipelines, tasks, agents, and SLA status
  • Options: None
  • Use case: Get a quick overview of factory health

2. /factory pipelines

  • Purpose: List active pipelines or get details for a specific pipeline
  • Options:
    • status (optional): Filter by status (active/paused/completed/failed)
    • pipeline_id (optional): Get detailed view of a specific pipeline
  • Returns: List embed or detailed pipeline status with progress bar
  • Use case: Monitor pipeline status and progression through stages

3. /factory queue

  • Purpose: Show pending decision queue
  • Options:
    • priority (optional): Filter by priority (critical/high/medium/low)
    • batch (optional): Show as batch review grouped by risk
  • Returns: List of pending tasks with SLA info, or batch review embed
  • Features: Includes "Approve Low-Risk" batch button
  • Use case: Review pending approvals and identify urgent items

4. /factory approve

  • Purpose: Approve a pending task
  • Options:
    • task_id (required): The task ID to approve
    • notes (optional): Approval notes
  • Returns: Updated approval embed
  • Use case: Fast-track approval from command line

5. /factory reject

  • Purpose: Reject a pending task with a reason
  • Options:
    • task_id (required): The task ID to reject
    • reason (required): Why this is being rejected
    • changes (optional): Requested changes (comma-separated)
  • Returns: Updated rejection embed
  • Use case: Block task progression with actionable feedback

6. /factory deploy

  • Purpose: Deploy a pipeline to staging or production
  • Options:
    • pipeline_id (required): The pipeline to deploy
    • target (required): staging or production
    • dry_run (optional): Preview without actually deploying
  • Returns: Deploy status embed with URL or error details
  • Use case: Trigger deployments from Discord

7. /factory blockers

  • Purpose: Show what's stuck and why
  • Options:
    • pipeline_id (optional): Filter to a specific pipeline
  • Returns: List of blockers with suggested actions
  • Use case: Identify and resolve pipeline bottlenecks

🎨 Embed Types (5)

1. Deploy Notification (embeds/deploy-notification.ts)

  • Channel: #factory-deploys
  • Triggers: Deploy started/succeeded/failed
  • Features:
    • Status-specific colors and emojis
    • Deploy URL for successful deploys
    • Error logs for failed deploys
    • Retry button on failures
  • Data: pipeline, target, version, status, url, error, triggeredBy

2. SLA Warning (embeds/sla-warning.ts)

  • Channel: #factory-alerts
  • Triggers: Task approaching SLA deadline or breached
  • Features:
    • @here for warnings, @everyone for breaches
    • Escalation level tracking
    • Time remaining/overdue display
    • Quick approve/reject buttons
  • Variants: Standard warning, critical escalation (T+SLA+2h)
  • Data: taskId, title, pipelineId, slaDeadline, minutesRemaining, escalationLevel

3. Batch Review (embeds/batch-review.ts)

  • Channel: #factory-tasks
  • Triggers: Multiple tasks ready for review
  • Features:
    • Groups tasks by risk level (low/medium/high)
    • Shows test results and coverage
    • Batch approve buttons
    • Select menu for individual review
  • Risk classification: Based on priority, SLA, test results, coverage, diff size
  • Data: Array of {task, riskLevel}

4. Pipeline Status (embeds/pipeline-status.ts)

  • Channel: Responses to /factory pipelines
  • Features:
    • Progress bar showing stage completion
    • Stage duration tracking
    • SLA deadline countdown
    • Status-specific colors
  • Variants: List view (compact), detail view (full status)
  • Also includes: Stage transition notifications for #factory-feed

5. Approval Request (embeds/approval-request.ts)

  • Channel: #factory-tasks
  • Triggers: New task requires human approval
  • Features:
    • Test results, coverage, and diff summary
    • Priority indicators
    • SLA countdown
    • Interactive buttons: Approve/Reject/Details/Defer
    • Details button creates a thread for discussion
  • State transitions:
    • Approved: Green embed with approver
    • Rejected: Red embed with reason
    • Deferred: Gray embed (escalates internally)

🎮 Interaction Types

Buttons (interactions/button-handler.ts)

Button ID Pattern Action Handler
approve:{taskId} Approve task Finds approval, calls API, updates embed
reject:{taskId} Show rejection modal Opens modal for reason + changes
details:{taskId} Show task details Creates thread or ephemeral reply
defer:{taskId} Defer decision Escalates task internally
batch-approve-low:{ids} Batch approve low-risk Calls bulk API
batch-approve-all:{ids} Batch approve all Calls bulk API
batch-review-individual Switch to individual mode Info message
deploy-retry:{pipelineId}:{target} Retry failed deploy Calls deploy API

Modals (interactions/modal-handler.ts)

Modal ID Pattern Inputs Handler
reject-modal:{taskId} reason (required, paragraph)
requested_changes (optional, paragraph)
Rejects approval via API, updates embed

Select Menus (interactions/select-handler.ts)

Select Menu ID Options Handler
batch-select-review Task list (up to 25) Loads selected task as ephemeral approval request

🔌 Factory API Calls

All API calls go through api-client.ts → Factory API at FACTORY_API_URL (default: https://api.goosefactory.dev/v1)

Endpoints Used:

Method Endpoint Used By Purpose
GET /dashboard/summary /factory status Dashboard overview
GET /pipelines /factory pipelines List pipelines
GET /pipelines/{id} /factory pipelines Get pipeline details
GET /pipelines/{id}/stages /factory pipelines Get stage progress
GET /tasks /factory queue List pending tasks
GET /tasks/{id} Button handlers Get task details
GET /tasks/stats /factory queue Task statistics
POST /tasks/bulk Batch approve Bulk approve/reject
GET /approvals Button handlers Find approval for task
GET /approvals/{id} Button handlers Get approval details
POST /approvals/{id}/approve Approve handlers Approve a task
POST /approvals/{id}/reject Reject handlers Reject a task
POST /approvals/{id}/escalate Defer handler Escalate/defer a task
POST /deploy /factory deploy Trigger deploy
GET /blockers /factory blockers Get blockers

API Headers:

  • X-API-Key: {FACTORY_API_KEY}
  • X-Request-Id: {uuid}
  • Content-Type: application/json

🔐 Environment Variables

Create a .env file in packages/discord-bot/ with:

# Discord Bot Configuration
DISCORD_TOKEN=                     # Bot token from Discord Developer Portal
DISCORD_CLIENT_ID=                 # Application ID (for registering commands)
DISCORD_GUILD_ID=                  # Your Discord server ID (for guild commands)

# Channel Routing
FACTORY_FEED_CHANNEL_ID=           # General activity feed (#factory-feed)
FACTORY_TASKS_CHANNEL_ID=          # Approval requests (#factory-tasks)
FACTORY_DEPLOYS_CHANNEL_ID=        # Deploy notifications (#factory-deploys)
FACTORY_ALERTS_CHANNEL_ID=         # SLA warnings and critical alerts (#factory-alerts)

# Factory API
FACTORY_API_URL=https://api.goosefactory.dev/v1  # Factory API base URL
FACTORY_WS_URL=wss://api.goosefactory.dev/v1/ws  # WebSocket for real-time events
FACTORY_API_KEY=                   # API key for Factory authentication

# Optional
LOG_LEVEL=info                     # debug | info | warn | error
NODE_ENV=development               # development | production | test

Required variables:

  • All DISCORD_* variables
  • All channel IDs
  • FACTORY_API_KEY

How to get these values:

  1. Discord Bot Setup:

    • Go to Discord Developer Portal
    • Create new application or select existing
    • Go to Bot section → Reset Token → Copy DISCORD_TOKEN
    • Copy Application ID → DISCORD_CLIENT_ID
    • Enable Message Content Intent, Server Members Intent
  2. Guild & Channel IDs:

    • Enable Developer Mode in Discord (User Settings → Advanced)
    • Right-click server → Copy ID → DISCORD_GUILD_ID
    • Right-click each channel → Copy ID → Channel ID variables
  3. Factory API Key:

    • Contact Factory admin or generate via Factory dashboard
    • If self-hosting, check Factory API .env for key generation

🚀 Prerequisites

Before starting the bot:

1. Services Must Be Running

  • Factory API (at FACTORY_API_URL)
  • Factory WebSocket (at FACTORY_WS_URL) — for real-time events
  • PostgreSQL (if Factory API depends on it)

2. Discord Bot Setup

  • Bot created in Discord Developer Portal
  • Bot added to your Discord server with permissions:
    • Send Messages
    • Embed Links
    • Read Message History
    • Use Slash Commands
    • Create Public Threads
    • Manage Threads
  • Intents enabled: Message Content, Server Members

3. Dependencies Installed

cd packages/discord-bot
npm install

4. Missing Files to Create

The bot is missing these core files (they need to be created):

src/index.ts (Main bot entry point)

  • Load Discord.js client
  • Register command handlers
  • Register interaction handlers
  • Connect to Factory WebSocket
  • Listen for events and route to correct channels

src/register-commands.ts (Command registration script)

  • Load all command definitions
  • Use Discord REST API to register commands
  • Should support both guild and global registration

src/logger.ts (Logging utility)

  • Simple console logger or winston/pino
  • Used throughout codebase (import { logger } from './logger.js')

src/bridge/ (WebSocket event bridge)

  • Connect to Factory WebSocket
  • Listen for factory events (deploy, stage change, task created, SLA warning)
  • Route events to correct Discord channels using embeds
  • Should be empty currently — needs implementation

.env.example (Template for environment variables)

  • Copy of env vars with placeholder values
  • Documents what each variable is for

📝 How to Register Slash Commands

Important: Commands must be registered before the bot can respond to them.

cd packages/discord-bot
npm run register-commands

This registers commands to your specific Discord server (via DISCORD_GUILD_ID). Commands appear instantly.

Option 2: Global Commands (Slow, for production)

Modify register-commands.ts to use global endpoint instead of guild endpoint. Commands take up to 1 hour to propagate.

Note: You need to create src/register-commands.ts first. It should:

import { REST } from '@discordjs/rest';
import { Routes } from 'discord-api-types/v10';
import { SlashCommandBuilder } from 'discord.js';
import { config } from './config.js';

// Import all command modules
import * as status from './commands/status.js';
import * as pipelines from './commands/pipelines.js';
// ... import all 7 commands

const commands = [
  new SlashCommandBuilder()
    .setName('factory')
    .setDescription('GooseFactory pipeline management')
    .addSubcommand(status.data)
    .addSubcommand(pipelines.data)
    // ... add all subcommands
].map(cmd => cmd.toJSON());

const rest = new REST({ version: '10' }).setToken(config.DISCORD_TOKEN);

// Register commands
await rest.put(
  Routes.applicationGuildCommands(config.DISCORD_CLIENT_ID, config.DISCORD_GUILD_ID),
  { body: commands }
);

console.log('✅ Commands registered!');

▶️ How to Start the Bot

Development Mode (with hot reload)

cd packages/discord-bot
npm run dev

This uses tsx watch to automatically reload on file changes.

Production Mode

cd packages/discord-bot
npm run build    # Compile TypeScript
npm start        # Run compiled JavaScript

Expected Startup Output

[INFO] Loading configuration...
[INFO] Environment validated
[INFO] Connecting to Discord...
[INFO] Logged in as GooseFactory#1234
[INFO] Connecting to Factory WebSocket at wss://api.goosefactory.dev/v1/ws
[INFO] Factory bridge connected
[INFO] Bot is ready!

If startup fails:

  • Check .env for missing/invalid values
  • Verify Factory API is reachable
  • Check bot token is valid
  • Ensure bot is added to Discord server

🧪 How to Test Each Command

Once bot is running and commands are registered:

1. Test /factory status

/factory status

Expected: Dashboard embed with pipeline counts, task stats, agent status, SLA info.

2. Test /factory pipelines

/factory pipelines
/factory pipelines status:active
/factory pipelines pipeline_id:pipe_abc123

Expected: List of pipelines or detailed pipeline view with progress bar.

3. Test /factory queue

/factory queue
/factory queue priority:high
/factory queue batch:true

Expected: List of pending tasks or batch review embed with approve buttons.

4. Test /factory approve

/factory approve task_id:task_xyz789 notes:"LGTM!"

Expected: Task embed updated to "Approved" state, green color.

5. Test /factory reject

/factory reject task_id:task_xyz789 reason:"Tests are failing" changes:"Fix unit tests, Add error handling"

Expected: Task embed updated to "Rejected" state, red color, reason displayed.

6. Test /factory deploy

/factory deploy pipeline_id:pipe_abc123 target:staging dry_run:true
/factory deploy pipeline_id:pipe_abc123 target:staging

Expected: Deploy status embed posted to #factory-deploys channel.

7. Test /factory blockers

/factory blockers
/factory blockers pipeline_id:pipe_abc123

Expected: List of blockers with suggested actions, or "No blockers" message.

8. Test Button Interactions

Find an approval request message in #factory-tasks and click:

  • Approve button: Should update embed to green "Approved" state
  • Reject button: Should open modal for rejection reason
  • Details button: Should create thread with full task details
  • Defer button: Should escalate task internally

9. Test Modal Submission

Click Reject button → Fill in modal → Submit Expected: Embed updates to red "Rejected" state with reason displayed.

10. Test Batch Actions

Use /factory queue batch:true → Click "Approve All Low-Risk" Expected: Multiple tasks approved at once, summary message displayed.


🛠️ Troubleshooting

Commands not appearing

  • Run npm run register-commands again
  • Check DISCORD_GUILD_ID is correct
  • Wait up to 1 hour if using global commands
  • Try kicking and re-inviting the bot

"Missing Access" errors

  • Check bot has correct permissions in channel
  • Verify channel IDs in .env are correct
  • Ensure bot role is above any channel-specific permission overrides

API errors

  • Verify FACTORY_API_URL is correct and reachable
  • Check FACTORY_API_KEY is valid
  • Look for 401/403 errors in logs (auth issue)
  • Check Factory API logs for request details

WebSocket disconnects

  • Factory WebSocket may require reconnection logic
  • Check FACTORY_WS_URL is correct
  • Verify API key works for WebSocket auth

Buttons not working

  • Check interaction handlers are registered in index.ts
  • Verify message was sent by bot (can't interact with old messages)
  • Check bot has "Use Application Commands" permission

📦 Missing Implementation

The following features are designed but not yet implemented:

  1. WebSocket Bridge (src/bridge/)

    • Should listen to Factory events and post to Discord
    • Events to handle:
      • task.created → Post approval request to #factory-tasks
      • task.sla_warning → Post SLA warning to #factory-alerts
      • task.sla_breach → Post critical alert to #factory-alerts
      • deploy.started → Post to #factory-deploys
      • deploy.completed → Update deploy message
      • pipeline.stage_changed → Post to #factory-feed
  2. Core Bot Files

    • src/index.ts — Main entry point
    • src/logger.ts — Logging utility
    • src/register-commands.ts — Command registration script
  3. Configuration

    • .env.example — Template for environment setup

📊 Summary

What's Complete

  • 7 slash commands fully implemented
  • 5 embed types with rich formatting
  • 3 interaction handlers (buttons, modals, selects)
  • API client with full Factory API coverage
  • Type-safe config with Zod validation

What's Needed to Go Live

  1. Create src/index.ts (bot entry point)
  2. Create src/register-commands.ts (command registration)
  3. Create src/logger.ts (logging)
  4. Implement src/bridge/ (WebSocket event bridge)
  5. Create .env.example template
  6. Get Discord bot token from Developer Portal
  7. Get Factory API key
  8. Set up 4 Discord channels and get their IDs
  9. Register commands: npm run register-commands
  10. Start bot: npm run dev

🎯 Next Steps

  1. Create missing infrastructure files (index, logger, register-commands)
  2. Set up Discord bot (get token, add to server, get channel IDs)
  3. Get Factory API access (API key, verify endpoints)
  4. Register commands and test each one
  5. Implement WebSocket bridge for real-time events
  6. Deploy to production (PM2, Docker, or systemd service)

Total Implementation Status:

  • Commands: 7/7
  • Embeds: 5/5
  • Interactions: 3/3
  • API Integration: 100%
  • Infrastructure: 0%
  • Event Bridge: 0%