-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathindex.ts
More file actions
71 lines (63 loc) · 2.34 KB
/
index.ts
File metadata and controls
71 lines (63 loc) · 2.34 KB
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
import { Boom, forbidden } from '@hapi/boom';
import crypto from 'crypto';
import { Request, ResponseObject, ResponseToolkit, ServerRoute } from '@hapi/hapi';
import { Config } from '../../config';
import { reactionBuild } from '../../reactions/github';
import { RepositoryWebhookPayload } from '../../schemas/github/repository-webhook-payload';
import { gitHubWebhookHeaders } from '../../schemas/gitHubWebhookHeaders';
import { gitHubWebhookPayload } from '../../schemas/gitHubWebhookPayload';
import { StreamLabs } from '../../services/StreamLabs';
import { TwitchChat } from '../../services/TwitchChat';
export const routes = (config: Config): ServerRoute[] => [
{
method: 'POST',
path: '/github',
options: {
validate: {
headers: gitHubWebhookHeaders(),
payload: gitHubWebhookPayload(),
},
},
handler: async (request: Request, h: ResponseToolkit): Promise<ResponseObject | Boom> => {
const { payload, headers } = (request as unknown) as {
payload: RepositoryWebhookPayload;
headers: { 'x-github-event': string; 'x-hub-signature': string };
};
if (config.GITHUB_SECRET) {
if (!headers['x-hub-signature']) {
console.error("missing 'x-hub-signature' header");
return forbidden();
}
const hmac = crypto.createHmac('sha1', config.GITHUB_SECRET);
const digest = Buffer.from(
'sha1=' + hmac.update(JSON.stringify(payload)).digest('hex'),
'utf8',
);
const checksum = Buffer.from(headers['x-hub-signature'], 'utf8');
if (checksum.length !== digest.length || !crypto.timingSafeEqual(digest, checksum)) {
console.error('unable to verify request signature');
return forbidden();
}
}
const event = headers['x-github-event'];
const streamlabs = new StreamLabs({ token: config.STREAMLABS_TOKEN || '' }, request);
const twitchChat = new TwitchChat({
botName: config.TWITCH_BOT_NAME || '',
botToken: config.TWITCH_BOT_TOKEN || '',
channel: config.TWITCH_BOT_CHANNEL || '',
});
const reactions = reactionBuild({
twitchChat,
streamlabs,
}).filter((reaction) => reaction.canHandle({ event, payload, config }));
if (reactions.length === 0) {
return h.response({
message: `Ignoring event: '${event}'`,
});
}
return h.response({
messages: await Promise.all(reactions.map((reaction) => reaction.handle({ payload }))),
});
},
},
];