TIPS

[TIPS] Bots를 이용한 슬랙봇 만들기

Gray Park 2020. 9. 5. 09:00
728x90
반응형

 

지난번에는 웹훅을 이용해서 슬랙봇을 만들어보았다.

그런데 기능이 제한적이라 아쉬움이 많이 남아서, 이번에는 언제든지 원하는 기능을 추가할 수 있는 슬랙봇을 만들어보았다.

서버에 관해 포스팅을 하기로 했는데, 제가 heroku를 떠나는 바람에 이 포스팅을 먼저 진행합니다

 

봇을 만들기 위해서는 토큰이 필요하다. 봇 토큰을 얻는 방법은 웹훅 때와 비슷하니, 웹훅에서 url 얻는 파트를 살짝 보고 오시길 추천한다. ( 첫 줄의 링크를 클릭하면 이동 )

 

지난번에는 검색바에 webhook을 검색했지만, 이번에는 bots를 검색한다. 그러면 4번째에 Bots라는 친구가 보이는데 이 녀석이 우리에게 슬랙에서 사용할 수 있는 토큰을 제공해준다.

몇 번의 클릭을 통해 토큰을 얻었다면, 이게 토큰이 맞는 지 확인이 필요하다. 만약 눈에 보이는 토큰이 'xoxb-'로 시작한다면 우리가 찾는 토큰이 맞다.

 

이제, 봇을 만들어야 한다. 깃허브에 레포지토리를 하나 생성하거나 혹은, 제 레포지토리 ( link ) 를 포크하세요. ( 이제부터는 안내를 위함이니 존대로 변경 ) 포크한 레포지토리를 로컬에 clone하고 해당 폴더 안에서 npm install을 실행합니다.


만약, 제 레포지토리를 사용하지 않는 경우에는 몇 가지 설치해야할 패키지가 있습니다.

  1. @slcak/rtm-api // @slack/client 패키지를 다운받으셔도 됩니다.
  2. slack-node
  3. node-schedule // 정해진 시간을 사용하기 위해 사용한 패키지입니다.

모든 패키지를 설치했다면, bot.js를 엽니다. 현재 해당 레포지토리의 bot.js 에 작성된 내용은, yejiseo라는 다른 폴더( 봇네임 강제공개 ) 로부터 정보를 전달받고 있습니다. 그래서 필요한 부분을 남기고 다 지워줍니다. 아래는 사용에 필요한 내용만 편집해서 담아두었습니다.

import RtmPkg from '@slack/rtm-api';
import schdulePkg from 'node-schedule';
import Slack from 'slack-node';

const token = process.env.SLACK_TOKEN || myToken; // myToken에 아까 받은 토큰을 삽입

const { RTMClient } = RtmPkg;
const { scheduleJob } = schdulePkg;
const slack = new Slack(token);

// send 함수는 원하는 내용을 원하는 채널로 전달합니다
// * 단 채널에는 해당 봇이 초대된 상태여야 합니다 *
const send = async (message, channel) => {
	slack.api(
		'chat.postMessage',
		{
			username: 'botName', // 슬랙에 표시될 봇이름
            text: message,
			channel, // 메시지가 전송될 채널
			icon_url: 'imageUrl', // 슬랙에 표시될 봇의 이미지
		},
		function (err, response) {
			// console.log(response); // 보낼 때마다 내용을 확인하고 싶은 경우 주석해제
		}
	);
};

let time = new Date();
send(`${time}`, '${channelId}'); // 채널 아이디를 확인하는 방법은 이 코드블럭 아래에 설명

// 평일 아침 8시 50분에 '좋은 아침'이라는 내용으로 특정 채널에 메시지를 보낸다
// 보내는 PC ( 서버 ) 의 시스템 시간이 적용됩니다
scheduleJob('00 50 08 * * 1-5', () => {
	send('좋은 아침', '${channelId}');
});

// Real Time Messages
const rtm = new RTMClient(token);
rtm.start();

// 이제부터 봇이 추가된 모든 채널의 메시지를 읽어들입니다.
// message 객체는 이 코드블럭 아래의 채널 아이디 확인 방법 아래에 설명
rtm.on('message', (message) => {
  if ( message.text.split(' ').includes('botName') ) {
    send(`안녕 ${message.user}, 나는 ${botName}이야`;
  }
}

 

RTM ( Real Time Manage API ) 

RTM api를 사용하면 봇이 추가된 모든 채널의 모든 메시지를 받아봅니다. 이 때, message 객체의 text 프로퍼티가 사람들의 메시지가 됩니다. 위의 예제에서는 누군가가 텍스트로 봇의 이름인 botName 을 입력했을 때 send함수를 실행시킵니다. 메시지 객체로 어떤 것들이 들어오는 지 안다면, 조금 더 자유롭게 편집할 수 있을 거 같아서 아래에 남겨둡니다.

message:  {
  client_msg_id: 'somethingsomething',
  suppress_notification: false,
  type: 'message',
  text: 'botName',
  user: 'userId',
  team: 'teamId',
  blocks: [ { type: 'rich_text', block_id: 'n/KKN', elements: [Array] } ],
  source_team: 'sourceTeam',
  user_team: 'userTeam',
  channel: 'channel',
  event_ts: '1599187715.047100',
  ts: '1599187715.047100'
}

몇 가지 숨겨야하는 내용때문에 변경하였습니다. send 함수 하단의 console.log(response)를 주석해제하면 확인할 수 있습니다.

 

단, RTM을 사용하면서 text로 구분하고자 할 때 주의사항이 있습니다.

특히, thread로 대화를 나누도록 권장하는 곳일수록 더 중요합니다.

 

쓰레드에 글을 작성하면 에러가 출력이 됩니다. 그리고, response에 출력되는 내용도 조금 다릅니다. 이 부분은 자율적으로 해결하시도록 별도로 남겨두진 않습니다. 대신 해결하셨다면, 다른 분들을 위해 이 글의 댓글에 남겨주시길 부탁드립니다. ( 제 방식은 이미 레포지토리에 공개되어 있습니다 )

728x90
반응형