A FastAPI Slack app for managing away-from-keyboard status updates in a Slack workspace. Team members use the /afk slash command to set AFK windows with natural-language phrases, list active AFKs, view a compact table, or clear their own status. Records are stored in MongoDB and responses are posted with Slack Block Kit.
- Features
- Architecture
- Requirements
- Configuration
- Install and Run Locally
- Slack App Setup
- Using the Bot
- Development Commands
- Testing
- Deployment Notes
- Project Layout
- Suggested Improvements
/afk <phrase>parses natural-language time ranges such asfor 1 hour,until 5pm, orfrom 2pm to 3:30pm./afk listshows active AFK entries for the workspace./afk tableshows active AFK entries in a monospace table./afk clearcancels the current user's active AFK entries.- Interactive fallback opens a Slack date-time picker when the phrase cannot be parsed.
- MongoDB persistence stores AFK records with Motor, the async PyMongo driver.
- Locale-aware display uses Slack user locale and timezone data when rendering times.
- API server:
main.pyPOST /v1/slack_bot: slash command endpoint for create, list, table, and clear flows.POST /v1/interactive_message: Slack interactivity endpoint for manual date-time submission.GET /health-check: health endpoint.
- Core modules:
lib/models.py: Pydantic models and enums.command_handlers.py: subcommand handlers and Slack response flow.services/mongo_db.py: Motor client initialization and collection wiring.services/database_service.py: AFK record CRUD and clear logic.services/slack_service.py: Slack Web API calls and Block Kit builders.utils.py: formatting, MongoDB filter construction, and shared helpers.
- Python 3.14+
uv- MongoDB, local or hosted
- Docker and Docker Compose for the containerized integration test flow
- A Slack app with a bot token and slash command support
Provide configuration through .env for local development, or through your hosting provider's secret manager in production. The app also loads /etc/secrets/.env when present.
Required variables:
| Variable | Description |
|---|---|
SLACK_BOT_TOKEN |
Slack bot token beginning with xoxb-.... |
SLACK_SIGNING_SECRET |
Slack signing secret used to verify incoming requests. |
MONGODB_URI |
MongoDB connection string, for example mongodb://localhost:27017. |
PORT |
HTTP port for the FastAPI server. Defaults to 8000. |
ENABLE_HOT_RELOAD |
Set to true to enable Uvicorn reload in development. |
Example .env:
SLACK_BOT_TOKEN=xoxb-***
SLACK_SIGNING_SECRET=***
MONGODB_URI=mongodb://localhost:27017
PORT=8000
ENABLE_HOT_RELOAD=trueInstall dependencies with uv:
make install_devStart MongoDB locally, or point MONGODB_URI at a hosted database. For a default local setup, use:
MONGODB_URI=mongodb://localhost:27017Run the app:
make runThe server starts on http://localhost:8000 by default. Check http://localhost:8000/health-check to confirm it is running.
Security note: Slack request verification is currently present in main.py but commented out. Enable it before production use so incoming requests are validated with X-Slack-Signature and X-Slack-Request-Timestamp.
Import manifest.json in Slack to speed up app configuration.
Bot scopes:
chat:writechat:write.customizechat:write.publiccommandsusers:readchannels: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
After installing the app to your workspace, copy the bot token to SLACK_BOT_TOKEN and the signing secret to SLACK_SIGNING_SECRET.
Use these commands in any channel where the bot is present:
/afk for an hour
/afk until 5pm
/afk from 2pm to 3:30pm
/afk list
/afk table
/afk clear
If the bot cannot parse the requested time range, it sends an interactive date-time picker.
The Makefile uses uv for Python dependency management and command execution.
| Command | Description |
|---|---|
make install |
Install production dependencies. |
make install_dev |
Install runtime and development dependencies. |
make run |
Run the FastAPI app with uv run. |
make lint |
Run Pyright. |
make format |
Format Python files with Ruff. |
make test_local |
Run pytest against the currently configured MongoDB. |
make test |
Run the Docker Compose integration test stack with Python 3.14. |
make cleanup |
Stop and remove the Docker Compose test stack. |
make cleanup_deep |
Remove the test stack and tester image. |
make upgrade_dependencies |
Upgrade dependencies through uv sync --upgrade. |
Integration tests cover the database service with a real MongoDB container.
Run the containerized test suite:
make testThis builds Dockerfile.test, starts MongoDB from docker-compose-test.yaml, and runs:
uv run pytest tests -vClean up containers and networks:
make cleanupRemove the tester image as well:
make cleanup_deepIf MongoDB is already available through MONGODB_URI, run local tests with:
make test_localTo run local tests with a specific Python version:
make test_local TEST_PYTHON=3.14The repo includes vercel.json pointing at main.py. For Vercel or another host:
- Configure
SLACK_BOT_TOKEN,SLACK_SIGNING_SECRET, andMONGODB_URIas environment variables. - Set public HTTPS Slack request URLs for slash commands and interactivity.
- Expose
${PORT}when deploying outside Vercel. - Ensure Slack request verification is enabled before accepting production traffic.
.
├── main.py
├── lib/
│ ├── command_handlers.py
│ ├── models.py
│ ├── utils.py
│ └── services/
├── tests/
├── manifest.json
├── pyproject.toml
├── uv.lock
├── Makefile
├── Dockerfile.test
└── docker-compose-test.yaml
- Enable Slack signature verification and add tests for rejected requests.
- Replace
printdiagnostics with structured logging. - Add CI that runs
make lintandmake test. - Add unit tests for slash-command routing, interactive payload handling, and Slack Block Kit output.
- Add a
.env.examplewith safe placeholder values. - Consider indexes for active AFK lookup fields in MongoDB if the workspace grows.