Amplify 배포 알림봇 구현
시작하기
aws Amplify는 이메일 알림을 기본적으로 지원합니다.
사이드바의 알림 항목에 들어가면 이메일을 추가하고, 해당 메일로 알림을 받을 수 있습니다.

다만 매번 이메일을 확인해야하는 번거로움이 발생합니다.
작업 효율성 향상을 위해, slack에서 웹훅을 추가하여 알림을 받고, 람다 함수를 이용해 메세지를 커스텀 해보겠습니다.
1. 배포 알림을 받을 Slack 채널 생성
2. Slack 에 Incoming Webhook 앱 추가


추가 버튼을 누르면 아래와 같은 페이지가 뜹니다.
각 항목을 작성 후, 웹훅 url을 복사합니다.

3. aws Lambda 함수 생성


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


람다 함수
const webhookUrl = "Slack Webhook url"; const https = require("https"); const postRequest = (data) => { return new Promise((resolve, reject) => { const url = new URL(webhookUrl); const options = { host: url.hostname, path: url.pathname, method: 'POST', headers: { 'Content-Type': 'applicationjson', }, }; const req = https.request(options, (res) => { resolve(JSON.stringify(res.statusCode)); }); req.on('error', (e) => { reject(e.message); }); req.write(JSON.stringify(data)); req.end(); }) } exports.handler = async (event) => { const message = event.Records[0].Sns.Message.slice(1, -1); const buildStatus = message.includes('STARTED') ? 'STARTED' : message.includes('FAILED') ? 'FAILED' : 'SUCCEED'; const urlRegex = /https:\/\/[^\s]+/g; const urlMatches = message.match(urlRegex); const branchNameMatches = urlMatches[0].includes('master') ? 'master' : urlMatches[0].includes('dev') ? 'dev' : 'unknown branch'; const deployHistory = urlMatches[1].split('/').pop(); const title = buildStatus === 'STARTED' ? `${branchNameMatches} #${deployHistory} start build!\n` : buildStatus === 'FAILED' ? `${branchNameMatches} deploy failed!\n` : `${branchNameMatches} #${deployHistory} deploy successed!\n`; const utcTimestamp = new Date(event.Records[0].Sns.Timestamp); const kstOffset = 9 * 60 * 60 * 1000; const kstTime = new Date(utcTimestamp.getTime() + kstOffset); const formatKST = (date) => { const year = date.getFullYear(); const month = (date.getMonth() + 1).toString().padStart(2, '0'); const day = date.getDate().toString().padStart(2, '0'); const hours = date.getHours().toString().padStart(2, '0'); const minutes = date.getMinutes().toString().padStart(2, '0'); return `${year}-${month}-${day}T${hours}:${minutes}`; } const slackMessage = { attachments: [ { title, title_link: buildStatus === 'SUCCEED' ? branchNameMatches === 'master' ? '운영 서버 url' : branchNameMatches === 'dev' ? '개발 서버 url' : undefined : undefined, color: buildStatus === 'STARTED' ? 'info' : buildStatus === 'FAILED' ? 'danger' : 'good', fields: [ { title: '브랜치', value: branchNameMatches, short: true, }, { title: '배포 현황', value: urlMatches[1], }, { title: '배포 시각', value: `${formatKST(kstTime)}` }, ], }, ], }; await postRequest(slackMessage); };
*함수 최상단의 webhookUrl은 Slack 웹훅 앱에서 복사한 url을 붙여넣습니다.
4. 트리거 추가
SNS 항목을 선택해 추가합니다.

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


완료! 🙂
