평일에 갑자기 찾아온 휴일 (광복절).. 지난 회고편 이후 달라진 마음가짐으로 블로깅을 하던 찰나 재밌는 생각이 들었다. 지금 ec2, rds 등을 어떻게 쓰는지 배워밨으니 써봐야 하지 않을까?
여기서 ec2와 nodejs 를 사용하는 간단한 토이프로젝트로 뭘 해볼수 있을까?
나는 지금 몇몇 크루원들과 함께 리액트 스터디를 진행중이다. 이 스터디에서의 Ground-Rule 은 주에 2회이상 리액트에 관한 자유주제를 잡고 블로깅등 학습증명을 하자는 것과 위반 2회시 다른 크루원에게 젤라또를 사주자는 것이다.
슬랙에 채널을 하나 만들어서 블로깅 링크를 올리고 깃허브 레포 에서 전체 스터디 진행상황을 정리하고 있다.
그러면 블로깅 작성을 촉구하는 알림과 일요일이 끝날때 Ground-Rule 을 누가 지키지 못했는지 체크해주는 슬랙봇을 만들어볼까? 라는 생각이 들었다.
그럼 만들어보자.
설계 및 작업기한
2023.08.15
아이디어는 간단하다.
현재 블로깅을 증명하기 위해 리액트 스터디 채널을 하나 만들었다.
매주 @channel n주차 리액트 학습
이라는 메시지에 댓글로 자신의 블로깅 링크를 건다.
Nodejs 기반으로 index.js 파일을 하나 만들고 거기서 스터디를 기록중인 슬랙의 채널 id와 슬랙봇의 토큰값을 넣어 그 주에 해당하는 메시지 (이번주는 3주차니 @channel 3주차 리액트 학습) 에 댓글로 진행상황을 체크하는 것이다.
월 ~ 일요일 23시 59분까지 블로깅을 작성해야 하니
슬랙봇
이 매주 토요일 오전 10시에 시간이 얼마 남지 않았으니 블로깅을 서둘러주세요!
라는 댓글을 달고슬랙봇
이 매주 일요일 오후 11시 59분에 해당 댓글에 달린 스레드 (댓글) 작성자 리스트를 읽어 카운트후 2회보다 적은 인원들은 @@@, @@@ 님 시간이 초과되었습니다.
라는 댓글을 달게 한다.무중단 배포를 위해 마틴 리더님
이 살짝 언급해주셨던 pm2
를 사용하자.
배포 자체는 NCP 보단 AWS 의 EC2 에 배포를 해보자.
좋다. 설계가 끝났으니 한번 만들어보자.
https://api.slack.com/apps 에서 앱 생성
Basic Information 에서 Add feature and functionality 의 Bots 선택
사실 슬랙봇은 슬랙봇이 동작할 수 있는 scope 범위를 설정해줘야 추가할 수 있다.
OAuth & Permissions - Scope
아래로 스크롤하면 Scope 를 설정하는 부분을 볼 수 있다.
위의 Scope 들을 추가해줬다.
이미지 출처 : 정우일 블로그 - Python 으로 Slack Bot 만들기
workspace 에 설치하자
그런데 설치할 봇 사용자가 없다는 창이 떠서 원인을 찾던중 App Home 에서 앱의 Display Name, Defualt Name 을 설정해야 해결할 수 있다는 글을 봤다.
App Home 에서 App Display Name 과 Default Name 을 설정했다.
오.. 그러고나니 워크스페이스에 설치할 수 있게 창이 떴다.
그러고 나니 index.js 에 넣어야 할 슬랙봇 토큰이 생성되었다.
그럼 이제 슬랙의 App 에서 스터디 알림봇을 찾아 react-study 채널에 추가해줬다.
이제 슬랙에서 처리할 것은 끝났다.
다음은 backend 에서의 index.js 코드를 짜야 한다.
@channel n주차 React 학습
이라는 메세지에만 댓글을 달아야 한다.Reference docs
Sample code
Tester
https://api.slack.com/ 에서 API 이름을 검색하면 해당 API 에 대한 Reference docs ( 어떤 parameter 를 사용하는지, 에러가 발생한다면 원인이 무엇인지 ), Sample code ( JavaScript 가 있다!! ), Tester ( 실제로 API 실행해보는데 슬랙봇 생성시 토큰 생성했던걸 저 위치에 넣으면 된다. )
https://api.slack.com/ 에서 conversations.list
, conversations.history
, chat.postMessage
, users.info
, conversations.replies
가 필요했다.
conversations.list
: 토큰과 type 에 private_channel
을 넣으면 slack 채널의 id 를 얻을 수 있다. (id 가 channel_id)conversations.history
: 특정 채널의 history 를 읽는다.
conversations.replies
: 특정 채널의 특정 스레드의 댓글들을 읽는다.
users.info
: 댓글 작성자의 슬랙 프로필 정보를 가져오는데 사용한다. 그렇지 않으면 슬랙에서의 유저 id 만 담겨 있어 누가 댓글을 달았는지 알기 어렵다.
chat.postMessage
: 특정 채널 특정 스레드에 정해진 텍스트로 댓글을 단다.
const schedule = require("node-schedule");
CommonJS 의 require 을 통해 node-schedule 미들웨어를 가져와 사용했다.
이 미들웨어를 통해
// 토요일 오전 10시에 리마인더
schedule.scheduleJob({ dayOfWeek: 6, hour: 10, minute: 0 }, () => {
monitorChannelAndAddReminders();
});
// 일요일 오후 11시 59분에 초과 메세지
schedule.scheduleJob({ dayOfWeek: 0, hour: 23, minute: 59 }, () => {
monitorChannelAndAddRemindersOver();
});
특정 요일 정해진 시간에 API 를 실행할 수 있도록 했다.
EC2 는 수업을 통해 어떻게 만들고 접속하는지를 배웠다.
배포는 로컬에서 index.js 를 실행하는 것과 같다. 이걸 EC2 인스턴스라는 다른 컴퓨터에서 index.js 를 실행하는게 배포라고 하는 것이다.
먼저 만들어뒀던 EC2 인스턴스를 가져다 썼다. 그리고 로컬에서 깃허브 프로젝트를 클론받아 사용하듯이
다음 링크를 통해 접속한 EC2 에서 git clone https://github.com/Stendalsynd/... 를 쳐서 프로젝트를 클론했다.
이후 변경사항이 발생할 때마다 ec2 내에서 git pull 을 받아주면 되는 것이다.
그런데 ec2 는 ubuntu 를 AMI 로 사용했고 아직 nodejs 와 npm 그리고 나머지 설치했던 express, node-schedule, @slack/web-api 가 없다. 각각을 npm 설치후 npm install ... 해줘도 되지만 package.json-lock 에 있는 의존성에 위배되지 않게 같은 버전의 미들웨어를 설치하고 싶다면 npm install ...
이 아닌 npm ci
로 충분하다.
npm ci
프로젝트에서 사용중인 미들웨어중 로컬에서 설치가 되어있지 않은게 있다면 프로젝트의 버전과 일치하게 미들웨어를 설치하라는 명령어이다.
npm install 을 해버리면 프로젝트에서 사용중인 미들웨어를 최신버전으로 설치해서 버전이 달라지게 될 수 있다.
AMI 로 ubuntu 를 선택했으니 apt 로 npm 을 설치해준다.
참고로 EC2 의 시간은 UTC 기준이다. (영국 그리니치 기준이니 한국 KST 시간보다 9시간 느리다.) 그래서 EC2의 시간을 KST 로 바꿔줬다. (실제 서비스에선 UTC 기준으로 두고 index.js 에서 이에 맞추는게 맞을 것 같다.)
슬랙봇이 특정 시간대에 리마인더 메세지로 댓글을 남겼고 댓글을 작성한 횟수에 따라 Ground-Rule 을 위반한 인원들을 언급하며 댓글을 작성했다.
바로 원하던 대로 EC2 서버 사용, pm2 를 활용한 무중단 배포, 조건부 알림 기능을 갖춘 슬랙봇의 활용이라는 목표를 이뤘다. 아주 간단하게 토이프로젝트를 해봤는데 하루안에 끝날 수 있어서 다행이다.
참고로 슬랙에서 @ 를 사람 이름 앞에 붙이면 해당 인원에게 알림이 가는데 텍스트 내용을 수정한다면 아직 블로깅을 다 작성하지 않은 인원들에게 자동으로 슬랙 알림이 울리도록 할 수 있다.
이제 슬랙봇을 자유롭게 사용할 수 있게 되었다. slack api 중 댓글 기능만 사용해봤던 것인데 여기에 button 을 추가해서 동적 API 실행을 한다던지 serverless 로 aws lambda 를 이용한 주기적인 반응을 설정한다던지 새로운 시도를 해보고 싶다. 이걸 좀 활용한다면 #점심밥 뭐먹지 채널을 만들고 첫 프로젝트때 2시에 뭐해
팀처럼 인근 맛집 리스트를 rds 에 넣어두고 랜덤으로 돌려서 2시에 슬랙 알림으로 오늘의 추천 맛집을 띄우도록 할 수도 있을 것 같다.
로컬 설치
npm install express node-schedule @slack/web-api dotenv
sudo npm install pm2 -g
환경변수
// 루트 디렉토리에 .env 파일 생성후 MEMBER=이름1|이름2|이름3
// .gitignore 에 .env 추가
// 환경변수를 사용하는 파일에서
require('dotenv').config()
process.env.MEMBER
EC2 설치
sudo apt update
sudo apt install nodejs
sudo apt install npm
git clone https://github.com/...
cd [프로젝트 루트]
npm ci
EC2 환경변수 설정
cd ~
vim .bash_profile
export MEMBER="이름1|이름2|이름3"
esc
:wq 입력후
source .bash_profile
EC2 서버시간 Asia/Seoul 로 변경
date // EC2 에서의 시간대 확인 명령어
sudo su - root // root 로그인
// 로컬 타임을 Asia/Seoul 로 변경
sudo rm /etc/localtime
sudo ln -s /usr/share/zoneinfo/Asia/Seoul /etc/localtime
무중단 배포
pm2 start index.js --watch --update-env// 무중단으로 특정 파일을 계속 실행
pm2 monit // 현재 실행중인 명령어를 확인
pm2 kill // 실행중인 pm2 명령어 중단
pm2 logs --err // 현재 실행중인 환경에서 오류가 발생하는지 확인가능
Github 레포 링크 를 통해 전체 코드를 확인할 수 있다.
docs
slack api
blog
dulcis-hortus - 설치할 봇을 갖고있지 않습니다 오류 해결
HelloMinchan - pm2
itaeiou - EC2 ubuntu 서버시간 변경