2020-06-13

Slack のステータスを変更する CLI ツールっぽいものを Python で作ってみた

一つ前の記事で Google Apps Script を使って Slack のステータスを変更しましたが、今回はそれを Python 製の CLI ツールっぽいものとして作ってみた話です。

目次

概要

コマンドラインから Slack のステータスを変更するコードを Python で実装します。 CLI ツールというほどしっかりしたものではないため、 「っぽいもの」 ということにしておきます。

基本的には前回の記事で書いたスクリプトを Python に書き換えるのですが、セットする絵文字やメッセージをコマンドラインからオプションとして渡せるような形で実装をしています。

Google Apps Script で Slack のステータスを変更する

実装

構成としては、 Slack の API や対象のユーザ ID などを記述した設定ファイル config.json と、実際の処理をする Python スクリプト change_status.py の 2 つを次のように配置します。

$ tree .
.
├── config.json
└── src
    └── change_status.py

config.json

config.json の中身は次のような構造にします。

{
  "slack": {
    "user_id": "XXXXXXXX",
    "api_token": "xoxp-********-********-********",
    "default_status_emoji": ":ghost:",
    "default_status_message": "I'm a ghost."
  }
}

change_status.py

change_status.py は次のように実装します。ランタイムは Python 3 です。

import argparse
import json
import os
import urllib.parse
import urllib.request

# define config value
with open(os.path.dirname(os.path.abspath(__file__)) + '/../config.json') as j:
    config = json.load(j)

USER_ID = config['slack']['user_id']
API_TOKEN = config['slack']['api_token']
DEFAULT_STATUS_EMOJI = config['slack']['default_status_emoji']
DEFAULT_STATUS_MESSAGE = config['slack']['default_status_message']
PROFILE_SET_URL = 'https://slack.com/api/users.profile.set'

# CLI option setting
p = argparse.ArgumentParser()
p.add_argument('-e', '--emoji',
               help='Slack emoji code for status icon. (e.g) :ghost:',
               default=DEFAULT_STATUS_EMOJI)
p.add_argument('-m', '--message',
               help='message for status.',
               default=DEFAULT_STATUS_MESSAGE)
args = p.parse_args()


def set_status(emoji, message):
    # type: (str) -> ()
    """Set Slack status."""
    headers = {
        'Authorization': 'Bearer %s' % API_TOKEN,
        'X-Slack-User': USER_ID,
        'Content-Type': 'application/json; charset=utf-8'
    }
    params = {
        'profile': {
            'status_emoji': emoji,
            'status_text': message
        }
    }

    req = urllib.request.Request(
        PROFILE_SET_URL,
        method='POST',
        data=json.dumps(params).encode('utf-8'),
        headers=headers
    )

    with urllib.request.urlopen(req) as res:
        print(json.dumps(json.loads(res.read().decode('utf-8')), indent=2))


if __name__ == '__main__':
    status_emoji = args.emoji
    status_message = args.message

    set_status(status_emoji, status_message)

特に変わったところは無いですが、コマンドラインから実行する際に引数とオプションを楽に扱うことが出来るように argparse モジュールを使用しています。

ファイル上部にある下記の部分で、コマンドラインオプションの設定をしています。

# CLI option setting
p = argparse.ArgumentParser()
p.add_argument('-e', '--emoji',
               help='Slack emoji code for status icon. (e.g) :ghost:',
               default=DEFAULT_STATUS_EMOJI)
p.add_argument('-m', '--message',
               help='message for status.',
               default=DEFAULT_STATUS_MESSAGE)
args = p.parse_args()

これで、 -e または --emoji オプション、 -m または --message オプションを使用して絵文字とメッセージそれぞれの値を受け取ることができます。例えば -e オプションで指定された値をプログラム内で参照するには、 args.emoji のようにして使います。

argparse については下記の記事を参考にしました。

argparse を使用すると、 -h オプションで実行することで add_argument()help で指定した文字列が良い感じに出力されます。

$ python3 src/change_status.py -h
usage: change_status.py [-h] [-e EMOJI] [-m MESSAGE]

optional arguments:
  -h, --help            show this help message and exit
  -e EMOJI, --emoji EMOJI
                        Slack emoji code for status icon. (e.g) :ghost:
  -m MESSAGE, --message MESSAGE
                        message for status.

Docker イメージで実行

次のコマンドを叩いて実行します。

$ python3 src/change_status.py

ただ、これだと Python 3 の環境が無いとダメなので、 Docker イメージで実行できるようにしてみました。

次のような Dockerfile を用意します。今回は Python 3.8.3 のイメージを使用します。

FROM python:3.8.3
COPY . /app
ENTRYPOINT [ "python", "/app/src/change_status.py" ]

これをビルドして

$ docker build -t michimani/chss .

実行します。

$ docker run michimani/chss

オプションを指定する場合は次のように実行します。

$ docker run michimani/chss -e ":monkey:" -m "I am a monkey."

このように、 Docker は CLI っぽく使うことが出来るのが良いですね。必要なプロセスを必要なときにだけ起動して、不要になったら削除するという Docker の主とした使い方です。 … まあこれは先日レビューしたみんなの Python の 第 2 章に書かれていたことなんですが。

まとめ

Slack のステータスを変更する CLI ツールっぽいものを Python で作ってみた話でした。 ソースコードは GitHub に置いているので、もしよかったら使ってみてください。

https://github.com/michimani/chss

用途としては、毎日の勤務開始・終了と一緒に使うくらいですかね…。