Node.js 로 slack-bot 을 만들어보았다

Eamon·2021년 8월 2일
21

회고

목록 보기
2/5
post-custom-banner

내게 개발을 공부하기 전에 개발자에 대한 어떤 로망 이 있었던 것은 사실이다.
그 무수한 로망 중 하나가 게으른 개발자 로망인데 설명하자면 이런 것이다.

"아~ 이거 계속 반복하기 귀찮은데 (거만한 표정으로) 귀찮은데 코딩으로 자동화 시켜볼까~"

대충 이런 로망이다. 물론 굉장히 과장한 로망이다.

사실 실상 만드는 건 이런 것들... 이라는 것을 깨닫게 되어버렸다.

이런 이야기로 글을 시작하게된 이유는 이번에만든 slack-bot의 이유가 '자동화' 에 있기 때문이다. 물론, slack-bot 을 어떻게 만드는 과정인지에 대한 설명도 하겠지만 자동화의 고민에 대해서 글을 적게 되었다.

🔍 slack-bot 왜 만들게 되었나?


위에서 말했던 것처럼 가장 큰 이유는 귀찮음 이였다. 매일 진행되는 TIL 스터디에서 아침마다 전날에 TIL(git에 pr 보내는 TIL)을 안쓴사람을 체크하는 채팅을 적는 일을 반복하게 되었다. 물론 당번을 정해서 돌아가면서 적는 방법도 있었으나, git-api 와 slack-api 를 이용하면 자동으로 전날 보내지 않은 사람들을 뽑아내서 봇이 출력해 낼 수 있을 것 같았다.

🔍 slack-bot 어떻게 만들까?


드디어 대망의 만드는 방법에 대한 이야기 ( 서론이 너무 길었다. ) 내가 진행했던 슬랙봇 생성(배포) 과정은 크게 3단계로 나눠진다.
  1. slack 봇 생성하고 권한 부여하기
  2. 봇의 SLACK_BOT_TOKENSigning Secret 키 찾기
  3. node js 에서 웹 서버(express 등)를 이용해서 post 요청 주고 받기
  • post 요청을 주고 받기 위해 웹서버 배포하기(헤로쿠나 AWS에)

❗주의❗ 최대한 정리를 해보려했지만 많은 삽질로 인해 글이 난해 할 수도 있습니다 죄송합니다.

1. slack 봇 생성하고 권한 부여하기


먼저 slack api 에서 app을 생성해 봇을 만든다.

[링크] https://api.slack.com/apps

앱 생성 버튼을 누른다.

앱의 기능을 Bots으로 선택한다.

Riview Scopes to Add 버튼을 눌러 앱 권한을 설정한다.

scopes 부분에 Add an OAuth Scope 버튼을 눌러 권한을 추가해준다.

내가 사용해야하는 api 는 chat.postMessage 이였다. 그것에 맞는 필요한 권한 설정은 여기 에서 확인할수 있었다.

2. 봇의 SLACK_BOT_TOKENSigning Secret 키 찾기

우선 SLACK_BOT_TOKEN 은 @slack/web-api 에서 토큰으로 필요하다.
token 을 얻기위해서는 권한을 설정하는 페이지인 OAuth & Permissions 에서 맨 위에 위치해있는 install to workspace 를 클릭하면된다.

권한을 변경할때마다 당연히 토큰을 refresh 해주어야하고 reinstall 해달라는 안내문구가 나온다.



Signing Secret 키는 @slack/events-api 에서 키로 필요하다.
Basic Information -> App Credentials -> Signing Secret 에서 봇마다 고유한 키를 가지고 있다.

3. node js 에서 웹 서버(express 등)를 이용해서 post 요청 주고 받기

  • post 요청을 주고 받기 위해 웹서버 배포하기(헤로쿠나 AWS에)

    이 부분이 내가 가장 많이 헤멧던 부분이다.
    우선 slack-api 는 workspace 에서 발생하는 event를 api 로 받아오려면 post 요청으로 유효한 서버의 요청인지 인증해주어야한다. (그렇기 때문에 먼저 헤로쿠나 AWS 에 배포를 해야 event 를 구독할수있다.

구독하는 거 말고 post 요청을 보내기만 하는 건 된다. 예를 들면 메세지 보내기 같은 것. (@slack/web-api) 나는 TIL 이라는 메세지를 입력하는 이벤트를 읽고 그것에 따라서 메세지를 보내려 했기 때문에 필요했다.

인증방법은 요청 받을 url(host,port,path) 을 입력하고 그 url 로 challenge parameter를 가진 request 보낸다. 그러면 우리의 서버는 그 challenge parameter를 그대로 response 로 보내주기만 하면된다.

위의 방법을 express의 post 로 그대로 구현할수도 있지만 npm install @slack/events-api 을 하였다면 requestListener 메소드를 이용하자!

자세한 설명은 친절하게 slack 공식 홈페이지에서 해주고있다.
[링크] https://slack.dev/node-slack-sdk/events-api


우선 서버를 돌려줄 프로젝트를 하나 만들자.


$ npm init // package.json 생성 후 필요한 모듈 설치
$ npm install --save express // 서버구동을 위해 express 설치
$ npm install --save @slack/events-api // event 구독을 위한 라이브러리
$ npm install --save @slack/web-api // bot event 생성을 위한 라이브러리

아 깜빡하고 먼저 안쓴게 있는데 nodejs 에서 slack-api 와 쉽게 연결하기위한 라이브러리인 @slack/events-api , @slack/web-api 를 이용하자

const { createEventAdapter } = require('@slack/events-api');
const { createServer } = require('http');
const { WebClient } = require('@slack/web-api');
const express = require('express');
const app = express();
const port = process.env.PORT || 3000;


const slackEvents = createEventAdapter(process.env.SLACK_SECRET);
const web = new WebClient(process.env.SLACK_BOT_TOKEN);

필요한 변수들을 선언한다.


slackEvents.on('message', async (event) => {
 // event hanle
  const result = await web.chat.postMessage({
   text: 'text',
   channel: 'channel',
  });

  console.log(
   `Successfully send message ${result.ts} in conversation ${event.channel}`
  );
 }
});

slackEvents.on('error', console.error);

app.use('/slack/events', slackEvents.requestListener());
// url 유효성 검사를 위한 requestListener
app.use(express.json());
// POST request data 를 parsing 하는 bodyparser
const server = createServer(app);
server.listen(port, (req, res) => {
 // Log a message when the server is ready
 console.log(`Listening for events on ${server.address().port}`);
});

slackEvents 에 event 를 등록하고 이벤트에 따른 bot 의 동작을 설정합니다.

이후에...


이후에는 aws의 EC2 가상머신에 이 서버를 배포하는 것을 해보았는데 이 부분은 나중에 따로 다룰 것이다.

결과물


아직은 아쉽게도 실용적으로 쓰이지는 않고있다. (현재 slack workspace 의 봇의 갯수가 9개 여서 ... 무료버젼에서는 10개 이상 등록하지 못한다. )

그래도 무엇인가 불편함을 느꼈을때 그것을 개선할 방법을 찾고 그 해결책을 위해서 노력했다는 사실이 뿌듯했다. (결과물도 생각보다 괜찮았다!)

profile
Steadily , Daily, Academically, Socially semi-nerd Front Engineer.
post-custom-banner

2개의 댓글

comment-user-thumbnail
2021년 8월 2일

대박 멋져요!!!!!!!!!!
근데 다음엔 케찹 뿌려주는 기계 만들어주세요

답글 달기

이몬~~스킬이 하나 더 늘었네요 멋집니다 ㅎㅎㅎ

답글 달기