들어가며
조직에서 개발 직군, 비개발 직군을 막론하고 공통적으로 자주 사용하는 것이 무엇일까요?
바로 “슬랙”과 같은 협업 도구입니다.
슬랙을 사용해 본 사람이라면 여러 종류의 슬랙봇을 이용해본 경험이 있을 것입니다.
슬랙봇은 다른 많은 도구들과 손쉽게 연결하여 반복적인 업무를 효율적으로 자동화할 수 있게 해줍니다.
기존에 하던 업무 중에는 반드시 사람의 손을 거쳐야 하는 인증 작업이 있었습니다.
신청 내용을 확인하고 DB에서 유저를 조회한 후 검수하고 다시 DB에서 유저 정보를 변경하는 간단한 작업이지만 여러 문제점들이 있었습니다.
1.
정확성 및 일관성을 보장해야함
2.
DB에 접근 권한이 없는 사람은 처리할 수 없음
3.
언제 어디서든 처리하기 어려움
이러한 문제점을 해결하고자 슬랙봇을 만들기로 하였습니다.
아키텍처
슬랙봇의 요청을 처리 해줄 서버로 Lambda를 선택하였습니다.
그 이유는 서버가 항상 실행되어 있을 필요가 없고 복잡한 처리가 필요한게 아니기 때문입니다.
또한 Lambda를 실행시켜 줄 트리거는 Slack API의 요청을 받는 API Gateway를 사용했습니다.
SlackBot 만들기
Slack App 생성
Slack 봇을 통해 Slack API를 사용하기 위해선 먼저 Slack App을 생성해야합니다.
Create New App - From scratch를 누른 후 원하는 이름과 추가할 워크스페이스를 선택하면 Slack App을 생성할 수 있습니다.
Permission 설정
OAuth & Permissions의 Scopes를 통해 Slack App의 권한을 설정할 수 있습니다.
저는 slash command를 사용할 것이기 때문에 commands 라는 scope를 추가했습니다.
그 외 권한들에 대한 설명은 아래의 표와 같습니다.
OAuth Scope | Description |
app_mentions:read | 대화에서 @앱 멘션을 직접 언급하는 메세지 보기 |
channels:history | 챗봇이 추가된 공개 채널에서 메세지 및 기타 콘텐츠 보기 |
channels:read | 워크스페이스의 공개 채널에 대한 기본 정보 보기 |
chat:write | @앱 멘션을 이용한 메세지 보내기 |
commands | 사용할 수 있는 단축키 및 / 또는 슬래시 명령 추가 |
files:read | 챗봇이 추가된 채널 및 대화에서 공유된 파일 보기 |
files:write | 챗봇으로 파일 업로드, 편집, 삭제 |
groups:history | 챗봇이 추가된 비공개 채널의 메세지 및 기타 콘텐츠 보기 |
groups:read | 챗봇이 추가된 비공개 채널의 기본 정보를 확인 |
im:history | 챗봇이 추가된 다이렉트 메세지의 메세지 및 기타 콘텐츠 보기 |
im:read | 챗봇이 추가된 다이렉트 메세지에 대한 기본 정보를 확인 |
mpim:history | 챗봇이 추가된 그룹 다이렉트 메세지의 메세지 및 기타 콘텐츠 보기 |
mpim:read | 챗봇이 추가된 그룹 쪽지에 대한 기본 정보를 확인 |
users:read | 워크스페이스에 있는 사람 보기 |
이제 위쪽에 Install to Workspace를 통해 원하는 워크스페이스에 해당 App을 설치합니다.
Lambda 생성
원하는 함수 이름, 언어, CPU 아키텍처를 선택합니다.
아래의 고급 설정에서는 VPC 연결을 원한다면 추가로 선택해줍니다.
API Gateway 생성
생성한 Lambda에서 트리거 추가를 통해 API Gateway를 추가합니다.
보안을 위해 JWT 방식을 사용해도 되지만 설명이 길어질거 같아서 생략하도록 하겠습니다.
또한 CORS도 본인의 판단하에 적용해주시면 됩니다.
생성된 API Gateway에서 기본으로 생성된 경로를 수정해줍니다.
SlackBot이 처리하는 업무들을 엔드포인트별로 나누고 싶다면 그에 맞는 경로들을 추가해줍니다.
그게 아니라면 “/” 엔드포인트 하나만 두고 함수 내에서 명령어 혹은 URI 별로 분기처리를 할 수도 있습니다.
Slash Commands 와 Interactivity & Shortcuts 설정
좌측 탭의 Slash Commands에서 SlackBot을 통해 처리할 명령어들을 추가합니다.
Request URL은 앞서 생성했던 API Gateway의 엔드포인트를 입력해줍니다.
이 때 URI에 유의해서 입력해주세요.
명령어를 통해 보낸 슬랙 메세지에서 컴포넌트를 통한 상호작용을 하기 위해서 Interactivity를 설정합니다.
토글 버튼을 통해 On 을 한 뒤 Request URL에 API Gateway의 엔드포인트를 입력합니다.
이 때도 해당 요청을 받을 URI에 유의해서 입력해주세요.
코드 작성 및 메세지 꾸미기
코드 작성
Slack에서 해당 봇에게 “/명령어” 를 전송하게 되면 Slack은 command별로 지정된 엔드포인트로 POST 요청을 보냅니다.
token=gIkuvaNzQIHg97ATvDxqgjtO
&team_id=T0001
&team_domain=example
&enterprise_id=E0001
&enterprise_name=Globular%20Construct%20Inc
&channel_id=C2147483705
&channel_name=test
&user_id=U2147483697
&user_name=Steve
&command=/weather
&text=94070
&response_url=https://hooks.slack.com/commands/1234/5678
&trigger_id=13345224609.738474920.8088930838d88f008e0
&api_app_id=A123456
Plain Text
복사
POST 요청을 보낼 때 위와 같은 내용이 body에 담겨있습니다.
어떤 command를 사용했는지와 응답을 위한 임시 웹훅 url인 response_url 등을 확인할 수 있습니다.
body는 URL Encoding 이후 Base64 Encoding이 되어 있어 요청을 받았을 땐 반대순서로 Decoding을 해주어야 합니다.
Slack API의 요청에 응답할 때 신경써야 할 부분이 몇 가지 있습니다.
1.
우선 응답에 대한 타임아웃은 3초입니다.
3초라고 해서 무조건 3초안에 모든 처리를 끝내야 한다는 것은 아닙니다.
Slack API에 대한 요청을 확인 했다는 성공 응답만 보낸 후 response_url을 통해 후속적으로 메세지를 전송할 수 있습니다.
2.
Slack API의 요청에 대한 응답은 Slack Block Kit을 지원하지 않습니다.
Lambda의 handler 함수에서 최종적으로 나가는 응답은 body의 메세지를 plain text로 인식하여 줄바꿈조차 되지 않습니다.
Slack Block kit을 이용하면 줄바꿈, 마크다운, 버튼 등이 포함된 메세지를 보낼 수 있으며 이를 사용하기 위해선 response_url에다가 메세지를 POST 요청으로 보내야합니다.
그리고 난 뒤 handler 함수는 정상적으로 모든 요청을 마쳤다는 의미로 상태 코드 200의 응답을 보냅니다.
이 때, 응답의 body가 비어있거나 없다면 상태 코드가 200이더라도 Slack API는 이를 실패라고 판단합니다.
3.
Interaction의 응답은 노출되지 않습니다.
컴포넌트(버튼, 선택 매뉴, 데이트피커 등)를 통한 요청에 대한 응답은 메세지가 발송되지 않습니다.
위 사항들에 유의하며 Slack API Document를 참고해 업무 처리 프로세스에 맞게 코드를 작성합니다.
메세지 꾸미기
Slack 메세지는 Block 이라는 구조를 갖고 있습니다.
각 Block은 버튼 및 메뉴와 같은 대화형 구성 요소를 가지며 구성 객체로 빌드됩니다.
구성 객체엔 Block 내에서 텍스트, 옵션 또는 기타 대화형 기능을 정의합니다.
Block Kit UI 프레임워크는 이러한 블록들을 통해 레이아웃을 손쉽게 구축할 수 있도록 해줍니다.
Block Kit은 JSON 포맷으로 코드로도 손쉽게 만들 수 있습니다.
이 때 버튼 같은 블록의 block_id, action_id, value 들은 어떤 interaction이 일어났는지 구분할 수 있게 해줍니다.
결과물
이제 “/명령어”를 사용해서 인증 신청 목록을 유저 정보와 함께 조회할 수 있게 되었습니다.
신청한 닉네임으로 검색된 유저들 중 부합하는 유저를 선택하여 승인 혹은 반려를 할 수 있습니다.
승인 시 해당 유저는 인증 처리가 되고 반려 시 해당 유저에게 반려에 대한 이메일이 발송됩니다.