Skip to main content
Some people send every Slack message in ALL CAPS!!!! This walkthrough builds a small Python tool that detects those messages, runs them through /v1/whisper to lowercase them, and emits a calmer version. You can drop the result into a chat display, an internal feed, or a late-night digest where everyone is too tired for shouting. Two paths are covered:
  • Batch mode. Read a Slack export (or any list of messages) from JSON, rewrite the shouty ones, write the result back. Runnable without any Slack credentials.
  • Live mode. A Slack Bolt app that listens to channel messages and posts a calmed reply in-thread when shoutiness crosses a threshold.

What you will build

Given an input file messages.json:
The tool produces quiet.json:
Lowercase messages pass through unchanged. Only the screamers get whispered.

Prerequisites

  • Python 3.10 or newer.
  • pip install requests for batch mode.
  • pip install slack-bolt for live mode (optional).
  • An ACAAS API key in ACAAS_API_KEY. The demo key works.
  • For live mode: a Slack workspace where you can install a bot, plus a bot token (SLACK_BOT_TOKEN) and an app-level token (SLACK_APP_TOKEN).

Step 1: Decide what counts as shouty

Before calling the API, decide which messages deserve a whisper. A simple heuristic combines two signals: how much of the message is uppercase, and how many exclamation marks it carries.
shoutiness.py
The thresholds are deliberately conservative. A message is only flagged as shouty if more than 60% of its letters are uppercase or if exclamation marks make up more than 5% of the text. Tune them to taste — a more permissive 0.4 ratio also catches mixed-case yelling like “Why Are We Doing This Again.” A quick sanity check:

Step 2: Whisper a single message

Wrap /v1/whisper in a function. Reuse the Client pattern from the release notes cookbook, or use this minimal inline version:
whisperer.py
For production code, fold in retry handling for 429 and 5xx as shown in the errors reference. For this walkthrough, the bare call keeps the focus on the use case.

Step 3: Process a batch

Wire the heuristic and the whisperer together. The function below preserves message order and metadata, only mutating text when shoutiness fires.
calm_batch.py
Run it:
The shouty messages now read at conversational volume. Original timestamps, user IDs, and any other fields you carry through are preserved untouched — only text is rewritten and a calmed boolean is added so downstream code can highlight or count rewrites.

Step 4: Wire it to a live Slack channel

Skip this section if batch processing is enough. For real-time calming, use Slack Bolt for Python with Socket Mode so you do not need a public URL.
quiet_bot.py
A few choices worth calling out:
  • Reply in-thread, do not edit. Slack’s API only lets a bot edit messages it posted itself. Posting a calmed reply in-thread keeps the original message intact and lets the author see the contrast.
  • Skip subtypes and bot messages. Channel joins, edits, and the bot’s own posts arrive as the same message event. Filtering them prevents loops and noise.
  • Italics for the prefix. _at conversational volume:_ reads as a gentle aside in Slack, not a callout.
Required scopes for the bot: chat:write, channels:history, groups:history, im:history, mpim:history, plus the corresponding message.* event subscriptions. Install the app to a test channel before turning it loose on #general.
Auto-rewriting other people’s messages — even as a thread reply — can feel passive-aggressive. Pilot the bot in an opt-in channel first, and consider a slash command (/whisper) as a less invasive alternative.

Step 5: Smoke-test the heuristic

Before turning the bot on, run the heuristic against a varied corpus to make sure the threshold is tuned for your team. The included fixture covers the usual cases:
smoke.py
Expected output on the sample fixture:
Adjust thresholds in shoutiness.py until your own corpus produces sensible flags before connecting to a live workspace.

What you learned

  • Heuristic before API call. A cheap local check (is_shouty) keeps most messages out of the request path entirely. Only the loud ones cost a quota slot.
  • Preserve metadata, mutate only what you must. Carrying user, ts, and any other fields through unchanged makes the calmed output a drop-in replacement for the original.
  • Reply, do not rewrite. Posting a thread reply respects authorship and Slack’s API permissions.
  • Pilot before you scale. Auto-rewriting tone is a social intervention as much as a technical one. Start in a small, consenting channel.

Next steps

Release notes amplifier

The companion cookbook — uses scream and emphasize end-to-end.

Whisper reference

Full request and response schema for /v1/whisper.

Errors

Add retry handling once you move past the demo key.

Rate limiting

Pace the bot if your channel is genuinely chatty.