简体   繁体   中英

"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.

  • Bolt for JavaScript: I don't want to use Slack's bare-bones API, but want to benefit from the function that wraps it.
  • React: Needed to use Next.js
  • Next.js: Slack needs a request URL to notify my bot app when events such as mentions occur in Slack, but Next.js makes it easy to create an API endpoint to be set to that URL (eg /api/something)
  • ngrok: In the local development environment, that URL will be http://localhost:3000 , so the protocol will be http instead of https . Slack does not allow this, so we need a URL that starts with https that tunnels to the local http://localhost:3000 . ngrok provides that easily!

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
}

Issue

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

  • Running npm run dev in a Next.js project starts a server at localhost:3000.
  • Running app.start() in Slack Bolt for JavaScript starts a server using Express.js, which also tries to use localhost:3000.
  • This causes an error because two servers are trying to use the same port.

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

Solution

  • You can change the port number used by Bolt to, for example, 3001.
  • However, this will make it difficult for the two servers at localhost:3000 and 3001 to communicate with each other.
  • The request URL registered in the Slack Bolt for JavaScript console is set to 3000, so events received there will not be able to flow to port 3001.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM