June 25, 2018

slackで日程調整するときの準備をシェルスクリプトで自動化した

slackで↓のような感じでemojiを使って予定を調整することがあります。

image.png (36.1 kB)

が、色々面倒なのでシェルスクリプトで自動化しました。

  • reactionをつけられるようにするために1日ずつ発言しないといけなくてめんどい
  • reactionをポチポチ選んだり + :ok_woman: するのめんどい(しかも発言ごとに繰り返し)

日付を発言するときに曜日は日本語にしたいのですが、ターミナルで半角全角どっちも打つの面倒だった(英語表記にすればいいけど日本語のほうが個人的にわかりやすいので好き)のと、どうせ日付しか入れないし自動化しようと思って、ツェラーの公式を使って計算するようにしました。 なお、動作はMacで確認しています。

使い方

jq をインストールしておきます。(Homebrew だと brew install jq

書き込みたいslackのTokenが必要なので https://api.slack.com/custom-integrations/legacy-tokens に行って取得します。シェルスクリプトのためにOAuthするの大変だったのでlegacy token使ってますが、気になる方は適宜修正してください。最終的にAPIを叩くためのTokenが手に入っていればコードのそれ以外の部分は大丈夫のはず。

その後、↓のコードをコピーして適当に保存します。(ここでは chousei-kun.sh )そしたらさっき作ったTokenでコード内の YOUR_TOKEN を置き換えてください。

(ちなみに set -eu の前にtokenを設定してるのは、もし set -eu のあとでtokenを設定してるときにデバッグで set -eux にして標準出力にTokenが出るのが嫌だったからです)

あと username , teamname , reactions を適宜修正します。 teamname# が必要だけど curl で送信する関係でエンコードして %23 にしておく必要があります。シェルでエンコードまでしようかと思ったけど、そこそこ面倒そうな割に、そんなにコード中で使わないのでやめました。

これで設定は終わりなので、後は↓のような感じで実行すると、指定した日付から自動で曜日を取得して一つずつ username として teamname のチャンネルに発言し、 reactions にあるemojiでreactionします。

./chousei-kun.sh 20180423 20180524 20180630

コード

#!/bin/bash

# Usage:
#  chousei-kun.sh 20180423 20180524 20180630

# tokenは https://api.slack.com/custom-integrations/legacy-tokens で取得
token=YOUR_TOKEN

set -eu

username="hyoshihara"
teamname="%23general" # URLエンコードしておくこと( %23=# )
reactions=("ok_woman" "no_good")

# ツェラーの公式で曜日を算出する
# https://ja.wikipedia.org/wiki/%E3%83%84%E3%82%A7%E3%83%A9%E3%83%BC%E3%81%AE%E5%85%AC%E5%BC%8F
calc-day() {
    year=$1
    month=$2
    day=$3

    if [ $month -le 2 ]; then
        month=`expr $month + 12`
        year=`expr $year - 1`
    fi

    c=`expr $year / 100`
    y=`expr $year % 100`

    item1=`expr \( $month + 1 \) \* 26 / 10`
    item2=`expr $y / 4`
    gregorian=`expr -2 \* $c + $c / 4`

    dayNum=`expr \( $day + $item1 + $y + $item2 + $gregorian \) % 7`
    dates=("土" "日" "月" "火" "水" "木" "金")

    echo ${dates[${dayNum}]}
}

for candidate in $@
do
    # candidateは yyyymmdd を想定
    y=${candidate:0:4}
    m=${candidate:4:2}
    d=${candidate:6:2}
    target="$y-$m-$d%20(`calc-day $y $m $d`)" # %20 = 半角スペース
    echo $target
    res=`curl \
    --data token=${token} \
    --data channel=${teamname} \
    --data text=${target} \
    --data as_user=${username} \
    -s \
    "https://slack.com/api/chat.postMessage"`

    if [ `echo $res | jq ."ok"` != "true" ]; then
        echo "postMessage: ${target} is failed"
        echo error: `echo $res | jq ."error"`
        exit -1
    fi

    channel=`echo $res | jq -r ."channel"`
    ts=`echo $res | jq -r ."ts"`

    for reaction in ${reactions[@]}
    do
        # reaction追加のタイミング早すぎるとemojiの並び順が安定しないので待っている
        sleep 1

        res=`curl \
        --data token=${token} \
        --data channel=${channel} \
        --data name=${reaction} \
        --data timestamp=${ts} \
        -s \
        "https://slack.com/api/reactions.add"`

        if [ `echo $res | jq ."ok"` != "true" ]; then
            echo "reactions.add: ${reaction} for ${target} is failed"
            echo error: `echo $res | jq ."error"`
            exit -1
        fi
    done
done

echo "Done."

ツェラーの公式の実装について

公式自体の詳細はググっていただくとして、Wikipedia見て愚直に実装しました。変数名とかはWikipedia準拠です。なんか間違ってた時に自分で直しやすい実装をしようと思って書いたので、もし別のやり方をしたい方は適宜修正してください。

© yoshihara 2017-2019

Powered by Hugo & Kiss.