# 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 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) | | 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-constructs` for 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 ```bash 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 documents - `AgentId` — Bedrock Agent ID - `SlackWebhookUrl` — URL to register in Slack app settings - `NotionSecretName` — 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. ```bash aws s3 cp ./your-docs/ s3:/// --recursive ``` ### 2. Trigger KB sync ```bash aws bedrock-agent start-ingestion-job \ --knowledge-base-id \ --data-source-id \ --region us-east-1 ``` Or trigger from the Bedrock console: **Knowledge Bases → seahaven-kb → Sync**. ### 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 (`secret_...`) 4. In AWS Console: **Secrets Manager → `seahaven/notion/api-key` → Edit** — set `apiKey` to your token 5. Run a manual test: ```bash 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](https://api.slack.com/apps): 1. **Event Subscriptions** → enable → set Request URL to `https://bot.seahaven.com/slack/events` 2. Subscribe to bot event: `message.im` 3. **OAuth & Permissions** → Bot Token Scopes: `chat:write`, `im:history` 4. **App Home** → Messages Tab → enable, allow users to send messages 5. 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](https://developer.intuit.com/app/developer/playground) and update the `seahaven/qbo/oauth` secret. - **Notion sync** runs daily at 02:00 UTC automatically. To trigger an immediate sync, invoke `seahaven-notion-sync` manually via the Lambda console or CLI. - **PO sync** runs daily at 02:00 UTC. Scans the `purchase-orders` DynamoDB table (from [po-ingest](https://github.com/Sea-Haven-Industries/po-ingest)) and exports each PO as markdown to the KB. Manual trigger: invoke `seahaven-po-sync`. - **Work order sync** runs daily at 02:00 UTC. Scans `WorkOrders` and `WorkOrderComments` DynamoDB tables (from [workorder-ingest](https://github.com/Sea-Haven-Industries/workorder-ingest)) and exports each work order + comment history as markdown to the KB. Manual trigger: invoke `seahaven-workorder-sync`. - **Site assignments** are stored in the `SiteAssignments` DynamoDB table. To update, re-run the seed script with the latest CSV: ```bash npx tsx scripts/seed-sites.ts path/to/updated-site-list.csv ``` The site markdown file in the KB bucket (`sites/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.