next.jsslackslack-apingrokbolt

"error - unhandledRejection: Error: listen EADDRINUSE: address already in use :::3000" when I use Slack Bolt for JavaScript with ngrok and Next.js


Background

We are developing a Slack Bot. This time we are using Bolt for JavaScript (Node.js) provided by Slack, React, Next.js, and ngrok. Here is what each of them does.

Problem to be solved.

I have already confirmed that if I type @xxxx in a certain workspace in Slack, the event is notified to https://xxxx.jp.ngrok.io/api/slack/events. However, in this API file

app.event("app_mention", async ({ event, say }) => {
  .
  .
  .
}

is not invoked and the following error occurs

error - unhandledRejection: Error: listen EADDRINUSE: address already in use :::3000

I would like to know why and how to resolve this.

Source code

/api/slack/events.ts

import type { NextApiRequest, NextApiResponse } from "next";
require("dotenv").config();
import app from "../../../config/slackAuth";

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  // Unique case for Slack challenge
  if (req.body.challenge) return res.status(200).json(req.body);

  // Subscribe to 'app_mention' event in your App config
  // See https://api.slack.com/tutorials/tracks/responding-to-app-mentions
  app.event("app_mention", async ({ event, say }) => {
    try {
      // Response to the message in the thread where the event was triggered with @${message.user} 
      // See https://slack.dev/bolt-js/concepts#message-sending
      await say({
        text: `Hi <@${event.user}>!`,
        thread_ts: event.ts,
      });
    } catch (error) {
      await say({
        text: `<@${event.user}> ${error.message}.`, // @userName Request failed with status code 429.
        thread_ts: event.ts,
      });
    }
  });

  (async () => {
    // Start this app
    await app.start(process.env.PORT || 3000);
    console.log("⚡️ Bolt app is running!");
  })();

  return res.status(404).json({ message: "Unknown event type" });
}

Error code

error - unhandledRejection: Error: listen EADDRINUSE: address already in use :::3000
    at Server.setupListenHandle [as _listen2] (net.js:1331:16)
    at listenInCluster (net.js:1379:12)
    at Server.listen (net.js:1465:7)
    at C:\Users\81906\Documents\slackGpt3\node_modules\@slack\bolt\dist\receivers\HTTPReceiver.js:176:25    
    at new Promise (<anonymous>)
    at HTTPReceiver.start (C:\Users\81906\Documents\slackGpt3\node_modules\@slack\bolt\dist\receivers\HTTPReceiver.js:142:16)
    at App.start (C:\Users\81906\Documents\slackGpt3\node_modules\@slack\bolt\dist\App.js:241:30)
    at eval (webpack-internal:///(api)/./pages/api/slack/events.ts:69:69)
    at handler (webpack-internal:///(api)/./pages/api/slack/events.ts:71:7)
    at Object.apiResolver (C:\Users\81906\Documents\slackGpt3\node_modules\next\dist\server\api-utils\node.js:363:15) {
  code: 'EADDRINUSE',
  errno: -4091,
  syscall: 'listen',
  address: '::',
  port: 3000
}

Solution

  • Issue

    Using Slack Bolt for JavaScript with Next.js is not straightforward due to the following reasons:

    This information was provided by someone at Slack, and the source can be found at https://github.com/slackapi/bolt-js/issues/1687.

    Solution