튜터링의 슬랙에는 튜달봇 형제가 살고 있다. 튜달봇 형은 주로 일을 하고, 동생은 주로 형에게 일을 시킨다.
이 글에서는 튜달봇 형제가 태어난 이야기와 간단한 구현 방법에 대해서 이야기해 본다.
2017년 8월. 내가 튜터링에 입사 첫날 가장 인상 깊었던 것은 출입구 앞에 놓여있는 커다란 TV였다. 그 TV 화면에는 튜터링 서비스를 시작한 2016년 9월 1일부터 오늘까지의 가입자, 결제액, 수업수가 표시된 그래프가 있었다. 전 직원들에게 원 단위까지 매출액을 공개하고 있었고, 그 그래프는 이제 막 J커브가 시작되는 참이었다.
튜터링의 모든 구성원들이 노력한 결과인 매출정보를 전 직원 모두가 실시간으로 확인할 수 있다니, 정말 멋진 생각이지 않은가?
다만, 그것을 확인하려면 TV 앞으로 가야 했다.
이 회사에서, 나의 고생은 아래와 같은 생각을 하고 나서부터 시작되었다.
튜터링에서는 슬랙을 사용하고 있으니, 슬랙 채널에서 오늘의 매출을 바로 확인할 수 있으면 좋지 않을까?
그래서 생각한 시나리오는 아래와 같았다.
1. 슬랙에 채널을 하나 만든다.
2. 그 채널에서 누군가 "결제"라고 입력한다.
3. 오늘과 이번 달의 결제액이 "짠" 하고 나온다.
별것도 아닌데, 모두들 신기해했다. 그냥 원래 있던 대시보드용 API를 슬렉에 붙인 것뿐인데...
튜터링은 튜터와 학생을 매칭 해주는 서비스이기 때문에 튜터와 학생의 발란스가 중요한데 우선 중요한 것은 서비스에 접속해 있는 튜터의 수이다. 때문에 모두들 아침 점심 저녁으로 지금 로그인해서 대기 중이거나 수업 중인 튜터의 수를 궁금해했다. 이쯤에서 나는 멈추었어야 했다.
튜터의 활동 상태를 실시간으로 확인할 수 있게 하면 더 좋지 않을까??
그래서 또 생각한 시나리오는 아래와 같다.
1. 아까 만든 채널에서 "튜터"라고 입력한다.
2. 지금 이 순간 튜터의 대기 중/수업 중 상황이 "짠" 하고 나온다.
명령어 "튜터"는 특히 튜터 운영 파트에서 많이 사용하는데, 그중 손가락이 두꺼워 오타를 자주 입력하는 "벨라"를 위해서 "튜타, 큐커, 튜토, 튜커"로 입력해도 모두 동일한 튜터 상태를 알려준다.
마케팅 파트의 "폴"님의 동반자인 "(공기)정화"를 슬랙 채널에서 부르면 미세먼지 정보를 알려주는 명령어 "정화야"
애묘인들을 위한 명령어 "냥이"
본격 개그 봇 - "멤버 닉네임"
더 이상의 튜달봇 명령 추가 요청을 거부하는 명령어 "진진"
그 외에도 지라 이슈가 등록되면 알려주는 기능, 소스 배포가 완료되면 알려주는 기능 등 수많은 기능이 있지만 나머지는 재미가 없으므로 생략한다.
이 아래부터는 조금 기술적인 내용이 있으니, 개발자가 아닌 분이거나 개발을 완전 잘하시는 분은 여기까지만 보시면 되겠다.
슬랙에서는 외부와 통신하는 방법이 2가지가 있다. 슬랙의 채널에서 작성한 메시지가 외부의 URL로 전송되는 Outgoing WebHook과 외부에서 슬랙의 특정 채널로 메시지를 보내는 Incoming WebHook이다.
사실상 튜달봇은 챗봇이 아니라 웹 훅에 반응하는 API다. 이글의 첫 번째 이미지를 보시고 눈치챈 분이 계실지도 모르겠지만, 튜달봇은 Outgoing WebHook, 튜달봇 동생은 Incoming WebHook을 조금 재미있게 이름을 붙인 것이다.
슬랙 워크스페이스 관리 화면에서 아래 메뉴를 따라가면 Outgoing WebHook을 설정할 수 있다.
Browse Apps > Custom Integrations > Outgoing WebHooks > Edit configuration
위와 같이 설정하면, 설정한 채널에서 멤버가 입력한 내용이 모두 등록한 웹 훅 URL로 전송되고, 웹 훅 URL에서 응답한 메시지가 다시 채널에 표시된다.
슬랙과 통신하는 API를 만들기 위해서 서버에 apache, php, composer를 설치하고, Laravel 앱을 하나 만들었다. 슬랙 통신을 위한 패키지인 'botman/botman', 'botman/driver-slack'까지 설치하면 연동 준비가 끝난다.
$ composer create-project --prefer-dist laravel/laravel slackbot
$ cd slackbot
$ composer require botman/botman
$ composer require botman/driver-slack
Outgoing WebHook은 별다른 설정 없이, 아래 정도의 코드면 작동한다. 이미지에 있는 코드는 미리 설정된 슬랙 채널에서 "클로이"라는 문구가 입력되면 등록된 WebHook Url이 호출되고, WebHook Url에서는 Request에서 대기하고 있던 BotMan 인스턴스가 작동하면서 "클로이"문구에 대응하는 "빠나나우유 사주세욤~!"을 응답하게 된다. API의 Response를 슬랙이 채널에 포스팅하면 하나의 프로세스가 끝나게 된다.
이 원리를 응용해서, "튜터"라는 명령어를 수신하면 튜터링 앱에서 사용하는 "튜터 상태 API"를 호출한 후에 적절히 응답할 문자열을 만들어서 전송하는 것이다.
Incoming WebHook은 조금 더 복잡한데, 자세한 설명은 아래 링크를 참조 바라고 자세한 설명은 생략한다. (사실 저 분보다 더 자세하게 쓸 자신이 없습니다.)
https://zeddios.tistory.com/123
간단히 설명드리자면 Incoming WebHook을 생성 시 선택한 슬랙 채널의 전용 메시지 수신용 웹 훅 URL이 생성되고 그 URL의 파라미터로 메시지 정보를 json형태로 호출하면 채널에 메시지가 전송된다.
그렇기 때문에 위에서 만든 명령어를 호출하기 위한 용도로 튜달봇 동생(Incoming WebHook)이 특정 채널에 명령어를 입력하면, 튜달봇(Outgoing WebHook)이 응답하는 원리이다.
튜터링에서는 소스 배포 알람, 서버 부하 경고, 배치작업 완료 등 서비스 운영의 주요 알람 수신을 위해 Incoming WebHook을 활용한다.
끗.