javascript2017.11.29 11:21

서버, 파이썬, node.js 없이 브라우저만으로 돌아가는, 

간단한 반응형 슬랙봇 만들기 (자바스크립트)

Simple reactive Slackbot in Javascript without Python, node.js, REACT and a server. 

All you need is a browser.



커뮤니티툴로 슬랙이 인기다. 외부 확장이 쉽도록 API와 BOT인터페이스들을 잘 제공하고 있는데, 카카오톡의 폐쇄성에 답답하던 사람들에게 해방구가 아닐까 싶다. 


간단히 슬랙으로 메세지를 보내려면 단순히 URL+파라미터 형태만으로도 가능하다. curl같은 프로그램으로 리눅스 쉘에서 바로 보낼 수도 있다. 


문제는 반응형인데 (슬랙 유저가 채널에 작성한 메세지에 반응하는 형태), 슬랙에서 이런 반응형 봇을 만들수 있게 제공해주는 기반은 RTM (RealTime Messaging) 혹은 Event 방식이다. 


구글링으로 찾아본, 이걸 구현한 라이브러리/샘플들은 대부분 파이썬, node.js 등으로 만들어져 있다. 파이썬에 익숙한 사람들은 좋겠지만 나처럼 극악으로 싫어하는 사람들은 다른 샘플이 필요했다. 


php로 된 샘플도 찾아내긴 했는데, RTM을 구현하려면 소켓연결라이브러리 REACT가 필요하고, 이것을 설치하려면 어쩌고 저쩌고....  아 이산이 아닌갑다. 하고 포기하게 된다. 


이쯤이면 직접 만들각이다.  

성격급한 사람들을 위한 소스 다운로드 : https://github.com/jadumate/jadubot



간단한 메세지전송  (Simple Posting)


반응형이 필요 없는 경우 - 예를 들면 매일아침 주가지수를 알려주는 봇 -는 굉장히 쉽게 구현이 가능하다.  슬랙API페이지에서 안내하듯이 curl 같은걸 써서 특별한 코딩없이 바로 가능한데, 일단 Js로 구현해 보았다. 



사전작업 (https://api.slack.com/)
1. App을 생성하고 셋팅. 'Incoming Webooks'를 활성화시켜준다. 

2. 채널별로 Webhook URL을 생성한다. 




이제 이 URL만 있으면 슬랙채널에 메세지를 날릴 수 있다.



function
sendWebhook(url, msg)

{

$.ajax({
data: 'payload=' + JSON.stringify({ "text": msg }),
dataType: 'json',
processData: false,
type: 'POST',
url: url
});
}


이런 형태로 사용한다. 

sendWebhook('https://hooks.slack.com/services/.....', 'Hello Slack');  




반응형 메세지 전송 (Reactive Messaging)


반응형이란, 슬랙채널 누군가가 보낸 메세지를 분석해서 그에 따라 반응하는 형태를 말한다. 예를 들면 '점심 메뉴를 골라줘' 라는 요청에 대해 답을 찾아주는 것.


사전작업

1. 슬랙 API페이지에서 BOT User를 생성한다. 

2. Bot User OAuth Access Token을 복사한다. 

3. 적당한 권한을 설정한다. 








이제 코딩


function onevent(event) {
var json = JSON.parse(event.data);
if( json.type == 'message'){
processMessage(json);
}
console.log('RAW: ' + event.data);
};
function openSocket(url) {
console.log('WS:url : ' + url);
window.ws = new WebSocket(url);
window.ws.onmessage = onevent;
window.ws.onopen = function() {
console.log('WS:opened');
};
}
function run(){
$.post(
'https://slack.com/api/rtm.start',
{ token : config.apiToken, type : 'hello' },
function(data){
if(data && data.ok) {
metadata = data;
openSocket(data.url);
}
}
);
return false;
}


브라우저의 웹소켓 (websocket)을 이용한다.  


1. https://slack.com/api/rtm.start 에 접속하여 metadata를 얻는다. 이 데이터안에 연결해야할 websocket 주소가 있다.

2. 웹소켓을 연결하고 이벤트핸들러를 설정한다. 

3. 핸들러 루틴을 작성한다. 




function processMessage(json)
{
if(! json.text) return;
if(json.bot_id !== undefined) return;
var userName = getUsername(json.user);
dump( userName + ' : ' + json.text + '\n');
if(json.text.indexOf('Hello') >= 0){
postMessage(json.channel, 'Hello ' + userName);
}
}


누군가 'Hello' 라고 입력하면, 그사람 이름붙여서 같이 인사해주는 코드다.

슬랙에 메세지를 보내는 방법은 여러가지가 있는데, 이상하게도 websocket으로 보내는 방식은 꾸미기가 불가능하게 되어 있다 (간단한 텍스트만 전송).   그래서 chat.postmessage라는 또다른 api를 사용해 보자.


function postMessageSimple(channel, msg)
{
var text = {
as_user: false,
username: config.botName,
channel : channel,
type : 'message',
text : msg
};
window.ws.send( JSON.stringify(text) );
}

function
postMessage(channel, msg)
{
var params = {
token : config.apiToken,
encoding: 'utf8',
channel : channel,
as_user: false,
username: config.botName,
text: msg
};
$.post(
'https://slack.com/api/chat.postMessage',
params,
function(status){
console.log(status);
}
);
console.log('#slack send : ' + msg);
}



스크립트는 완성. 이제 콘솔이 될 html 페이지를 대충 만들어 보자.



<body onload="return run();">
<form action='' methos='POST'>
<div style='width:100%;'>Jadubot V1.0 by jadumate@gmail.com</div>
<textarea id='dump' style='width:100%; height:80%;'>
</textarea>
</form>
</body>




function
dump(msg)
{
$("#dump").append(msg);
}




이렇게 해서 기본구현은 끝. processMessage에서 적당히 구문분석하고 다른 일들을 해주면 되겠다.


소스파일을 돌려보려면 두 파일을 다운받아 html파일을 브라우저에서 열면 된다. 미리 config.js 안에 자기의 슬랙에 맞는 webhookurl, apitoken값을 지정해주어야 한다.  실제 통신이 잘 이루어지는지 알고 싶으면 F12를 눌러 콘솔 덤프를 확인해 보자. 




Posted by Jadumate

티스토리 툴바