aws Amplify는 이메일 알림을 기본적으로 지원합니다.
사이드바의 알림 항목에 들어가면 이메일을 추가하고, 해당 메일로 알림을 받을 수 있습니다.
다만 매번 이메일을 확인해야하는 번거로움이 발생합니다.
작업 효율성 향상을 위해, slack에서 웹훅을 추가하여 알림을 받고, 람다 함수를 이용해 메세지를 커스텀 해보겠습니다.
추가 버튼을 누르면 아래와 같은 페이지가 뜹니다.
각 항목을 작성 후, 웹훅 url을 복사합니다.
*Node.js16 런타임 환경으로 설정 시 aws sdk2가 사용되는데 sdk2는 cjs을 지원하여 해당 문법을 사용할 수 있습니다. Node.js18환경 설정 시 aws sdk3이 사용되어 esm 문법으로 함수를 작성한다는 점 유의하세요!
함수가 생성되었습니다.
람다 함수
1const webhookUrl = "Slack Webhook url";
2
3const https = require("https");
4
5const postRequest = (data) => {
6 return new Promise((resolve, reject) => {
7 const url = new URL(webhookUrl);
8 const options = {
9 host: url.hostname,
10 path: url.pathname,
11 method: 'POST',
12 headers: {
13 'Content-Type': 'applicationjson',
14 },
15 };
16
17 const req = https.request(options, (res) => {
18 resolve(JSON.stringify(res.statusCode));
19 });
20
21 req.on('error', (e) => {
22 reject(e.message);
23 });
24
25 req.write(JSON.stringify(data));
26
27 req.end();
28 })
29}
30
31exports.handler = async (event) => {
32 const message = event.Records[0].Sns.Message.slice(1, -1);
33
34 const buildStatus = message.includes('STARTED')
35 ? 'STARTED'
36 : message.includes('FAILED')
37 ? 'FAILED'
38 : 'SUCCEED';
39
40 const urlRegex = /https:\/\/[^\s]+/g;
41 const urlMatches = message.match(urlRegex);
42
43 const branchNameMatches = urlMatches[0].includes('master')
44 ? 'master'
45 : urlMatches[0].includes('dev')
46 ? 'dev'
47 : 'unknown branch';
48
49 const deployHistory = urlMatches[1].split('/').pop();
50
51 const title =
52 buildStatus === 'STARTED'
53 ? `${branchNameMatches} #${deployHistory} start build!\n`
54 : buildStatus === 'FAILED'
55 ? `${branchNameMatches} deploy failed!\n`
56 : `${branchNameMatches} #${deployHistory} deploy successed!\n`;
57
58 const utcTimestamp = new Date(event.Records[0].Sns.Timestamp);
59 const kstOffset = 9 * 60 * 60 * 1000;
60 const kstTime = new Date(utcTimestamp.getTime() + kstOffset);
61
62 const formatKST = (date) => {
63 const year = date.getFullYear();
64 const month = (date.getMonth() + 1).toString().padStart(2, '0');
65 const day = date.getDate().toString().padStart(2, '0');
66 const hours = date.getHours().toString().padStart(2, '0');
67 const minutes = date.getMinutes().toString().padStart(2, '0');
68 return `${year}-${month}-${day}T${hours}:${minutes}`;
69}
70 const slackMessage = {
71 attachments: [
72 {
73 title,
74 title_link:
75 buildStatus === 'SUCCEED'
76 ? branchNameMatches === 'master'
77 ? '운영 서버 url'
78 : branchNameMatches === 'dev'
79 ? '개발 서버 url'
80 : undefined
81 : undefined,
82 color:
83 buildStatus === 'STARTED'
84 ? 'info'
85 : buildStatus === 'FAILED'
86 ? 'danger'
87 : 'good',
88
89 fields: [
90 {
91 title: '브랜치',
92 value: branchNameMatches,
93 short: true,
94 },
95 {
96 title: '배포 현황',
97 value: urlMatches[1],
98 },
99 {
100 title: '배포 시각',
101 value: `${formatKST(kstTime)}`
102 },
103 ],
104 },
105 ],
106 };
107
108 await postRequest(slackMessage);
109};*함수 최상단의 webhookUrl은 Slack 웹훅 앱에서 복사한 url을 붙여넣습니다.
SNS 항목을 선택해 추가합니다.
SNS를 트리거로 추가하면, SNS Topic은 Amplify에 이메일 알림을 추가했을 때 자동 생성된 항목을 선택합니다.