A FastAPI-based Slack app to manage and broadcast "AFK" (away-from-keyboard) status updates in your Slack workspace. Team members can quickly set AFK windows with a natural-language phrase using the /afk slash command, list current AFKs, view a monospace table, or clear their status. Records are stored in MongoDB and messages are posted via Slack Block Kit.
- /afk : Parse a natural-language time range (e.g.,
for 1 hour,until 5pm,from 2pm to 3:30pm). If parsing fails, the bot opens an interactive modal to pick start/end. - /afk list: Shows active AFK entries for the workspace.
- /afk table: Shows a monospace table of active AFKs.
- /afk clear: Cancels your currently active AFK records.
- Persistence: Stores AFK records in MongoDB using Motor (async PyMongo).
- Locale-aware display: Uses user locale and timezone to render times.
- API server: FastAPI (
main.py)POST /v1/slack_bot: Slash command endpoint (form encoded) handling create/list/table/clear.POST /v1/interactive_message: Slack interactivity endpoint for the manual date-time submission flow.GET /health-check: Health endpoint.
- Core modules (
lib/)models.py: Pydantic models (AFKRecord, AFKRecordFilter, SlackPostRequestBody, UserInfo) and enums.command_handlers.py: Subcommand handlers and Slack message flow.services/:mongo_db.py: Initializes Motor client and exposesafk_records_collection.database_service.py: CRUD on AFK records and AFK clearing logic.slack_service.py: Slack WebClient integration and Block Kit builders.
utils.py: Helpers (MongoDB filter builder, formatting for display, etc.).
- Python 3.14+ (3.14 supported for local dev tooling)
- MongoDB (local or hosted)
- A Slack app with a bot token and the correct scopes
Provide these via .env (or your hosting provider’s secret manager). The app also reads /etc/secrets/.env when present (e.g., on some hosts).
Required:
SLACK_BOT_TOKEN— Bot token beginning withxoxb-...SLACK_SIGNING_SECRET— Slack signing secret for request verificationMONGODB_URI— MongoDB connection string (e.g.,mongodb://localhost:27017)PORT— Port for the FastAPI server (defaults to 8000 if unset)ENABLE_HOT_RELOAD—trueto enable Uvicorn reload in dev, otherwisefalse
Example .env:
SLACK_BOT_TOKEN=xoxb-***
SLACK_SIGNING_SECRET=***
MONGODB_URI=mongodb://localhost:27017
PORT=8000
ENABLE_HOT_RELOAD=true
Use the provided Makefile to create a virtualenv and install dependencies.
- Create venv and install dev deps:
make install_dev
-
Start MongoDB (local or Docker). For local Mongo: ensure it runs on
mongodb://localhost:27017or setMONGODB_URIaccordingly. -
Run the app:
make run
The server will start on http://localhost:8000. Visit http://localhost:8000/health-check to verify.
Notes:
- Slack request verification in
main.pyusesslack_sdk.signature.SignatureVerifierbut is currently commented out. For production, enable it by uncommenting those lines to validateX-Slack-SignatureandX-Slack-Request-Timestamp.
You can import manifest.json to speed up Slack app configuration.
Scopes (bot):
chat:write,chat:write.customize,chat:write.public,commands,users:read,channels:join
Slash command:
- Command:
/afk - Request URL:
https://<your-host>/v1/slack_bot - Short description: Manage AFK status
- Usage hint: for an hour
Interactivity:
- Enable interactivity
- Request URL:
https://<your-host>/v1/interactive_message
Install the app to your workspace and copy:
- Bot token →
SLACK_BOT_TOKEN - Signing secret →
SLACK_SIGNING_SECRET
In any channel where the bot is present:
/afk for an hour— Creates an AFK record for the next hour and posts a message./afk until 5pmor/afk from 2pm to 3:30pm— Natural language parsing viaafk_parser.- If parsing fails, an interactive date-time picker is sent.
/afk list— Shows active AFK entries./afk table— Shows a monospace table./afk clear— Cancels your active AFK entries.
Integration tests cover the database service with a real MongoDB in Docker.
Prerequisites:
- Docker and Docker Compose installed
Run the test suite:
make test
This will:
- Build a test image from
Dockerfile.test(Python 3.14, installs dev requirements) - Start MongoDB container and the tester container using
docker-compose-test.yaml - Execute
pytest -vv
Cleanup containers and network:
make cleanup
Remove the tester image (deep cleanup):
make cleanup_deep
- The repo includes a simple
vercel.jsonpointing atmain.py. For production use on Vercel or any other host, ensure:SLACK_BOT_TOKEN,SLACK_SIGNING_SECRET, andMONGODB_URIare configured as environment variables.- Public HTTPS URLs are set in Slack for slash command and interactivity.
- When hosting elsewhere (e.g., Render, Fly.io, Docker on a VPS), expose port
${PORT}and configure the same environment variables. The app will also load/etc/secrets/.envif available.
main.py— FastAPI app and HTTP routeslib/models.py— Pydantic models and enumslib/command_handlers.py— Command handlers and Slack message flowlib/services/mongo_db.py— Mongo client and collectionlib/services/database_service.py— Mongo CRUD and AFK clearinglib/services/slack_service.py— Slack Web API and Block Kit builderslib/utils.py— Utilities (formatting, query building)tests/— Pytest suite for database servicemanifest.json— Slack app manifest (import into Slack)Makefile— Dev tasks (install, test, lint, format)