Amplify 배포 알림봇 구현

date
Mar 25, 2024
slug
amplify-slack-bot
author
status
Public
tags
Etc
summary
type
Post
thumbnail
blue-1.jpg
category
updatedAt
May 27, 2024 01:12 PM

시작하기

aws Amplify는 이메일 알림을 기본적으로 지원합니다.
사이드바의 알림 항목에 들어가면 이메일을 추가하고, 해당 메일로 알림을 받을 수 있습니다.
notion image
다만 매번 이메일을 확인해야하는 번거로움이 발생합니다.
작업 효율성 향상을 위해, slack에서 웹훅을 추가하여 알림을 받고, 람다 함수를 이용해 메세지를 커스텀 해보겠습니다.
 

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

2. Slack 에 Incoming Webhook 앱 추가

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

3. aws Lambda 함수 생성

notion image
notion image
*Node.js16 런타임 환경으로 설정 시 aws sdk2가 사용되는데 sdk2는 cjs을 지원하여 해당 문법을 사용할 수 있습니다. Node.js18환경 설정 시 aws sdk3이 사용되어 esm 문법으로 함수를 작성한다는 점 유의하세요!
함수가 생성되었습니다.
notion image
notion image
 
람다 함수
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 항목을 선택해 추가합니다.
notion image
SNS를 트리거로 추가하면, SNS Topic은 Amplify에 이메일 알림을 추가했을 때 자동 생성된 항목을 선택합니다.

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

notion image
notion image

완료! 🙂

notion image