This repository has been archived by the owner on Dec 5, 2022. It is now read-only.
/
app.ts
166 lines (150 loc) · 5.18 KB
/
app.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
'use strict';
// ------------------------------------------------------
// Type definitions in TypeScript
import * as WebApi from 'seratch-slack-types/web-api';
import { Request, Response, Application } from 'express';
// ------------------------------------------------------
// Bot app
// https://slack.dev/bolt/
import { App, ExpressReceiver } from '@slack/bolt';
const expressReceiver = new ExpressReceiver({
signingSecret: process.env.SLACK_SIGNING_SECRET
});
export const expressApp: Application = expressReceiver.app;
const app: App = new App({
token: process.env.SLACK_BOT_TOKEN,
receiver: expressReceiver
});
// ------------------------------------------------------
// If you need to use API methods that are not listed on https://api.slack.com/bot-users#methods
// you need to use user api token instead like this:
import { WebClient } from '@slack/web-api';
app.client = new WebClient(process.env.SLACK_API_TOKEN);
// ------------------------------------------------------
// React to "app_mention" events
app.event('app_mention', async ({ event, say }) => {
app.client.users.info({ user: event.user })
.then((res: WebApi.UsersInfoResponse) => {
if (res.ok) {
say({
text: `Hi! <@${res.user.name}>`
});
} else {
console.error(`Failed because of ${res.error}`)
}
}).catch(reason => {
console.error(`Failed because ${reason}`)
})
});
// React to message.channels event
app.message('hello', ({ message, say }) => {
// say() sends a message to the channel where the event was triggered
say({
"text": null,
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": `Hey there <@${message.user}>!`
},
"accessory": {
"type": "button",
"text": {
"type": "plain_text",
"text": "Click Me"
},
"action_id": "button_click"
}
}
]
});
});
// Handle the click event (action_id: button_click) on a message posted by the above hello handler
app.action('button_click', ({ body, ack, say }) => {
// Acknowledge the action
ack();
say(`<@${body.user.id}> clicked the button`);
});
// Handle `/echo` command invocations
app.command('/echo', ({ command, ack, say }) => {
// Acknowledge command request
ack();
say(`You said "${command.text}"`);
});
// A simple example to use WebApi client
app.message('42', ({ message }) => {
// use chat.postMessage over say method
app.client.chat.postMessage({
channel: message.channel,
text: 'The answer to life, the universe and everything',
thread_ts: message.ts
})
.then((res: WebApi.ChatPostMessageResponse) => {
if (res.ok) {
console.log(`Succeeded ${JSON.stringify(res.message)}`)
} else {
console.error(`Failed because of ${res.error}`)
}
}).catch(reason => {
console.error(`Failed because ${reason}`)
})
})
// A simple example to use Webhook internally
app.message('webhook', ({ message }) => {
const { IncomingWebhook } = require('@slack/webhook');
const url = process.env.SLACK_WEBHOOK_URL;
const webhook = new IncomingWebhook(url);
webhook.send({
text: message.text.split("webhook")[1],
unfurl_links: true
})
.then((res) => {
console.log(`Succeeded ${JSON.stringify(res)}`)
}).catch(reason => {
console.error(`Failed because ${reason}`)
})
})
// Check the details of the error to handle cases where you should retry sending a message or stop the app
app.error((error) => {
console.error(error);
});
// As long as you run this app as a "Serverless Framework" app, you don't need to have the following code
// (async () => {
// // Start your app
// await app.start(process.env.PORT || 3000);
// console.log('⚡️ Bolt app is running!');
// })();
// ------------------------------------------------------
// OAuth flow
expressApp.get('/slack/installation', (_req: Request, res: Response) => {
const clientId = process.env.SLACK_CLIENT_ID;
const scopesCsv = 'commands,users:read,users:read.email,team:read'; // TODO: modify
const state = 'randomly-generated-string'; // TODO: implement the logic
const url = `https://slack.com/oauth/authorize?client_id=${clientId}&scope=${scopesCsv}&state=${state}`;
res.redirect(url);
});
expressApp.get('/slack/oauth', (req: Request, res: Response) => {
// TODO: make sure if req.query.state is valid
app.client.oauth.access({
code: req.query.code,
client_id: process.env.SLACK_CLIENT_ID,
client_secret: process.env.SLACK_CLIENT_SECRET,
redirect_uri: process.env.SLACK_REDIRECT_URI
})
.then((apiRes: WebApi.OauthAccessResponse) => {
if (apiRes.ok) {
console.log(`Succeeded! ${JSON.stringify(apiRes)}`)
// TODO: show a complete webpage here
res.status(200).send(`Thanks!`);
} else {
console.error(`Failed because of ${apiRes.error}`)
// TODO: show a complete webpage here
res.status(500).send(`Something went wrong! error: ${apiRes.error}`);
}
}).catch(reason => {
console.error(`Failed because ${reason}`)
// TODO: show a complete webpage here
res.status(500).send(`Something went wrong! reason: ${reason}`);
});
});