---
layout: post
title: slacker로 slack bot 만들기
comments: true
tags:
- python
- slack
- 봇
- slacker
---
&nbsp;&nbsp;&nbsp; 멘토님께서 라인의 `notification`을 이용해서 봇 만든것을 보고 따라 만들었다. 봇 만들고 싶은데 핑계가 없어서 고민하다가 동아리에서 `slack`을 쓰기 때문에 슬랙봇을 만들어보기로 했다. 스터디하는 사람들을 대상으로 커밋한지 얼마나 되었는지 알려주는 용도로 만들었다. 결과물은 아래와 같다.

<img src="/images/commit-bell.jpeg" alt="클린 코드를 위한 테스트 주도 개발" style="width: 480px; margin-left: auto; margin-right: auto; "/>

&nbsp;&nbsp;&nbsp; 먼저 봇을 등록해야한다. [Slack Apps](https://studytcp.slack.com/apps)의 우측 상단에 `Build`를 눌러서 등록을 한다. 아래와 같은 화면이 나온다. 다른 팀에게 공개하지 않을 것이라서 `Something just for my team`을 선택했다.
![slackbot 등록]({{ site.url }}/images/slackbot_0.png)

&nbsp;&nbsp;&nbsp; 두 번째 `Bots`를 선택한다.
![slackbot 등록]({{ site.url }}/images/slackbot_1.png)

&nbsp;&nbsp;&nbsp; 적절한 설정을 하고 `token`을 꼭 기억(복사)해 두자.

&nbsp;&nbsp;&nbsp; pip로 필요한 것을 설치하자. [github3.py](https://github3py.readthedocs.io/en/master/), [slacker](https://pypi.python.org/pypi/slacker/), datetime, pytz를 사용했다.
<pre>$ pip install slacker
$ pip install github3.py
$ pip install datetime
$ pip install pytz</pre>

&nbsp;&nbsp;&nbsp; 전체 코드는 아래와 같다.

```python
from slacker import Slacker
import github3
import datetime
import pytz

local_tz = pytz.timezone('Asia/Seoul')
token = 'xoxb-발급받은-토큰'
slack = Slacker(token)
channels = ['#채널1', '#채널2']

def post_to_channel(message):
    slack.chat.post_message(channels[0], message, as_user=True)

def get_repo_last_commit_delta_time(owner, repo):
    repo = github3.repository(owner, repo)
    return repo.pushed_at.astimezone(local_tz)

def get_delta_time(last_commit):
    now = datetime.datetime.now(local_tz)
    delta = now - last_commit
    return delta.days

def main():
    members = (
        # (git 계정 이름, repo 이름, 이름),
        # [...]
    )
    reports = []

    for owner, repo, name in members:
        last_commit = get_repo_last_commit_delta_time(owner, repo)
        delta_time = get_delta_time(last_commit)

        if(delta_time == 0):
            reports.append('*%s* 님은 오늘 커밋을 하셨어요!' % (name))
        else:
            reports.append('*%s* 님은 *%s* 일이나 커밋을 안하셨어요!' % (name, delta_time))

    post_to_channel('\n 안녕 친구들! 과제 점검하는 커밋벨이야 호호 \n' + '\n'.join(reports))

if __name__ == '__main__':
    main()
```

## **해결하지 못한 것**
* **X-RateLimit-Limit 올리기**      
&nbsp;&nbsp;&nbsp; 테스트 때문에 꽤 많이 돌리다 보니까 횟수제한에 걸렸다. 에러 메시지는 아래와 같다.
<pre>github3.models.GitHubError: 403 API rate limit exceeded for 106.246.181.100. (But here's the good news: Authenticated requests get a higher rate limit. Check out the documentation for more details.)</pre>

&nbsp;&nbsp;&nbsp; 찾아보니까 하나의 IP당 한 시간에 보낼 수 있는 횟수가 정해져 있다고 한다. 출력해 보면 아래와 같다. `X-RateLimit-Limit`은 기본이 60이고 최대 5000으로 올릴 수 있다는데 헤더 수정을 어떻게 해야할지 모르겠다. 사실 이거 해결한다고 시간이 꽤 지나버려서 해결(?)이 되었다.
<pre>[...]
Status: 403 Forbidden
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1475913003
[...]</pre>

* **이 코드를 어디서 돌려야 하는가.**     
&nbsp;&nbsp;&nbsp; 하루에 2-3번? 정도 해당 채널에 알림을 보낼 것이다. 사실 동아리 서버 쓰면 된다고는 하는데.. 개인 서버를 쓰고는 싶고 그렇다고 AWS 쓰자니 별로 하는것도 없는데 달마다 치킨 값을 헌납해야해서 고민이다.

## **참고자료**
* [https://corikachu.github.io/articles/python/python-slack-bot-slacker](https://corikachu.github.io/articles/python/python-slack-bot-slacker)
* [https://www.fullstackpython.com/blog/build-first-slack-bot-python.html](https://www.fullstackpython.com/blog/build-first-slack-bot-python.html)
* [https://godoftyping.wordpress.com/2015/04/19/python-%EB%82%A0%EC%A7%9C-%EC%8B%9C%EA%B0%84%EA%B4%80%EB%A0%A8-%EB%AA%A8%EB%93%88/](https://godoftyping.wordpress.com/2015/04/19/python-%EB%82%A0%EC%A7%9C-%EC%8B%9C%EA%B0%84%EA%B4%80%EB%A0%A8-%EB%AA%A8%EB%93%88/)
