Skip to content

Commit

Permalink
Piping slack requests to another port works!
Browse files Browse the repository at this point in the history
  • Loading branch information
renatodellosso committed Aug 1, 2024
1 parent 3afa20e commit fd94669
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 33 deletions.
2 changes: 2 additions & 0 deletions enviroment.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ declare global {
SLACK_CLIENT_SECRET: string;
SLACK_APP_TOKEN: string;
SLACK_SIGNING_SECRET: string;
SLACK_STATE_SECRET: string;
SLACK_PORT: string;

NODE_ENV: "development" | "production";
}
Expand Down
60 changes: 27 additions & 33 deletions index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { join } from "path";
import { SlashCommand, AckFn, RespondArguments, RespondFn } from '@slack/bolt';
import { SlashCommand, AckFn, RespondArguments, RespondFn, SocketModeReceiver } from '@slack/bolt';
import { createServer } from "https";
import { parse } from "url";
import next from "next";
import fs from "fs";
import { App } from "@slack/bolt";
import SlackCommands from "./lib/SlackCommands";
import { IncomingMessage, ServerResponse } from "http";
import { IncomingMessage, request, ServerResponse } from "http";
import { WebClientEvent } from "@slack/web-api";
import { startSlackApp } from "./lib/Slack";
import { StringIndexed } from "@slack/bolt/dist/types/helpers";

console.log("Starting server...");

Expand All @@ -29,6 +31,8 @@ const httpsOptions = {

console.log("HTTPS options set");

startSlackApp();

app.prepare().then(() => {
console.log("App prepared. Creating server...");

Expand All @@ -43,6 +47,26 @@ app.prepare().then(() => {
if (pathname && (pathname === '/sw.js' || /^\/(workbox|worker|fallback)-\w+\.js$/.test(pathname))) {
const filePath = join(__dirname, '.next', pathname);
(app as any).serveStatic(req, res, filePath);
} else if (pathname && pathname.startsWith("/slack")) {
console.log("Slack event received: " + parsedUrl.pathname);

// Pipe request to slack app
const newReq = request(
Object.assign(
{},
parse("http://localhost:" + process.env.SLACK_PORT + req.url),
{
method: req.method,
path: req.url,
}
),
(newRes) => {
res.writeHead(newRes.statusCode || 200, newRes.headers);
newRes.pipe(res);
}
);

req.pipe(newReq);
} else {
handle(req, res, parsedUrl);
}
Expand All @@ -64,34 +88,4 @@ app.prepare().then(() => {
}
});

console.log("App preparing...");

// Slack bot

const slackApp = new App({
token: process.env.SLACK_BOT_TOKEN,
signingSecret: process.env.SLACK_SIGNING_SECRET,
socketMode: true,
appToken: process.env.SLACK_APP_TOKEN,
});

slackApp.command(/\/.*/, async (props: { command: SlashCommand, ack: AckFn<string | RespondArguments>, respond: RespondFn }) => {
const { command, ack, respond } = props;

const commandName = command.command.replace("/", "");
const handler = SlackCommands[commandName];

if (handler) {
handler(command, ack, respond);
}
else {
await ack();
await respond(`Command not found: ` + commandName);
}
});

async function startSlackApp() {
await slackApp.start(port);
console.log("Slack bot is running!");
}
startSlackApp();
console.log("App preparing...");
1 change: 1 addition & 0 deletions lib/MongoDB.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export enum Collections {
Pitreports = "Pitreports",
Picklists = "Picklists",
SubjectiveReports = "SubjectiveReports",
SlackInstallations = "SlackInstallations",
}

export async function getDatabase(): Promise<MongoDBInterface> {
Expand Down
69 changes: 69 additions & 0 deletions lib/Slack.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { SlashCommand, AckFn, RespondArguments, RespondFn, App, Installation } from "@slack/bolt";
import SlackCommands from "./SlackCommands";
import { Collections, getDatabase } from "./MongoDB";

const slackApp = new App({
// token: process.env.SLACK_BOT_TOKEN,
signingSecret: process.env.SLACK_SIGNING_SECRET,
socketMode: true,
port: +process.env.SLACK_PORT,
redirectUri: "https://localhost/slack/oauth_redirect",
installerOptions: {
redirectUriPath: "/slack/oauth_redirect",
},
appToken: process.env.SLACK_APP_TOKEN,
clientId: process.env.NEXT_PUBLIC_SLACK_CLIENT_ID,
clientSecret: process.env.SLACK_CLIENT_SECRET,
stateSecret: process.env.SLACK_STATE_SECRET,
scopes: ["chat:write", "commands"],
installationStore: {
storeInstallation: async (installation) => {
console.log("Storing installation", installation.team?.name);

const db = await getDatabase();

db.addObject(Collections.SlackInstallations, installation);
},
fetchInstallation: async (InstallQuery) => {
const db = await getDatabase();

console.log("Fetching installation: " + InstallQuery.teamId);
const installation = await db.findObject<Installation>(Collections.SlackInstallations, {
userId: InstallQuery.userId,
team: {
id: InstallQuery.teamId,
}
});

console.log("Found installation", installation.team?.name);

if (!installation) {
throw new Error("No installation found");
}

return installation;
},
},
});

slackApp.command(/\/.*/, async (props: { command: SlashCommand, ack: AckFn<string | RespondArguments>, respond: RespondFn }) => {
const { command, ack, respond } = props;

const commandName = command.command.replace("/", "");
const handler = SlackCommands[commandName];

if (handler) {
handler(command, ack, respond);
}
else {
await ack();
await respond(`Command not found: ` + commandName);
}
});

export async function startSlackApp() {
await slackApp.start(process.env.SLACK_PORT);
console.log("Slack bot is listening at: http://localhost:" + process.env.SLACK_PORT);

return slackApp;
}
17 changes: 17 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"@next-auth/mongodb-adapter": "^1.1.3",
"@slack/bolt": "^3.19.0",
"@slack/web-api": "^7.0.2",
"@types/http-proxy": "^1.17.14",
"@types/react-dom": "18.0.11",
"@types/socket.io-client": "^3.0.0",
"bootstrap": "^5.3.2",
Expand Down

0 comments on commit fd94669

Please sign in to comment.