forked from fishbrain/codebuild-slack-notifier
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.ts
111 lines (96 loc) · 3.86 KB
/
index.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
import { WebClient } from '@slack/web-api';
import { Callback, Context, Handler } from 'aws-lambda';
import * as AWS from 'aws-sdk';
import { CodeBuildEvent, handleCodeBuildEvent } from './codebuild';
import { CodePipelineEvent, handleCodePipelineEvent } from './codepipeline';
import { Channel, ChannelsResult, Message } from './slack';
export const messageCache = new Map<string, Message>();
export const isCodePipelineEvent = (
event: CodeBuildEvent | CodePipelineEvent,
): event is CodePipelineEvent => {
return (
event['detail-type'] === 'CodePipeline Action Execution State Change' ||
event['detail-type'] === 'CodePipeline Pipeline Execution State Change' ||
event['detail-type'] === 'CodePipeline Stage Execution State Change'
);
};
const ssm = new AWS.SSM();
// Get project name out of the event
export const getProjectName = (event: CodeBuildEvent | CodePipelineEvent) => {
if (isCodePipelineEvent(event)) {
return event.detail.pipeline;
}
return event.detail['project-name'];
};
export const handler: Handler = async (
event: CodeBuildEvent | CodePipelineEvent,
_context: Context,
_callback: Callback | undefined,
) => {
try {
const indentLevel = 2;
// console.log('Received event:', JSON.stringify(event, null, indentLevel));
const projectName = getProjectName(event).split('-')[0];
// Get list of channels to notify
const notifyChannels = (await ssm
.getParameter({
Name: `/codebuild-slack-notifier/${projectName}_channels`,
WithDecryption: false,
})
.promise()).Parameter;
// console.log(`notifyChannels - /codebuild-slack-notifier/${projectName}_channels`);
// console.log(JSON.stringify(notifyChannels, null, indentLevel));
if (notifyChannels === undefined || notifyChannels.Value === undefined) {
throw new Error('Could not fetch notification channels');
}
const projectChannels = notifyChannels.Value.split(',');
// console.log('Slack channels');
// console.log(JSON.stringify(projectChannels, null, indentLevel));
// Connect to slack
const token = (await ssm
.getParameter({
Name: `/codebuild-slack-notifier/slack_token`,
WithDecryption: true,
})
.promise()).Parameter;
// console.log(`token - /codebuild-slack-notifier/slack_token`);
// console.log(JSON.stringify(token, null, indentLevel));
if (token === undefined || token.Value === undefined) {
throw new Error('Could not fetch slack token');
}
const slack = new WebClient(token.Value);
// console.log('messageCache before', messageCache);
// Get list of channels
const result = (await slack.channels.list()) as ChannelsResult;
const requests = result.channels.map(async (channel: Channel) => {
// console.log(`Trying channel -> ${channel.name}`);
if (projectChannels.find(c => c === channel.name)) {
if (isCodePipelineEvent(event)) {
console.log(`Processing CodePipeline event for channel -> ${channel.name}`);
return handleCodePipelineEvent(event, slack, channel);
}
console.log(`Processing CodeBuild event for channel -> ${channel.name}`);
return handleCodeBuildEvent(event, slack, channel);
}
});
// Promise.all(requests).then(r => {
// console.log(JSON.stringify(r.filter(i => i != null), null, indentLevel));
// Add all sent messages to the cache
/* r.forEach(m => {
if (m) {
messageCache.set([m.channel, buildId(event)].join(':'), {
...m.message,
ts: m.ts,
});
}
}); */
// console.log('messageCache after', messageCache);
// });
const responses = await Promise.all(requests);
console.log(JSON.stringify(responses.filter(r => r != null), null, indentLevel));
}
catch (err) {
console.log('An Error Occurred:', err.message);
console.log(err);
}
};