티스토리 뷰
개인 기록 유지 차원에서 정리해봄
Slack은 협업하는 Task내에서 의사소통으로 많이 쓰이는 수단이다. 단순히 유저별 message만 주고 받을 수 있는게 아니라, file upload같은 것도 되고, 더 좋은 것은 Custom Application을 channel내에 설치함으로써 업무내에서 확장할 수 있는 영역이 넓다는 것이다. 실제 사례로 이렇게 사용할 수 있다.
- git으로 file upload시 CI내에서 자동으로 전체 소스를 다운받아 빌드후 테스트 결과를 channel에 알려주는 용도
- 업무용 calendar 및 알림
- Event API를 활용한 자동화 구현
일단 내가 사용하려던 용도는 실험이 원격으로 진행되는지라, 원격에서 data를 수집한 후, 수집된 data의 summary를 slack에 올려서 비정상 동작 여부를 확인하고자 했고, 가능하다면 하루 정도 누적한 data에 대한 graph를 plot해서 png 파일 형식으로 upload하면 어떨까 했었다. 그걸 위한 tutorial이 slack에서도 잘 제공되어 있고, 특히 python용으로 만들어진 slack sdk를 사용하면 쉽게 위의 내용들을 구현할 수 있다.
우선 위의 내용을 구현하기 위한 선결과정은 바로 권한이 부여된 앱이 설치되고, 자신이 수행하고자 하는 기능이 적용된 token이 부여되어야 한다는 것이다. 먼저 앱을 먼저 만들어본다. (링크) 이때 App의 이름과 App이 동작할 workspace를 지정해준다. 참고로 workspace 설정 하단에도 나와있는 내용이지만 한번 설정한 workspace는 바꿀 수가 없고, workspace 삭제시 app도 같이 삭제된다는 점을 유의해야 한다.
그 다음으로 해줘야 할게 App이 수행할 기능이다.
App을 통해서 수행할 수 있는 기능은 크게 6가지가 있다.
- Incoming Webhooks : 외부의 환경에서 Slack channel로 message를 보내는 용도
- Slash Commands : 기본제공하는 slash command 기능 외에 추가 기능 구현 용도
- Bots : 자동응답용 봇 용도
- Interactive Components : 버튼이나 dropbox같이 UI를 활용해서 제어할 수 있는 용도
- Event Subscriptions : 앞에서 소개한 calendar와 같이 일정 예약을 위한 용도
- Permissions : Slack외부에서 개발된 별도 앱간의 interaction을 위한 권한 설정
여기서 message를 post하거나 file upload를 위한 기능을 추가하기 위해서 Incoming Webhooks를 설정해준다.
해당 기능을 On으로 바꿔주면 위와 같은 화면으로 바뀌게 되는데, 기본적으로 message는 json format으로 구성되어 post되는 형식으로 나간다. 그래서 자신이 보내고자 하는 데이터를 json으로 바꿔서 나름의 방법대로 전달해도 되고, 아니면 sample처럼 curl (command-line URL)을 사용해서 한줄로 간단하게 보낼 수 있다. 이제 해야 될건 webhook url을 얻는 것인데, 이는 아래의 Add New Webhook을 누르면 얻을 수 있다.
새 Webhook url을 만들기 위해서는 Test Notification의 권한과 어떤 channel에 post를 할 것인지 지정해줘야 한다. dropbox내에서 선택해줘도 되고, 신규로 만들어도 된다.
그러면 위와 같이 신규 webhook url이 생성되고, 그대로 terminal에 입력하면 지정한 channel에 message를 post할 수 있다.
이런 작업을 python용 slack sdk를 사용하면 더 쉽게 할 수 있다. 물론 굳이 sdk를 안쓰고, webhook url만 가지고 할수도 있겠지만, 앞에서 하고자 했던 목적 중 하나인 file upload를 수행하려면 slack sdk에서 제공하는 api를 사용하는 것이 편하다.
원래는 slacker라는 개별 유저가 개발한 라이브러리가 있었는데, 이제는 slack에서 공식지원하는 python slackclient를 사용하면 된다. 개발하고자 하는 script pc에서 pip를 통해 해당 sdk를 설치해준다.
$ pip3 install slackclient
일단 참고해야 될 내용은 이 slackclient도 일종의 eventloop 기반으로 동작한다는 것이다. 다시말해 Jupyter notebook과 같이 동일한 eventloop를 가지고 동작하는 프레임워크에서는 동작하지 않는다는 것이다. 이때는 asyncio와 같이 비동기적으로 eventloop를 빠져나올 수 있는 구조로 slackclient를 사용해야 한다. 아니면 그냥 script내에서 실행하던가 말이다...
역시 webhook 설정과 마찬가지로 이 file upload를 위해서는 권한 설정을 해줘야 한다. 이를 지정하는 것이 Scope란 항목이다.
원래는 Add an OAuth Scope를 통해서 설정하고자 하는 기능에 대한 scope를 지정해줬었지만, 최근에는 Update scopes 항목을 통해서 메뉴 형식으로 scope를 지정할 수 있게 되었다.
마지막으로 권한 부여까지 확인하고 나면 설정창 상단에 App을 재설치하라는 경고 메세지가 출력되고, 이를 수행하면 앞에서 설정한 scope가 반영된 새로운 Bot User OAuth Token이 발급된다. 이렇게 얻은 token을 slackclient 에서 띄우는 Webclient의 인자로 넣어주면 끝난다. 샘플 코드는 다음과 같다.
import slack
client = slack.WebClient(token='xoxb-xxxxxxxxxxxx-xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxx')
response = client.files_upload(
channels="#general",
file='test.py',
title='test.py',
filetype='python'
)
assert response["ok"]
위의 코드는 정해진 channel로 test.py를 보내되, file 이름을 test.py, file type을 python 코드로 보내겠다는 것을 명시적으로 표현한 것이다. 추가로 붙은 assert 구문은 이에 대한 response가 ok가 아닐 경우를 감지하기 위해서 넣은 구문이다. 이를 수행하면, 아래와 같이
파일 형식으로 channel에 upload되는 것을 확인할 수 있다. filetype을 적절히 적용했기에 위와 같이 syntax highlighting이 되는 것도 볼 수 있고, 이게 제대로 안되어 있으면 그냥 평문으로 올라간다.(물론 보는 것의 차이일뿐 내용은 동일하다.) 추가로 slack에 지원하는 file type은 다음 링크에서 확인해볼 수 있다.
이밖에도 OAuth Scope만 잘 지정하면 앞에서 내가 생각하고 있는 내용도 구현할 수 있고, 소위 말하자면 자동화가 이뤄지는 것이다. 굳이 데이터를 원격으로 긁어와서 후처리하는 번거로운 과정도 script하나만 잘 구현하면 몸이 편해지니, 잘 적용하면 업무 효율도 높일 수 있을거 같단 생각이 쪼금 든다.
'Study > SW' 카테고리의 다른 글
[Agile] Agile Manifesto와 12 principles (0) | 2016.09.02 |
---|
- Total
- Today
- Yesterday
- Off-policy
- ai
- 강화학습
- Kinect for windows
- Pipeline
- Expression Blend 4
- SketchFlow
- Windows Phone 7
- Policy Gradient
- Variance
- 딥러닝
- 한빛미디어
- processing
- dynamic programming
- bias
- End-To-End
- Kinect SDK
- Kinect
- Offline RL
- Gan
- PowerPoint
- Distribution
- ColorStream
- RL
- TensorFlow Lite
- windows 8
- arduino
- 파이썬
- reward
- DepthStream
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |