Bolt for JavaScript

repository·main·Indexed 25 days ago

https://github.com/slackapi/bolt-js

A framework for building Slack apps quickly using the latest Slack platform features, including Block Kit, Events API, and Socket Mode. The @slack/bolt package (version 5.0.0) provides tools for implementing custom receivers for 3rd party web frameworks, deploying to AWS Lambda and Heroku, and managing OAuth flows and Message Metadata events.

Tokens
99.1K
Snippets
231
Records
378
Agent score
81%

What's inside bolt-js

  1. Configure environment variables for OAuth

    main

    The OAuth Express Receiver example requires several environment variables. You can retrieve most of these from your Slack app configuration. SLACK_STATE_SECRET is a custom secret of your choosing used for state validation.

    export SLACK_CLIENT_ID=YOUR_SLACK_CLIENT_ID
    export SLACK_CLIENT_SECRET=YOUR_SLACK_CLIENT_SECRET
    export SLACK_SIGNING_SECRET=YOUR_SLACK_SIGNING_SECRET
    export SLACK_STATE_SECRET=YOUR_SLACK_STATE_SECRET
  2. Enable automatic token rotation with built-in OAuth

    main

    As of v3.5.0, Bolt for JavaScript supports token rotation following the OAuth V2 RFC. When enabled, access tokens expire and are replaced by new ones using a long-lived refresh token.

    If you use the built-in OAuth functionality in Bolt, the framework will automatically rotate tokens in response to incoming events.

  3. Enable Interactivity for Buttons and Modals

    main

    To use interactive features like buttons, select menus, date pickers, or modals, you must enable interactivity in your Slack App settings.

    For Socket Mode

    Interactivity is enabled by default. No additional configuration is required in the Slack App dashboard.

    For HTTP Mode

    1. Navigate to your app's settings page in Slack.
    2. Click on Interactivity & Shortcuts in the left sidebar.
    3. In the Request URL box, enter the same URL you use for events (e.g., https://your-domain.com/slack/events).
    4. Click Save Changes.
  4. Call the Web API using the listener client

    main

    To call Slack Web API methods within a listener function, use the client object provided in the listener's arguments. This client is an instance of WebClient that is automatically configured with the appropriate token:

    1. The token specified during Bolt app initialization.
    2. Or, the token returned from the authorize function during an OAuth flow (handled automatically by Bolt's built-in OAuth support).

    Using this client ensures that the API call is made with the correct context for the specific request being handled.

  5. Add custom HTTP routes to the App

    main

    Since v3.7.0, you can add custom HTTP routes by passing a customRoutes array to the App constructor. Each object in the array must include:

    • path: The URL path for the route.
    • method: A string or an array of strings representing the HTTP methods (e.g., 'GET', ['POST', 'PUT']).
    • handler: A function to handle the request, receiving req and res objects.

    Starting from v3.13.0, the default HTTPReceiver and SocketModeReceiver support dynamic route parameters (e.g., /music/:genre), allowing you to access URL values via req.params.

    You can specify the port for these routes using installerOptions.port in the App constructor. The default port is 3000.

    const { App } = require('@slack/bolt');
    
    // Initialize the Bolt app with custom routes
    const app = new App({
      token: process.env.SLACK_BOT_TOKEN,
      signingSecret: process.env.SLACK_SIGNING_SECRET,
      customRoutes: [
        {
          path: '/health-check',
          method: ['GET'],
          handler: (req, res) => {
            res.writeHead(200);
            res.end(`Things are going just fine at ${req.headers.host}!`);
          },
        },
        {
          path: '/music/:genre',
          method: ['GET'],
          handler: (req, res) => {
            res.writeHead(200);
            res.end(`Oh? ${req.params.genre}? That slaps!`);
          },
        },
      ],
      installerOptions: {
        port: 3001,
      },
    });
    
    (async () => {
      await app.start();
      app.logger.info('⚡️ Bolt app started');
    })();
  6. Configure Bot Token Scopes and Install App

    main

    To allow your app to perform actions (like posting messages), you must configure OAuth scopes and install the app to your workspace.

    1. In App Settings, go to OAuth & Permissions.
    2. Under Bot Token Scopes, click Add an OAuth Scope.
    3. Add the chat:write scope to allow the app to post messages.
    4. Scroll to the top and click Install to Team.
    5. Authorize the installation in the Slack OAuth UI.
    6. Copy the generated Bot User OAuth Access Token (starts with xoxb).

    Security Note: Never check tokens into version control. Use environment variables instead.

    $ export SLACK_BOT_TOKEN=xoxb-<your-bot-token>
  7. Implement OAuth flow in Bolt for JavaScript

    main

    To distribute a Slack app, you must implement the OAuth flow. Bolt handles routing, state parameter validation, and passing installation information to your app.

    To enable OAuth, you must provide:

    • clientId, clientSecret, stateSecret, scopes (Required)
    • installationStore (Highly recommended for production to save and retrieve installation information)

    For development and testing, you can use FileInstallationStore from @slack/oauth, but it is not recommended for production. In production, you should implement a custom installationStore using a real database.

    const { App } = require('@slack/bolt');
    const { FileInstallationStore } = require('@slack/oauth');
    const app = new App({
      signingSecret: process.env.SLACK_SIGNING_SECRET,
      clientId: process.env.SLACK_CLIENT_ID,
      clientSecret: process.env.SLACK_CLIENT_SECRET,
      stateSecret: process.env.SLACK_STATE_SECRET,
      scopes: ['channels:history', 'chat:write', 'commands'],
      installationStore: new FileInstallationStore(),
    });
  8. Subscribe to message events in Slack

    main

    To receive messages, you must configure your app in the Slack app settings:

    1. Go to Event Subscriptions and ensure Enable Events is toggled on.
    2. Under Subscribe to Bot Events, select the relevant message events:
      • message.channels: Messages in public channels.
      • message.groups: Messages in private channels.
      • message.im: Direct messages with the app.
      • message.mpim: Messages in multi-person direct messages.
    3. Click Save Changes.
    4. Important: You must reinstall the app to your workspace to apply the new scopes.
  9. Add routes using ExpressReceiver.router

    main

    If you are using the built-in ExpressReceiver, you can add custom routes or middleware by accessing the router property. The receiver.router exposes the internal Express Router instance used by the App, allowing you to use standard Express methods like .use(), .get(), .post(), etc., to handle web requests outside of Slack's event system.

    const { App, ExpressReceiver } = require('@slack/bolt');
    
    // Explicitly create the Bolt Receiver
    const receiver = new ExpressReceiver({ signingSecret: process.env.SLACK_SIGNING_SECRET });
    
    // Create the App using this receiver
    const app = new App({
      token: process.env.SLACK_BOT_TOKEN,
      receiver
    });
    
    // Define Slack-specific logic using App methods
    app.event('message', async ({ event, client }) => {
      // Do some slack-specific stuff here
      await client.chat.postMessage(...);
    });
    
    // Use receiver.router to add middleware
    receiver.router.use((req, res, next) => {
      app.logger.info(`Request time: ${Date.now()}`);
      next();
    });
    
    // Use receiver.router to define other web request handlers
    receiver.router.post('/secret-page', (req, res) => {
      // Handle standard Express request and response
      res.send('yay!');
    });
    
    (async () => {
      await app.start();
      app.logger.info('⚡️ Bolt app started');
    })();
  10. Send simple messages with say()

    main

    Within a listener function (like app.message or app.event), you can use the say() utility to post a message to the conversation that triggered the listener. say() accepts a string for simple text messages.

    If you need to send a message outside of a listener or require advanced error handling, use the chat.postMessage method via the client attached to your Bolt instance.

    // Listens for messages containing "knock knock" and responds with an italicized "who's there?"
    app.message('knock knock', async ({ message, say }) => {
      await say(`_Who's there?_`);
    });