Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add http handler example #7

Merged
merged 3 commits into from
Jul 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
SLACK_SIGNING_SECRET=<your-signing-secret>
SLACK_BOT_TOKEN=xoxb-<your-bot-token>
PORT=3000
WEBHOOK_TOKEN=123456789
PORT=3000
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ Follow these steps to set up this bot on your Slack
send chat messages:

- Go to _OAuth and Permissions_ in the left menu
- Add scope `users:read` and `chat:write`
- Required scopes `commands`, `users:read` and `chat:write`.
- Consider scopes `app_mentions:read`, `im:read`, `im:write`, `mpim:read`, `mpim:write`, `chat:write.public`, `links:write`, `incoming-webhook` (simplifies life and allows you to do basic interaction/conversation)

For our bot to be able to respond to interactive messages, we must enable
interactivity:
Expand All @@ -49,7 +50,14 @@ Follow these steps to set up this bot on your Slack
variables on the server we set up in step 1:

- `SLACK_SIGNING_SECRET`: Found in _Basic Information_ -> _Signing Secret_
- `SLACK_BOT_TOKEN`: Found in _Oath and Permissions_ -> _Bot User OAuth Access Token_
- `SLACK_BOT_TOKEN`: Found in _Oauth and Permissions_ -> _Bot User OAuth Access Token_

For our HTTP webhook receiver, we also want to set the following
environment variables:

- `WEBHOOK_TOKEN`: Any string that will work as a token for calling our endpoint.
- `SLACK_WEBHOOK_CHANNEL`: The channel (or user) to receive data from webhooks,
e.g. `#random` or `@myhandle`.

## Develop

Expand Down
12 changes: 11 additions & 1 deletion app.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,24 @@
"description": "A starter for making a Slack bot",
"env": {
"SLACK_BOT_TOKEN": {
"description": "Found in Slack/New App/Oath and Permissions. Can be set later",
"description": "Found in Slack/New App/Oauth and Permissions. Can be set later",
"value": "",
"required": false
},
"SLACK_SIGNING_SECRET": {
"description": "Found in Slack/New App/Basic Information. Can be set later",
"value": "",
"required": false
},
"SLACK_WEBHOOK_CHANNEL": {
"description": "Channel to report incoming webhook data to. Can be set later.",
"value": "#random",
"required": false
},
"WEBHOOK_TOKEN": {
"description": "A random secret token you create, for other services to communicate to Slack via your bot. Can be set later.",
"value": "a-secret",
"required": false
}
},
"repository": "https://github.com/tomfa/slack-app-starter",
Expand Down
4 changes: 4 additions & 0 deletions src/app.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import { Receiver } from "@slack/bolt";

require("dotenv").config();

import { ChatBot } from "./types";

export const createApp = (config: {
slackBotToken: string;
slackSigningSecret: string;
receiver: Receiver | undefined;
}): ChatBot =>
new ChatBot({
token: config.slackBotToken,
signingSecret: config.slackSigningSecret,
receiver: config.receiver,
});
27 changes: 27 additions & 0 deletions src/http.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { ChatBot } from "./types";

import { ExpressReceiver } from "@slack/bolt";

export const createHandler = (props: { signingSecret: string }) =>
new ExpressReceiver(props);

export const addHttpHandlers = (args: {
app: ChatBot;
receiver: ExpressReceiver;
allowedTokens: string[];
dmChannel: string;
}) => {
args.receiver.router.get("/secret-page", (req, res) => {
const token = req.query.token as string;
const hasAccess = token && args.allowedTokens.includes(token);
if (!hasAccess) {
console.log(`Attempted accessing http handler without valid token`);
return res.send("OK");
}
args.app.dm({
user: args.dmChannel,
text: "I suppose there will be a funny little PR tomorrow",
});
res.send(`I have informed our master of your arrival`);
});
};
21 changes: 16 additions & 5 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,28 @@
import { addEvents } from "./events";

require("dotenv").config();

import { addSlashCommands } from "./commands";
import { createApp } from "./app";
import { addEvents } from "./events";
import { addSlashCommands } from "./commands";
import { createHandler, addHttpHandlers } from "./http";

const receiver = createHandler({
signingSecret: process.env.SLACK_SIGNING_SECRET!,
});

const app = createApp({
slackBotToken: process.env.SLACK_BOT_TOKEN as string,
slackSigningSecret: process.env.SLACK_SIGNING_SECRET as string,
slackBotToken: process.env.SLACK_BOT_TOKEN!,
slackSigningSecret: process.env.SLACK_SIGNING_SECRET!,
receiver,
});

addSlashCommands(app);
addEvents(app);
addHttpHandlers({
app,
receiver,
allowedTokens: [process.env.WEBHOOK_TOKEN!],
dmChannel: process.env.SLACK_WEBHOOK_CHANNEL || "#random",
});

(async () => {
await app.start(process.env.PORT as string);
Expand Down