Internal Slack DM assistant for Sea Haven Industries, powered by AWS Bedrock
Bumps [fast-xml-builder](https://github.com/NaturalIntelligence/fast-xml-builder) from 1.1.5 to 1.2.0. - [Changelog](https://github.com/NaturalIntelligence/fast-xml-builder/blob/main/CHANGELOG.md) - [Commits](https://github.com/NaturalIntelligence/fast-xml-builder/compare/v1.1.5...v1.2.0) --- updated-dependencies: - dependency-name: fast-xml-builder dependency-version: 1.2.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> |
||
|---|---|---|
| .github | ||
| bin | ||
| lambda | ||
| lib | ||
| scripts | ||
| services/socket-mode | ||
| .gitignore | ||
| cdk.context.json | ||
| cdk.json | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| TODO.txt | ||
| tsconfig.json | ||
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
- QBO — existing vetted vendors in QuickBooks Online
- Knowledge Base — approved vendor lists in internal docs
- 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 documentsAgentId— 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
- Create a Notion internal integration at Settings → Connections → Develop or manage integrations
- Name it
seahaven-office-opsand associate it with the Office Operations teamspace - Copy the integration token and update: Secrets Manager →
seahaven/notion/api-key→ Edit
4. Configure Slack app
In the Slack API dashboard:
- Basic Information → update Display Name to "Alex", upload avatar
- Socket Mode → enable, generate app-level token with
connections:writescope - Store the app-level token in Secrets Manager as
seahaven/slack/app-level-token - Event Subscriptions → enable (no Request URL needed with Socket Mode)
- Subscribe to bot events:
message.im,app_mention,app_home_opened - OAuth & Permissions → Bot Token Scopes:
chat:write,im:history,app_mentions:read,channels:history,groups:history - App Home → enable Home Tab and Messages Tab
- Reinstall app to workspace
- 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-ordersDynamoDB table (from po-ingest). Manual trigger: invokeseahaven-po-sync. - Work order sync runs daily at 02:00 UTC. Scans
WorkOrdersandWorkOrderComments(from workorder-ingest). Manual trigger: invokeseahaven-workorder-sync. - Site assignments are auto-populated from the
verified-sitesDynamoDB table, maintained by the po-ingest DynamoDB Streams pipeline. No manual seeding required. - Unanswered questions are logged to
seahaven-unanswered-questionswhen Alex detects it couldn't answer a question. Review via DynamoDB console — records havestatus: "pending"and 180-day TTL. - Socket Mode — the ECS Fargate task maintains a persistent WebSocket connection to Slack. Monitor via CloudWatch Logs (
socket-modelog stream). The service auto-restarts on failure.