任意のコマンド実行が終わったらSlackに通知を送りたい


動機

いま在籍している大学の研究室では、設置されているワークステーション(すごく性能のいいPC)に数日かかるようなすごく重い処理を実行させて、ちょくちょく処理終わってるかな~?と様子を見に来る、という使い方をしています。

わざわざ様子を見るためだけに来るのも手間なので、終了したことを通知してくれるツールがあると便利だな~と思って作りました。

環境

Ubuntu 18.04
Python 3.6

使用例

これは実行したいコマンド

python aaa.py

以下のように、コマンドの前にslacknoticeを付けると…

slacknotice python aaa.py

slackに開始と終了が通知されます。

方法

  1. Slack Incoming WebhooksというSlackアプリケーションを用いてPOSTリクエストでメッセージを送信するためのエンドポイントを作成
  2. ローカル側で「slacknotice」というスクリプトを作成。ここでは引数に受け取ったコマンドを実行し、その実行前と後にPOSTリクエストを送る。ディレクトリにPATHを通して全体から呼び出せるようにする。

1. Slack Incoming Webhooksの設定

アプリをSlackに追加する という画面から「Incoming Webhooks」というアプリケーションを検索して追加します。
投稿するチャンネルや通知するメッセージのアイコンなどの設定を行うと、進めていった先の画面で Webhook URL を取得できます。これを次の手順で使用します。
※くわしい設定方法:SlackのIncoming Webhooksを使い倒す

2. スクリプトの準備

2-1. スクリプト作成

「slacknotice」というスクリプトを作ります。
Pythonで書いています。なのでPythonの入っている(Pythonコマンドでインタープリタが起動する)環境でしか動きません…
(シェルスクリプトでcurlなどを使用して書く方法でもできるとは思います)

以下は一番シンプルなパターン

#!/usr/bin/env python

# ここを取得したWebhook URLに変更
webhook_url = "https://hooks.slack.com/services/AAAAA/BBBBBB/CCCCCCCC"

import json, os, requests, sys
from subprocess import run

# 通知を送る関数を定義
def notice(msg):
    post_data = json.dumps({"text": msg})
    requests.post(webhook_url, data=post_data, headers={"Content-Type": "application/json"})


# 引数から実行するコマンドを取得
command = sys.argv[1:]

# 実行前通知
notice("実行開始")

# コマンド実行、ユーザーのカレントディレクトリ(os.getcwd())で実行するようにしている。
run(commands, cwd="{}/".format(os.getcwd()))

# 実行後通知
notice("実行終了")

これを保存します。
今回は~/scripts/slacknoticeにあるという前提で話を進めます。

2-2. 実行権限の付与

chmod u+x ~/scripts/slacknotice

でスクリプトを実行可能にします。

2-3. PATHを通す

echo export PATH='$PATH:$HOME/scripts/' >> ~/.bashrc
source ~/.bashrc

でスクリプトが保存されているディレクトリ~/scripts/にPATHを通します

2-4. 実行

slacknotice ls -altr

など適当なコマンドを実行すると、実行前と後に通知が飛びます。

まとめ

Slackは手軽にメッセージ送信を行えるので、便利ですね。