Reese-log
  • About
  • Blog

© 2025 Reese. All rights reserved.

2024년 3월 25일

Amplify 배포 알림봇 구현

#Etc

시작하기

aws Amplify는 이메일 알림을 기본적으로 지원합니다.

사이드바의 알림 항목에 들어가면 이메일을 추가하고, 해당 메일로 알림을 받을 수 있습니다.

다만 매번 이메일을 확인해야하는 번거로움이 발생합니다.

작업 효율성 향상을 위해, slack에서 웹훅을 추가하여 알림을 받고, 람다 함수를 이용해 메세지를 커스텀 해보겠습니다.

1. 배포 알림을 받을 Slack 채널 생성

2. Slack 에 Incoming Webhook 앱 추가

추가 버튼을 누르면 아래와 같은 페이지가 뜹니다.

각 항목을 작성 후, 웹훅 url을 복사합니다.

3. aws Lambda 함수 생성

*Node.js16 런타임 환경으로 설정 시 aws sdk2가 사용되는데 sdk2는 cjs을 지원하여 해당 문법을 사용할 수 있습니다. Node.js18환경 설정 시 aws sdk3이 사용되어 esm 문법으로 함수를 작성한다는 점 유의하세요!

함수가 생성되었습니다.

람다 함수

javascript
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을 붙여넣습니다.

4. 트리거 추가

SNS 항목을 선택해 추가합니다.

SNS를 트리거로 추가하면, SNS Topic은 Amplify에 이메일 알림을 추가했을 때 자동 생성된 항목을 선택합니다.

5. 람다 함수의 ARN을 복사해 Amplify의 이메일 항목에 추가

완료! 🙂