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.
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!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.
/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 - 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
}
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.