Internal Slack DM assistant for Sea Haven Industries, powered by AWS Bedrock
This repository has been archived on 2026-08-04. You can view files and clone it, but cannot push or open issues or pull requests.
Find a file
Adam Moussa e5752e6a5d fix: grant bedrock:GetGuardrail to agent execution role
The Bedrock Agents service fetches the guardrail config via GetGuardrail
before applying it. The role only had ApplyGuardrail, so every agent
invocation logged an AccessDenied and tripped the CIS 4.1
UnauthorizedAPICalls alarm.

Scoped to the same guardrail ARNs already granted for ApplyGuardrail.
Cross-reviewed (IAM change): APPROVE, no findings.
2026-06-04 16:42:55 -04:00
.github Enable QEMU for arm64 Docker builds (#29) 2026-05-08 17:48:19 -04:00
bin Initial scaffold: Bedrock-backed Slack DM bot 2026-04-11 23:15:15 -04:00
lambda fix: flat DM replies, clean up debug logging 2026-04-30 18:37:08 -04:00
lib fix: grant bedrock:GetGuardrail to agent execution role 2026-06-04 16:42:55 -04:00
scripts feat: Alex rollout — persona, Socket Mode, payments, channels, App Home, unanswered questions 2026-04-30 16:38:54 -04:00
services/socket-mode build(deps): bump axios from 1.15.2 to 1.16.1 in /services/socket-mode (#37) 2026-05-29 16:46:57 +00:00
.gitignore fix: flat DM replies, clean up debug logging 2026-04-30 18:37:08 -04:00
cdk.context.json Place QBO Lambdas in VPC for static outbound IP 2026-04-13 19:51:00 -04:00
cdk.json Initial scaffold: Bedrock-backed Slack DM bot 2026-04-11 23:15:15 -04:00
package-lock.json build(deps): bump the minor-and-patch group across 1 directory with 4 updates (#36) 2026-06-03 23:02:16 +00:00
package.json build(deps): bump the minor-and-patch group across 1 directory with 4 updates (#36) 2026-06-03 23:02:16 +00:00
README.md feat: Alex rollout — persona, Socket Mode, payments, channels, App Home, unanswered questions 2026-04-30 16:38:54 -04:00
TODO.txt Initial scaffold: Bedrock-backed Slack DM bot 2026-04-11 23:15:15 -04:00
tsconfig.json Upgrade to TypeScript ~6.0.3 (#19) 2026-05-06 19:56:57 -04:00

Seahaven Slack Bot — Alex

Internal Slack assistant for Sea Haven Industries, powered by AWS Bedrock. Employees can DM Alex or @mention Alex in any channel to ask about vendors, payments, work orders, purchase orders, Amazon sites, company policies, and more.

Architecture

Slack (WebSocket)
   │
   ▼
ECS Fargate (Socket Mode)                ← persistent WebSocket connection to Slack
   │
   ├── DM (message.im) ──────────────────┐
   ├── @mention (app_mention) ────────────┤
   │                              async invoke
   │                                      ▼
   │                              slack-processor Lambda    ← calls Bedrock Agent, logs to DynamoDB, posts reply
   │                                      │
   │                                      ▼
   │                              Bedrock Agent — Alex (Claude Sonnet 4.5)
   │                                      ├── Knowledge Base (AOSS + S3)
   │                                      ├── QBO_Lookup action group       ← QuickBooks vendor search (VPC, static IP)
   │                                      ├── Google_Maps_Lookup action group ← fallback vendor search
   │                                      └── WO_PO_Lookup action group     ← WO, PO, site, and payment lookups (DynamoDB direct)
   │
   └── App Home opened ──────────────────→ app-home Lambda  ← publishes Block Kit capabilities view

API Gateway (bot.seahaven.com)
   │
   └── GET /qbo/*
          ▼
       qbo-oauth Lambda (VPC, static IP)  ← OAuth 2.0 connect/callback/disconnect/launch
          Outbound IP: 52.202.83.13 (NAT Gateway in seahaven-vpc)

EventBridge (daily 02:00 UTC)
   │
   ├── notion-sync Lambda     ← exports Office Operations Notion pages → S3 → KB ingestion
   ├── po-sync Lambda         ← exports purchase-orders DynamoDB → S3 → KB ingestion
   └── workorder-sync Lambda  ← exports WorkOrders + Comments DynamoDB → S3 → KB ingestion

What Alex Can Do

  • Vendor Lookup — search QBO for existing vendors, KB for approved lists, Google Maps for new options
  • Payment & Invoice Status — check if a vendor has been paid, if an invoice is scheduled, look up by check number
  • Work Order Lookups — status, assignments, comments, and full history by WO number
  • Purchase Order Lookups — status, line items, supplier, and ship-to details by PO number
  • Site Lookups — Amazon facility address and details by site code, or list all sites in a state
  • Company Policies & SOPs — employee handbook, SA8000 compliance, and operational procedures

Vendor Query Priority

  1. QBO — existing vetted vendors in QuickBooks Online
  2. Knowledge Base — approved vendor lists in internal docs
  3. Google Maps — fallback for net-new vendor discovery

Stack

Resource Details
AWS Account 328440206208, us-east-1
CDK TypeScript, v2
LLM Claude Sonnet 4.5 (anthropic.claude-sonnet-4-5-20250929-v1:0)
Embeddings Amazon Titan Embed Text V2 (1024 dimensions)
Vector Store OpenSearch Serverless (VECTORSEARCH)
Socket Mode ECS Fargate (seahaven-socket-mode) — persistent WebSocket to Slack
Conversation Log DynamoDB seahaven-conversations (90-day TTL)
Unanswered Questions DynamoDB seahaven-unanswered-questions (180-day TTL)
Payment Data DynamoDB PaymentsDashboard (via payments-dashboard)
PO Data Source DynamoDB purchase-orders (via po-ingest)
Work Order Data Source DynamoDB WorkOrders + WorkOrderComments (via workorder-ingest)
Site Assignments DynamoDB verified-sites (auto-populated via po-ingest Streams pipeline)
VPC seahaven-vpc (vpc-0d3d4b67bd0cf8a68) — QBO Lambdas + Socket Mode
Static Outbound IP 52.202.83.13 (NAT Gateway for Intuit IP allowlist)
QBO OAuth URLs bot.seahaven.com/qbo/connect, /qbo/callback, /qbo/disconnect, /qbo/launch

Prerequisites

  • Node.js 22+
  • AWS CDK (npm install -g aws-cdk)
  • Docker Desktop (required for Lambda bundling and Socket Mode container build)
  • AWS credentials configured locally

Secrets Manager

These secrets must exist before deploying. The Slack, QBO, Maps, and app-level token secrets must be created manually before first deploy. The Notion secret is created automatically by CDK with a placeholder.

Secret Name Created Structure
seahaven/slack/credentials Manual (pre-deploy) { "botToken": "xoxb-...", "signingSecret": "..." }
seahaven/slack/app-level-token Manual (pre-deploy) Plaintext xapp-... token with connections:write scope
seahaven/qbo/oauth Manual (pre-deploy) { "clientId": "", "clientSecret": "", "refreshToken": "", "realmId": "" }
seahaven/google/maps-api-key Manual (pre-deploy) { "apiKey": "" }
seahaven/notion/api-key Auto (CDK) { "apiKey": "secret_..." }

Deployment

npm install
npx cdk bootstrap aws://328440206208/us-east-1   # first time only
npx cdk deploy

The deploy takes ~15 minutes on first run. The AOSS collection, vector index creation, and Docker image build are the slow steps.

Stack outputs after deploy:

  • KBDocsBucketName — S3 bucket to upload knowledge base documents
  • AgentId — Bedrock Agent ID (Alex)

Post-Deployment Setup

1. Upload knowledge base documents

Upload SA8000 compliance docs, SOPs, and the employee handbook to the S3 bucket printed in stack outputs.

aws s3 cp ./your-docs/ s3://<KBDocsBucketName>/ --recursive

2. Trigger KB sync

aws bedrock-agent start-ingestion-job \
  --knowledge-base-id <from Bedrock console> \
  --data-source-id <DataSourceId> \
  --region us-east-1

3. Configure Notion sync

  1. Create a Notion internal integration at Settings → Connections → Develop or manage integrations
  2. Name it seahaven-office-ops and associate it with the Office Operations teamspace
  3. Copy the integration token and update: Secrets Manager → seahaven/notion/api-key → Edit

4. Configure Slack app

In the Slack API dashboard:

  1. Basic Information → update Display Name to "Alex", upload avatar
  2. Socket Mode → enable, generate app-level token with connections:write scope
  3. Store the app-level token in Secrets Manager as seahaven/slack/app-level-token
  4. Event Subscriptions → enable (no Request URL needed with Socket Mode)
  5. Subscribe to bot events: message.im, app_mention, app_home_opened
  6. OAuth & Permissions → Bot Token Scopes: chat:write, im:history, app_mentions:read, channels:history, groups:history
  7. App Home → enable Home Tab and Messages Tab
  8. Reinstall app to workspace
  9. Invite Alex to channels: /invite @Alex

Project Structure

bin/
  seahaven-slack-bot.ts       CDK app entry point
lib/
  seahaven-slack-bot-stack.ts  Main stack
  constructs/
    knowledge-base.ts          Bedrock KB + AOSS + S3 (via @cdklabs L2 construct)
    bedrock-agent.ts           Alex — Bedrock Agent + QBO/Maps/WO-PO-Site-Payment action groups
    slack-handler.ts           Processor Lambda + App Home Lambda + QBO OAuth + API Gateway
    socket-mode.ts             ECS Fargate service running Slack Socket Mode client
    conversation-log.ts        DynamoDB conversation + unanswered questions tables
    notion-sync.ts             EventBridge daily cron + notion-sync Lambda
    po-sync.ts                 EventBridge daily cron + po-sync Lambda
    workorder-sync.ts          EventBridge daily cron + workorder-sync Lambda
services/
  socket-mode/                 Socket Mode ECS service (Dockerfile, TypeScript, @slack/socket-mode)
lambda/
  slack-processor/             Calls agent, writes DynamoDB, posts Slack reply
  app-home/                    Publishes Block Kit capabilities view to App Home tab
  qbo-oauth/                   OAuth 2.0 connect/callback/disconnect/launch for QuickBooks
  qbo-lookup/                  Bedrock action group — QuickBooks vendor search
  maps-lookup/                 Bedrock action group — Google Maps Places search
  wo-po-lookup/                Bedrock action group — WO, PO, site, and payment lookups (DynamoDB direct)
  notion-sync/                 Daily Notion → S3 export, triggers KB ingestion
  po-sync/                     Daily purchase-orders DynamoDB → S3 export, triggers KB ingestion
  workorder-sync/              Daily WorkOrders DynamoDB → S3 export, triggers KB ingestion
scripts/
  create-aoss-index.ts         Manual fallback for AOSS index creation (not needed in normal deploy)

Known Maintenance Items

  • QBO OAuth — the refresh token auto-rotates on every API call (persisted back to Secrets Manager). If the token ever expires (100 days of inactivity), reconnect via https://bot.seahaven.com/qbo/connect.
  • Notion sync runs daily at 02:00 UTC automatically. Manual trigger: invoke seahaven-notion-sync.
  • PO sync runs daily at 02:00 UTC. Scans purchase-orders DynamoDB table (from po-ingest). Manual trigger: invoke seahaven-po-sync.
  • Work order sync runs daily at 02:00 UTC. Scans WorkOrders and WorkOrderComments (from workorder-ingest). Manual trigger: invoke seahaven-workorder-sync.
  • Site assignments are auto-populated from the verified-sites DynamoDB table, maintained by the po-ingest DynamoDB Streams pipeline. No manual seeding required.
  • Unanswered questions are logged to seahaven-unanswered-questions when Alex detects it couldn't answer a question. Review via DynamoDB console — records have status: "pending" and 180-day TTL.
  • Socket Mode — the ECS Fargate task maintains a persistent WebSocket connection to Slack. Monitor via CloudWatch Logs (socket-mode log stream). The service auto-restarts on failure.