We had three Slack workspaces that needed the same IT support bot. The naive approach: deploy three separate apps. The smart approach: one app that handles all three.
The Problem
Each workspace needed identical functionality: create Jira tickets from Slack, route by type, track SLAs. But maintaining three codebases is a nightmare. Updates mean three deployments. Bugs mean three fixes.
The Architecture
workspace_config = {
"T01XXXX": {"name": "Main", "jira_project": "IT"},
"T02XXXX": {"name": "Target", "jira_project": "TG"},
"T03XXXX": {"name": "Longeron", "jira_project": "LG"}
}
def get_workspace(team_id):
return workspace_config.get(team_id)
The bot extracts team_id from every Slack event, looks up the config, and routes to the right Jira project. One codebase, one deployment, three workspaces.
How It Works
Every Slack event payload includes a team_id field identifying which workspace sent it. The bot uses this as a routing key:
- User submits a support request via Slack modal
- Bot reads
team_idfrom the event - Config lookup determines Jira project, channel IDs, SLA rules
- Ticket created in the correct Jira project with workspace-specific metadata
Adding a new workspace is a single config entry—no code changes, no redeployment.
Results
Key Lessons
- Multi-tenancy from day one. Even if you start with one client, architect for many.
- Config over code. New workspace = new config entry, not new deployment.
- DigitalOcean caches secrets. Updating app specs doesn't update encrypted values—check runtime logs.