Skip to main content

Authorization

Authorization is the process of deciding which Slack credentials (such as a bot token) should be available while processing a specific incoming request.

Custom apps installed on a single workspace can simply use the token option at the time of App initialization. However, when your app needs to handle several tokens, such as cases where it will be installed on multiple workspaces or needs access to more than one user token, the authorize option should be used instead. If you're using the built-in OAuth support authorization is handled by default, so you do not need to pass in an authorize option.

The authorize option can be set to a function that takes an event source as its input, and should return a Promise for an object containing the authorized credentials. The source contains information about who and where the request is coming from by using properties like teamId (always available), userId, conversationId, and enterpriseId.

The authorized credentials should also have a few specific properties: botToken, userToken, botId (required for an app to ignore messages from itself), and botUserId. You can also include any other properties you'd like to make available on the context object.

You should always provide either one or both of the botToken and userToken properties. At least one of them is necessary to make helpers like say() work. If they are both given, then botToken will take precedence.

const app = new App({ authorize: authorizeFn, signingSecret: process.env.SLACK_SIGNING_SECRET });

// NOTE: This is for demonstration purposes only.
// All sensitive data should be stored in a secure database
// Assuming this app only uses bot tokens, the following object represents a model for storing the credentials as the app is installed into multiple workspaces.

const installations = [
{
enterpriseId: 'E1234A12AB',
teamId: 'T12345',
botToken: 'xoxb-123abc',
botId: 'B1251',
botUserId: 'U12385',
},
{
teamId: 'T77712',
botToken: 'xoxb-102anc',
botId: 'B5910',
botUserId: 'U1239',
},
];

const authorizeFn = async ({ teamId, enterpriseId }) => {
// Fetch team info from database
for (const team of installations) {
// Check for matching teamId and enterpriseId in the installations array
if ((team.teamId === teamId) && (team.enterpriseId === enterpriseId)) {
// This is a match. Use these installation credentials.
return {
// You could also set userToken instead
botToken: team.botToken,
botId: team.botId,
botUserId: team.botUserId
};
}
}

throw new Error('No matching authorizations');
}