Warning
This is a simple POC. The code hasn't been audited and there are no warranties it will be suitable for produciton environments. Actually... I do not recommend using it in production before securing it - by default there's no validation on the AWS Lambda endpoint, amongst other areas which require TLC (POC, remember?). Even if it won't be a lot of work to do that, it is not done yet.
Automatically generate structured incident postmortems in Notion from Slack incident channels using Claude AI.
the_coroner is a serverless pipeline that:
- Receives a Slack slash command from an incident channel
- Fetches Slack channel messages
- Extracts transcription links from message text
- Sends the combined context to Claude AI
- Creates a structured Notion page with the generated postmortem
- Replies to Slack with the Notion page URL
- Slack
/generate-postmortemslash command integration - Slack message retrieval with pagination
- Transcription link extraction from channel text
- Claude AI postmortem generation
- Notion page creation with structured content
- Ephemeral Slack response with link to the generated page
Slack (/generate-postmortem)
↓
API Gateway
↓
AWS Lambda (src/handlers/postmortemHandler.ts)
↓
Slack API, Claude API, Notion API
↓
Notion page created, Slack ephemeral reply sent
- Node.js 18+
- AWS SAM CLI
- AWS CLI (recommended)
- Slack App with slash command
- Notion integration with page access
- Claude / Anthropic API key
git clone <repository>
cd the_coroner
npm installStore these secrets in AWS Systems Manager Parameter Store:
| Parameter Name | Type | Description |
|---|---|---|
/notion-pm/slack-bot-token |
SecureString | Bot token from Slack App (xoxb-...) |
/notion-pm/slack-signing-secret |
SecureString | Signing secret from Slack App |
/notion-pm/notion-api-key |
SecureString | Notion integration secret |
/notion-pm/notion-incidents-parent-id |
String | Page ID of parent incidents page |
/notion-pm/claude-api-key |
SecureString | Anthropic API key (sk-ant-...) |
/notion-pm/claude-max-tokens |
String | Max tokens for Claude (optional, defaults to 4000) |
Create parameters using AWS CLI:
aws ssm put-parameter --name "/notion-pm/slack-bot-token" --value "xoxb-your-token" --type "SecureString"
aws ssm put-parameter --name "/notion-pm/slack-signing-secret" --value "your-signing-secret" --type "SecureString"
aws ssm put-parameter --name "/notion-pm/notion-api-key" --value "secret-your-key" --type "SecureString"
aws ssm put-parameter --name "/notion-pm/notion-incidents-parent-id" --value "your-page-id" --type "String"
aws ssm put-parameter --name "/notion-pm/claude-api-key" --value "sk-ant-your-key" --type "SecureString"
aws ssm put-parameter --name "/notion-pm/claude-max-tokens" --value "4000" --type "String"The SAM template automatically retrieves these parameters and makes them available to the Lambda function.
npm run buildsam deploy --guidedDuring deployment, the SAM template will:
- Create an IAM role for the Lambda function with SSM parameter read permissions
- Reference the SSM parameters you created in step 2
- Deploy the API Gateway and Lambda function
- Create a Slack App at https://api.slack.com/apps
- Add a Slash Command:
- Command:
/generate-postmortem - Request URL: your API Gateway endpoint
- Command:
- Install the app into your workspace
- Add the bot to the incident channel and use the slash command
- Create a Notion integration at https://www.notion.so/my-integrations
- Share the parent incidents page with the integration
- Use the parent page ID for
NOTION_INCIDENTS_PARENT_ID
Use these exact names in your deployment or local environment:
SLACK_BOT_TOKENSLACK_SIGNING_SECRETNOTION_API_KEYNOTION_INCIDENTS_PARENT_IDCLAUDE_API_KEYCLAUDE_MAX_TOKENS
CLAUDE_MAX_TOKENS is optional and defaults to 4000.
- Open the incident-only Slack channel
- Ensure the bot is present in the channel
- Run
/generate-postmortem - The Lambda will process the channel and create a Notion page
- A Slack ephemeral message returns the page URL
Key source files:
src/handlers/postmortemHandler.ts— receives Slack requests, verifies the signature, and triggers the servicesrc/services/postmortemService.ts— orchestrates Slack fetch, transcription extraction, Claude call, and Notion page creationsrc/clients/slackClient.ts— Slack API integrationsrc/clients/claudeClient.ts— Claude API integrationsrc/clients/notionClient.ts— Notion API integrationsrc/utils/extractTranscriptions.ts— transcription link extraction and fetch logicsrc/utils/ssmClient.ts— current environment variable mapping for secrets
Generated Notion pages follow this title pattern:
YY_MM_DD-Incident-<affected-stack>
Build and test locally:
npm run build
npm test
npm run lint- The current implementation does not use an AWS Secrets Manager integration; it reads environment variables directly.
- Transcription extraction is based on URL patterns and generic HTML text extraction.
- The Lambda runtime is Node.js 20 with 1024 MB memory and a 60-second timeout.
- Production deployments should harden the API endpoint and secure environment variable handling.
MIT