If your app is installed on multiple workspaces, you cannot use a single token in the App constructor. Instead, you can provide a custom authorize function to the App instantiation.
This function is called for every incoming request. It receives enterprise_id, team_id, and a logger. Your implementation should look up the appropriate credentials for that specific workspace (e.g., from a database) and return an instance of AuthorizeResult.
Using a custom authorize function allows you to dynamically provide the correct credentials for the workspace that sent the request, enabling features like say() to work correctly for each specific installation.
import os
from slack_bolt import App
from slack_bolt.authorization import AuthorizeResult
# Example installation data (in a real app, this would be in a database)
installations = [
{
"enterprise_id": "E1234A12AB",
"team_id": "T12345",
"bot_token": "xoxb-123abc",
"bot_id": "B1251",
"bot_user_id": "U12385"
}
]
def authorize(enterprise_id, team_id, logger):
for team in installations:
is_valid_enterprise = "enterprise_id" not in team or enterprise_id == team["enterprise_id"]
if is_valid_enterprise and team["team_id"] == team_id:
return AuthorizeResult(
enterprise_id=enterprise_id,
team_id=team_id,
bot_token=team["bot_token"],
bot_id=team["bot_id"],
bot_user_id=team["bot_user_id"]
)
logger.error("No authorization information was found")
app = App(
signing_secret=os.environ["SLACK_SIGNING_SECRET"],
authorize=authorize
)