The Problem
A 25-person engineering team runs everything through Slack, but their workflows are entirely manual. The team lead posts standup prompts every morning and manually compiles responses into a summary. Incident alerts from PagerDuty go to a channel where someone has to manually create a war room, tag the on-call engineer, and start a timeline. Deployment approvals happen through DMs that get lost in the scroll. PTO requests live in a spreadsheet that someone updates twice a week.
Every week, 6-8 hours of engineering time goes to coordination that could be automated. Worse, the manual processes have gaps: approvals get forgotten, standup summaries miss people who responded late, and the PTO spreadsheet is always a week behind reality. The information exists in Slack -- it just needs structure.
The Solution
Use slack-bot-builder to create interactive Slack bots with slash commands and scheduled messages, coding-agent to implement the business logic and database layer, and n8n to connect external services like PagerDuty, Google Calendar, and GitHub.
Step-by-Step Walkthrough
Step 1: Build the Standup Automation
Build a Slack bot using the Bolt framework that automates daily standups.
Every weekday at 9:00 AM, it posts a standup prompt to #engineering with
three thread reply buttons: "Yesterday", "Today", "Blockers". Team members
click each button, get a modal to fill in their update, and the bot compiles
all responses into a summary posted at 9:30 AM. Include a /standup-skip
command for days off. Store responses in SQLite.
At 9:00 AM every weekday, a Block Kit message appears in #engineering with three buttons: "Yesterday," "Today," and "Blockers." Clicking a button opens a modal -- much cleaner than asking people to format thread replies.
At 9:30 AM, the bot compiles every response into a formatted summary:
Daily Standup — Tuesday, Feb 18
Alex Chen
Yesterday: Shipped the notification preferences UI
Today: Starting delivery tracking integration
Blockers: None
Priya Nair
Yesterday: Fixed the Redis connection pool leak
Today: Load testing the chat WebSocket server
Blockers: Need staging environment credentials from DevOps
Blockers get a special treatment -- any standup with a blocker also posts to #blockers with a mention of the team lead. /standup-skip marks a team member as "out today" so the summary does not flag them as missing.
Responses persist in SQLite, so a /standup-history @alex last week command shows what anyone reported over a given period. Useful for 1:1 prep.
Step 2: Create the Incident Response Workflow
Add an incident command: /incident-create [severity] [title]. When triggered,
the bot should:
1. Create a new channel #inc-{date}-{short-title}
2. Set the channel topic to the incident description
3. Invite the current on-call person (query PagerDuty API)
4. Post an incident template with severity, status, and timeline
5. Pin a running timeline that auto-updates when people post updates
6. Add reaction-based status updates (red for investigating, yellow for identified, green for resolved)
When resolved, generate a summary and post to #incidents.
When someone types /incident-create P1 Payment processing down, the following happens in under 2 seconds:
- A new channel
#inc-20260218-payment-processingis created - The channel topic is set to "P1 -- Payment processing down"
- The current on-call engineer is fetched from the PagerDuty API and auto-invited
- A pinned message appears with the incident template:
Incident: Payment processing down
Severity: P1
Status: Investigating
Commander: @oncall-engineer
Created: 2026-02-18 14:23 UTC
Timeline:
14:23 — Incident created by @alex
Team members use /incident-update Fixed the connection pool exhaustion to append entries to the pinned timeline. Reactions on the pinned message change the status: red circle for investigating, yellow circle for identified, green circle for resolved.
When someone marks resolved, the bot generates a summary (duration, timeline, participants) and posts it to #incidents for the historical record. The incident channel gets archived after 7 days.
The manual version of this -- creating a channel, tagging on-call, starting a doc, updating stakeholders -- took 15 minutes of scrambling during an active outage. The automated version takes 2 seconds.
Step 3: Set Up Deployment Approvals
Build a deployment approval flow: when someone runs /deploy [service] [env],
the bot posts an approval request to #deployments with the service name,
environment, git diff summary (from GitHub API), and Approve/Reject buttons.
For staging: any engineer can approve. For production: requires approval from
a team lead (check Slack user group membership). Track all deployments in a
database with who requested, who approved, and timestamp.
/deploy payments-api production posts an approval request to #deployments:
Deployment Request
Service: payments-api
Environment: production
Requested by: @alex
Branch: fix/connection-pool (3 commits ahead of main)
Changes:
+ lib/pool.ts — Fix connection pool exhaustion under load
+ tests/pool.test.ts — Add pool stress test
~ config/production.json — Increase max connections 20 → 50
[Approve] [Reject]
The diff summary comes from the GitHub API -- the bot fetches the compare between the branch and main, summarizing changed files. For staging deploys, any engineer can click Approve. For production, the bot checks Slack user group membership and only accepts approvals from @team-leads.
Every deployment is recorded: who requested, who approved, when, and what changed. /deploy-history payments-api shows the last 10 deployments with their full approval chain. No more "did anyone approve this?" conversations.
Step 4: Automate PTO Tracking
Add /pto-request [dates] [reason] that creates an approval flow: posts to
the requester's manager (looked up from a team config), shows a calendar
view of team availability for those dates, and provides Approve/Deny buttons.
On approval, update Google Calendar, set a Slack status with vacation emoji for
those dates, and notify the team channel. Add /pto-calendar showing who's
out this week and next.
/pto-request Feb 24-28 Family vacation sends an approval request to the requester's manager (looked up from a team config JSON):
PTO Request
From: @alex (Backend team)
Dates: Feb 24-28 (5 days)
Reason: Family vacation
Team availability for those dates:
Feb 24 (Mon): 4/5 backend engineers available
Feb 25 (Tue): 4/5 backend engineers available
Feb 26 (Wed): 3/5 backend engineers available (Priya also out)
Feb 27 (Thu): 4/5 backend engineers available
Feb 28 (Fri): 4/5 backend engineers available
[Approve] [Deny]
The availability visualization is the key detail -- the manager immediately sees whether approving this request leaves the team short-handed on any day.
On approval, three things happen automatically: a Google Calendar event is created (via an n8n webhook), the user's Slack status updates to "On vacation" with a palm tree emoji for those dates, and #engineering gets a notification. No spreadsheet to update, no calendar to maintain.
/pto-calendar shows a weekly availability dashboard:
Team Availability — This Week
Mon Feb 17: Everyone in
Tue Feb 18: Everyone in
Wed Feb 19: Priya out (doctor appointment)
Thu Feb 20: Everyone in
Fri Feb 21: Alex out (half day)
Next Week
Mon Feb 24 - Fri Feb 28: Alex out (vacation)
Wed Feb 26: Priya out (personal)
Step 5: Connect Everything with n8n
Set up n8n workflows to connect the Slack bot with external services:
1. PagerDuty → Slack: route alerts to the right channel based on service
2. GitHub → Slack: post PR review requests to #code-review with approve/reject buttons
3. Google Calendar → Slack: morning digest of today's meetings posted to each person's DM
4. Slack → Jira: /ticket command creates a Jira issue from Slack with context
Show me the n8n workflow JSON for each integration.
Four n8n workflows bridge Slack with the external tools the team already uses:
- PagerDuty -> Slack: Webhook receives alerts, routes to the correct channel based on the affected service (payments alerts go to #payments-alerts, infra alerts go to #infra-alerts). P1 alerts also trigger the incident creation workflow.
- GitHub -> Slack: When a PR is tagged "ready for review," a message appears in #code-review with the title, description, and Approve/Request Changes buttons that map back to the GitHub review API.
- Google Calendar -> Slack: At 8:30 AM, each engineer gets a DM with their meetings for the day, including join links. No more checking the calendar separately.
- Slack -> Jira:
/ticket Bug: payments timeout on large orderscreates a Jira issue with the channel context, message permalink, and reporter automatically populated.
Each workflow includes an error handling node that posts failures to #bot-errors. If the PagerDuty webhook fails, the team knows within seconds instead of discovering it during an incident.
Real-World Example
An engineering manager at a 30-person SaaS company deploys the standup bot first. Daily compilation that used to take 20 minutes of manual work now takes zero. The incident workflow launches the following week and reduces mean-time-to-organize from 15 minutes of scrambling to 2 seconds.
Deployment approvals create a complete audit trail -- the team can trace every production deploy back to who requested it, who approved it, and what changed. PTO tracking moves from a spreadsheet to Slack, and the team sees availability at a glance for the first time.
Total time saved: 8+ hours per week across the team. More importantly, every decision -- every deploy approval, every incident timeline, every PTO request -- is documented automatically. The team stops losing information to Slack scroll.