DEV Community

Vincent Voyer
Vincent Voyer

Posted on

5 3

How to verify signatures from Slack incoming requests with Next.js

Hi there, this is a short blog post for anyone looking to handle Slack incoming requests with Next.js.

When creating a Slack application that will interact with your web application, Slack will call you back on some actions like:

Here's an example Slack postMessage call:

import { WebClient } from "@slack/web-api";
const web = new WebClient(token);
web.postMessage({
  channel: "#general",
  // fallback for mobile and email notifications:
  text: "Please visit <https://google.com>",
  blocks: [{
    type: "section",
    text: {
      type: "mrkdwn",
      text: "Please visit https://google.com"
    }
  }, {
    type: "actions",
    elements: [{
      type: "button",
      text: {
        type: "plain_text",
        text: "google",
      },
      url: `https://google.com`,
      action_id: "go_to_google_button",
    }],
  }]
});
Enter fullscreen mode Exit fullscreen mode

If you do this, you'll get this result:

Screenshot of a Slack message with a button.

And if you click on the "google" button, it will open Google in your browser. Pretty cool way to link from Slack to your web app for example.

But, that's not the end of the story. If you only do this then Slack will complain because a button, even if it only open a new url, is still an interactive element from Slack point of view.

So Slack will try to call the URL defined in your application "Interactivity & Shortcuts" Slack settings.

And it will fail because you've not defined a route for that.

Now to solve that, if you're using Next.js, you have to define a route as follow:

// pages/api/slackInteractiveEndpoint.js

import { createMessageAdapter } from "@slack/interactive-messages";

// you can find this secret in your app "Basic information" tab
const slackInteractions = createMessageAdapter(slackSigningSecret); 

slackInteractions.action(
  { type: "button", actionId: "go_to_google_button" },
  // no need to reply, it's just a button to a url
  () => {},
);

export default slackInteractions.requestListener();

export const config = {
  api: {
    bodyParser: false,
    externalResolver: true,
  },
};
Enter fullscreen mode Exit fullscreen mode

Then add this route in your Slack application "Interactivity & Shortcuts" tab. Test one message, click on the button and .. voilà!

Because the Slack SDK is responsible for parsing the body and replying to the request, we tell Next.js to let it go via:

  • bodyParser: false
  • externalResolver: true

Hope this helped you! Post a comment otherwise :)

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more