
Key contributions
- Slack bot that responds to
/summary
commands and @mentions, summarizing messages from channels and threads. - Event‑driven architecture with AWS Lambda (Python 3.11) and no persistent infrastructure.
- Integration with Slack Events API and Slash Commands via Lambda Function URLs.
- Secure credential management using AWS Secrets Manager.
- Robust signature verification, message parsing, retry logic and error handling.
- Support for dynamic user and channel name resolution.
- App Home interface built using Slack Block Kit for onboarding and quick help.
Highlights
- Natural‑language summaries in Slack with near real‑time performance.
- Clean, minimal deployment with no external dependencies.
- Hands‑on experience with the Slack platform, OpenAI API and serverless operations.
How It Works
- A user sends a command (@mention or /summary) to the bot
- Slack sends an event to AWS Lambda, which triggers a Lambda function
- Lambda verifies the request signature and processes the Slack event
- The bot fetches relevant conversation history using the Slack API
- It sends messages to the OpenAI API for summarization
- The generated summary is posted back to Slack
Implementation
Slack part
- Go to https://api.slack.com/apps
- Create a new app (from scratch)
- Enable the following:
- App Home: Enable Home Tab
- Event Subscriptions: Enable and provide AWS Lambda function URL endpoint
- Bot Token Scopes:
app_mentions:read # Allow the bot to read messages where it's mentioned
channels:history # Read message history from public channels
channels:read # List public channels in the workspace
chat:write # Post messages as the bot
commands # Enable use of slash commands (e.g., /summary)
groups:history # Read message history from private groups
groups:read # List private groups the bot is a member of
im:history # Read message history from direct messages
im:write # Send direct messages as the bot
users:read # Read basic user info (for name resolution in summaries)
- Events to Subscribe:
app_home_opened # Triggered when a user opens the App Home tab
app_mention # Triggered when the bot is mentioned in a channel
message.channels # Triggered for new messages in public channels
message.im # Triggered for new messages in direct messages (IMs)
- Install the app to your workspace and retrieve the OAuth token (starts with “xoxb-…”) and Slack signing secret
OpenAI Part
- Generate OpenAI API token (starting with “sk-…”)
AWS Part
- Navigate to AWS Secrets Manager and create a secret
{
"slack_bot_token": "xoxb-...",
"openai_api_key": "sk-...",
"slack_signing_secret": "..."
}
- Create IAM role for Lambda function with permissions
secretsmanager:GetSecretValue
lambda:InvokeFunction
Attach these inline policies to the role:
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
}
// Secrets Manager read‑write
{
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue",
"secretsmanager:PutSecretValue"
],
"Resource": "arn:aws:secretsmanager:*:*:secret:slackSummariserCreds*"
}
- Create a Lambda function using e.g. Python 3.11.
- Set handler to lambda_function.lambda_handler (depending on your code)
- Attach IAM Role from previous step
- Create environment variable referring to your secret, e.g.
SECRETS_ID = slackSummariserCreds
- Upload the Lambda code zip package
Lambda Function
Core Features
- Summarizes Slack conversations using OpenAI (GPT-4o)
- Supports threads, channels, and DMs
- Handles slash commands like /summary 2h #general
- Includes shared files and attachments in context
- Deduplicates requests to avoid double-processing
- Verifies Slack request signatures
- Caches user/channel lookups to reduce API calls
- Handles API errors and shows friendly messages
- Supports help prompts and onboarding
Workflow Breakdown:
- Event Entry Point:
Lambda is triggered by Slack events or internal jobs and routes based on the request type. - Signature Verification:
Validates requests using Slack’s signing secret. - Command Detection:
Recognizes patterns likesummary 2h #general
from DMs, mentions, or slash commands. - Request Deduplication:
Prevents duplicate requests by caching request IDs. - Request Routing:
Routes to worker mode, slash processor, or inline summarization based on the request. - Message Fetching:
Pulls messages and threads from the Slack API, excluding bot messages. - Text Normalization:
Converts Slack formatting (e.g.,@user
,#channel
, user groups) to readable text. - Summarization via OpenAI:
Callsgpt-4o
with a structured prompt and handles retries or truncating if needed. - Posting the Result:
Replies in the same thread or channel with the summary. - Caching and Cleanup:
Caches metadata lookups and clears expired entries regularly.
- Event Entry Point:
Lessons Learned
Avoid Duplicate Processing with Caching
- Slack can resend the same event multiple times.
- Adding hashed request IDs and short-term caches prevents duplicate summaries and spammy replies.
Slack Mentions Require Careful Resolution
- Slack uses internal IDs like
<@U12345>
and<#C67890>
that must be converted into human-readable names. - Extra effort is needed for user groups, apps, and workflows to avoid unresolved IDs in summaries.
- Slack uses internal IDs like
Don’t Rely on Channel Names Alone
- Channel names can be ambiguous or change over time.
- Always validate channel names using the Slack API and support both
#name
and<#ID|name>
formats.
Use Background Workers for Slash Commands
- Slack slash commands expect quick responses.
- Offload the summarization to a separate asynchronous Lambda call to avoid timeouts and improve user experience.
Handle Bot Loops Proactively
- Bot messages can trigger the bot itself if not filtered.
- Filtering out messages from the bot’s own user ID avoids endless loops.
Respect OpenAI API Limits
- Large conversations can exceed token limits or cause 400 errors.
- Add safeguards to truncate long inputs and retry intelligently on failure.
Fail Gracefully with User-Friendly Errors
- If the bot isn’t in a channel or a Slack API fails, show helpful guidance.
- For example: suggest
/invite @ThreadDigest
instead of just failing silently.
Slack User Input Needs Normalization
- Users often mix up
@general
and#general
. - Add validation and correction messages to guide users toward the correct format.
- Users often mix up
Summarizing Threads Is Essential
- Many key conversations happen in thread replies, especially in channels like
#alerts
or#support
. - Including all thread messages produces more complete and useful summaries.
- Many key conversations happen in thread replies, especially in channels like
User Caches Reduce Slack API Load
- Repeated lookups for users, channels, and apps are expensive.
- Adding positive and negative caching significantly improves performance and reliability.
Be Conservative with Regex Matching
- Overeager regexes can misinterpret raw IDs or unrelated strings.
- Keep match patterns strict and scoped to known formats to avoid false positives.