msdd’s blog

deep learning勉強中。プログラム関連のこと書きます。

毎日、Githubのトレンドを投稿してくれるSlackアプリを作る(1)

はじめに

毎日、SlackでGithubのトレンドを通知してくれるものが欲しかったので作っている。

今回は、ローカルでプログラムを実行すると、Githubのトレンド情報を投稿できるよう なものを作った。

作り方

1. Slackのワークスペース作った

通知するためにSlackのワークスペースを作った。

f:id:msdd:20200501181524p:plain

test用にチャンネルを作った。右側のサイドバーのチャンネルの+ボタンを押して、チャンネルを作った。 ここに投稿していく。

f:id:msdd:20200501181545p:plain

2. Slackのアプリを作る

Slack App作成

まず Slack Appを作る。このSlack Appはユーザーと似たようなことができ、権限を与えれば プログラムからSlackに書き込んだりすることができる。 これを使い、GithubのトレンドをSlackに投稿していく。

Slack Appの作り方は、Create Slack appに従って進めていった。create a slack appのボタンを押して、アプリを作成する。

f:id:msdd:20200501181602p:plain

App Nameにアプリ名(後で変更可)とどのワークスペースに追加するかを指定して、 Create Appのボタンで作成する。App NameGithubTrendingNotificationAppで、 ワークスペースは先ほど作ったワークスペースを指定した。

f:id:msdd:20200501181617p:plain

アプリの設定

Appを作った後に、アプリの基本情報が表示される。 出ない時は、アプリ一覧からアプリを選択する。 f:id:msdd:20200501181633p:plain

プログラムでSlackへの書き込みができるように権限を与える。 左側のOAuth & Permissionsをクリックして、OAuthと権限を設定するページを開く。 下側へスクロールした所にある、ScopesのBot Token ScopesのAdd an OAuth Scopeボタンを押して、chat:writeに設定する。

f:id:msdd:20200501181645p:plain

アプリをワークスペースに追加

上のスクロールして戻ると、Install App to Workspaceのボタンがあるので押して、 アプリをワークスペースに追加する。

f:id:msdd:20200501181654p:plain

確認画面が出てくるので、許可を押して追加する。

f:id:msdd:20200501181709p:plain

トークンが表示される。これを使ってbotから投稿することになる。 コピーしておく。

f:id:msdd:20200501181721p:plain

Slack画面を見てみると、Appのところに、先ほど設定したアプリが入っているのがわかる。

f:id:msdd:20200501181731p:plain

次に、先ほど作ったtestチャンネルにアプリを追加する。 testチャンネルへ行くと、アプリを追加するとあるので、 クリックする。

f:id:msdd:20200501181854p:plain

作ったアプリ(GithubTrendingNotificationApp)を追加する。

f:id:msdd:20200501181903p:plain

3. 投稿プログラムを作った

pythonを使って、slackに投稿するプログラムを書く。 slackに投稿するために、Python slackclientを使った。 Python slackclientは、pythonのバージョンが3.6以上が必要。

anacondaで新しい環境作って動かした。 pythonのバージョンは、python:3.8.2、slackclientのバージョン:2.5.0。

conda create -n slack_github_trending_notification_app -y

環境を起動。

conda activate slack_github_trending_notification_app

slackclientをインストールした。

conda install -c conda-forge slackclient

試しに投稿するプログラム

試しに、slack apiのページにあったサンプルスクリプトを少し変えて動かしてみる。 tokenは先ほど作ったtoken。 api_test.pyとして、

python api_test.py

で動かした。

from slack import WebClient
from slack.errors import SlackApiError

def main():
    channel="#test"
    token="SLACK_TOKEN"
    text="Hello slack!"
    client=WebClient(token=token)

    try:
        response=client.chat_postMessage(
            channel=channel,
            text=text
        )

        assert response["message"]["text"]==text
    except SlackApiError as e:
        assert e.response["ok"] is False
        assert e.response["error"]

        print(f"エラー: {e.response['error']}")

if __name__=="__main__":
    main()

実行してみると、きちんとSlack上にHello slack!が表示され動く動いていることが確認できた。

github trendingからデータ取得して投稿するプログラム

次に、投稿内容をGithubのトレンド情報にしたいので、トレンドを取得する コードにする。 github trending を取得する公式APIはないので、 非公式APIで取得する。

www.msdd.info

前回の記事で、使ったコードも使う。

取得時間もメッセージに入れたいが、サーバーで動かす予定なので、 タイムゾーンが違うこともあるので、UTCからJSTに変換した。 そのため、pytzをインストールした。

conda install -c anaconda pytz

プログラムは下のようなものとなった。 中身は、 githubのトレンドのプログラミング言語と期間を指定して 取得する関数get_trending_repositoriesで、トレンドを取得する。 send_trending_messagesで、取得したリポジトリの情報を一つずつ Slackに送っていくようになっている。

assert response["message"]["text"]==textを入れていると、 エラーになることが有ったので外した。

from slack import WebClient
from slack.errors import SlackApiError

import urllib.request
import json
from datetime import datetime
import pytz

token="SLACK_TOKEN"

def get_trending_repositories(language=None,since="daily",spoken_language_code=None):
    params=""
    params+="?since="+since

    if language is not None:
        params+=("&language="+language)

    if spoken_language_code is not None:
        params+=("&spoken_language_code="+spoken_language_code)

    url="https://ghapi.huchen.dev/repositories"+params

    with urllib.request.urlopen(url) as res:
        body=res.read()
        j=json.loads(body)

        return j

def send_trending_messages(channel,language,since,num_repos=None):
    repos=get_trending_repositories(language=language,since=since)
    if num_repos is not None:
        repos=repos[:num_repos]
    
    time_utc=datetime.utcnow().replace(tzinfo=pytz.utc)
    time_jst=time_utc.astimezone(pytz.timezone("Asia/Tokyo"))
    for i,repo in enumerate(repos[:num_repos]):
        text=f"*{i+1} : {repo['name']}*\ntime(jst) : {time_jst}\n"\
        f"{repo['url']}\n{repo['description']}"
        send_message_to_slack(channel,text)

def send_message_to_slack(channel,text):
    client=WebClient(token=token)

    try:
        response=client.chat_postMessage(
            channel=channel,
            text=text
        )

        # assert response["message"]["text"]==text
    except SlackApiError as e:
        assert e.response["ok"] is False
        assert e.response["error"]

        print(f"エラー: {e.response['error']}")

if __name__=="__main__":
    send_trending_messages("#test","python","daily")

このファイルに名前を付けて、実行してみると、アプリが設定したtestチャンネルに、 pythonの日ごとのGithubのトレンドを通知してくれる。 気になる点としては、通知音がかさなってうるさい。

f:id:msdd:20200501181937p:plain

これで、通知するプログラムが完成した。

SlackのAPIを使って、Githubのトレンド情報を通知する アプリがconsoleで動くようになった。 次はサーバー上で動くようにして、 毎日投稿するようにしたい。

参考サイト

Sending messages | Slack