- Create SiteAssignments DynamoDB table with state GSI for site code and state-based queries - Add lookup_site function to wo-po-lookup action group lambda - Add seed script (scripts/seed-sites.ts) to load site CSV into DynamoDB - Upload site list markdown to KB S3 bucket for semantic search - Update agent instruction to include site lookup capability - Update README with site assignment docs and maintenance notes
8.1 KiB
Seahaven Slack Bot
Internal Slack DM assistant for Sea Haven Industries, powered by AWS Bedrock. Employees can ask questions about vendors, company policies, SOPs, SA8000 compliance, work orders, purchase orders, and Amazon site assignments via direct message.
Architecture
Slack DM
│
▼
API Gateway (bot.seahaven.com)
│
▼
slack-webhook Lambda ← verifies Slack signature, returns 200 immediately
│ (async invoke)
▼
slack-processor Lambda ← calls Bedrock Agent, logs to DynamoDB, posts reply
│
▼
Bedrock Agent (Claude Sonnet 4.5)
├── Knowledge Base (AOSS + S3) ← SA8000 docs, SOPs, employee handbook, Notion pages, POs, work orders, site list
├── QBO_Lookup action group ← QuickBooks vendor search
├── Google_Maps_Lookup action group ← fallback vendor search
└── WO_PO_Lookup action group ← work order, purchase order, and site lookups (DynamoDB direct)
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
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) |
| Conversation Log | DynamoDB seahaven-conversations (90-day TTL) |
| PO Data Source | DynamoDB purchase-orders (via po-ingest) |
| Work Order Data Source | DynamoDB WorkOrders + WorkOrderComments (via workorder-ingest) |
| Site Assignments | DynamoDB SiteAssignments (seeded from CSV via scripts/seed-sites.ts) |
| Webhook URL | https://bot.seahaven.com/slack/events |
Prerequisites
- Node.js 22+
- AWS CDK (
npm install -g aws-cdk) - Docker Desktop (required by
@cdklabs/generative-ai-cdk-constructsfor Lambda bundling) - AWS credentials configured locally
Secrets Manager
These secrets must exist before deploying. The Slack, QBO, and Maps secrets must be created manually before first deploy. The Notion secret is created automatically by CDK with a placeholder — update it after deploy.
| Secret Name | Created | Structure |
|---|---|---|
seahaven/slack/credentials |
Manual (pre-deploy) | { "botToken": "xoxb-...", "signingSecret": "..." } |
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 and vector index creation are the slow steps — both handled automatically.
Stack outputs after deploy:
KBDocsBucketName— S3 bucket to upload knowledge base documentsAgentId— Bedrock Agent IDSlackWebhookUrl— URL to register in Slack app settingsNotionSecretName— Secrets Manager secret to populate with your Notion integration token
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. Supported formats: PDF, DOCX, TXT, HTML, CSV, XLSX.
aws s3 cp ./your-docs/ s3://<KBDocsBucketName>/ --recursive
2. Trigger KB sync
aws bedrock-agent start-ingestion-job \
--knowledge-base-id <AgentId from outputs> \
--data-source-id <DataSourceId> \
--region us-east-1
Or trigger from the Bedrock console: Knowledge Bases → seahaven-kb → Sync.
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 (
secret_...) - In AWS Console: Secrets Manager →
seahaven/notion/api-key→ Edit — setapiKeyto your token - Run a manual test:
aws lambda invoke \
--function-name seahaven-notion-sync \
--region us-east-1 \
--log-type Tail \
--query 'LogResult' \
--output text \
/dev/null | base64 -d
The sync runs automatically every day at 02:00 UTC via EventBridge.
4. Configure Slack app
In the Slack API dashboard:
- Event Subscriptions → enable → set Request URL to
https://bot.seahaven.com/slack/events - Subscribe to bot event:
message.im - OAuth & Permissions → Bot Token Scopes:
chat:write,im:history - App Home → Messages Tab → enable, allow users to send messages
- Reinstall to workspace if prompted
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 Bedrock Agent + QBO/Maps/WO-PO-Site action groups
slack-handler.ts API Gateway + webhook/processor Lambdas
conversation-log.ts DynamoDB table
notion-sync.ts EventBridge daily cron + notion-sync Lambda + Secrets Manager
po-sync.ts EventBridge daily cron + po-sync Lambda
workorder-sync.ts EventBridge daily cron + workorder-sync Lambda
lambda/
slack-webhook/ Verifies Slack signature, fires processor async
slack-processor/ Calls agent, writes DynamoDB, posts Slack reply
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, and site code 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)
seed-sites.ts Load Amazon site assignments CSV into DynamoDB
Known Maintenance Items
- QBO refresh token expires after 100 days of inactivity. Rotate via the Intuit OAuth Playground and update the
seahaven/qbo/oauthsecret. - Notion sync runs daily at 02:00 UTC automatically. To trigger an immediate sync, invoke
seahaven-notion-syncmanually via the Lambda console or CLI. - PO sync runs daily at 02:00 UTC. Scans the
purchase-ordersDynamoDB table (from po-ingest) and exports each PO as markdown to the KB. Manual trigger: invokeseahaven-po-sync. - Work order sync runs daily at 02:00 UTC. Scans
WorkOrdersandWorkOrderCommentsDynamoDB tables (from workorder-ingest) and exports each work order + comment history as markdown to the KB. Manual trigger: invokeseahaven-workorder-sync. - Site assignments are stored in the
SiteAssignmentsDynamoDB table. To update, re-run the seed script with the latest CSV:
The site markdown file in the KB bucket (npx tsx scripts/seed-sites.ts path/to/updated-site-list.csvsites/amazon-site-assignments.md) should also be regenerated and re-uploaded, then trigger a KB ingestion job. - KB sync for manual S3 uploads (non-Notion docs) must still be triggered manually after uploading new documents to the S3 bucket.