Python とSlack の連携

November 07, 2018 3 min read

GPU サーバー上で Python の計算を回しているときに、計算が終わったことを外出先でも知りたいというモチベーションから連携させた話。みんな同じことを思ってるみたいで、 Google で調べてみると、 Incoming Webhooks を使う方法が紹介されていた。

個人で使うならこれでもいいが、予め設定したチャンネルのみにしか送れない。

You cannot override the default channel (chosen by the user who installed your app), username, or icon when you're using Incoming Webhooks to post messages. Instead, these values will always inherit from the associated Slack app configuration.

そのため、複数人が利用したいときに不便だ。研究室で使用したかったので、複数のチャンネルに送れる方法を API リファレンスで探していたところ、 chat.postMessage を見つけた。( Incoming Webhooks はこの chat.postMessage の機能拡張版らしい?)

おおまかな流れは

  • Slack App を作成
  • Workspace にインストール
  • Python で POST

だ。

Slack App を作成

Slack AppCreate New App を押して新しいアプリを作成する。(元からあるアプリの機能に追加する場合はこの手順は不要)今回は以下のように設定した。

  • App Name : jupyter-notification
  • Development Slack Workspace : 使いたいワークスペース

作成したら、ワークスペースにインストールする前に権限を追加する。 chat.postMessage を見ると、 chat:write:bot の権限が必要なことがわかる。

左のメニューの中にある OAuth & Permissions をクリックし、 Scopeschat:write:bot を追加したあと Sava Changes で保存する。

Workspace にインストール

さっきのページの一番上にある Install App を押してワークスペースにこのアプリを追加する。

インストールできたら、同じページに戻ってくるので、ページ上部に書いてある OAuth Access Token をメモする。これを使うことで chat.postMessage が使用できる。

Python で POST

python で POST するために requests を追加する。( Anaconda 環境の場合は source activate を忘れないように。)

pip install requests

次に POST する関数を書く。

def sendSlackMessage(msg):
    import requests
    import json
    url = 'https://slack.com/api/chat.postMessage'
    channel = u'#jupyter-notification'
    res = requests.post(url, data = json.dumps({
        'channel': channel,
        'text': msg.encode().decode('utf-8'),
        'icon_emoji': u':jupyter:',
        'link_names': u'true'
    }), headers={
        'Content-Type': 'application/json',
        'Authorization': 'Bearer xoxp-xxx-xxxx-xxxxx'
    })
    return res

channel で投稿するチャンネルを指定する。Authorization ヘッダーで指定するベアラートークンは上でメモしたものを使う。この手順はココに書いてある。(最初 body に含めていたらエラーが返ってきて辛かった。)

デフォルトでのアイコンは味気ないので ワークスペースに jupyter 絵文字を追加した。これは公式のガイド がわかりやすいので、追加したい場合はこちらを参照してほしい。

試しに

sendSlackMessage('[name] message')

のようなフォーマットで送って、無事 Slack の #jupyter-notification に送られてきたら成功だ。もし送られてこなかったら、レスポンスの中にエラーメッセージが含まれているので確認して直す。


Written by Shun Nishimura.

© Copyright 2020 Shun Nishimura - All Rights Reserved