この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは。サービスグループの武田です。
普段から業務でBacklogを使用しているのですが、ふと気付くとお知らせ通知の未読メッセージがたまっていました(ベルアイコンを開いたところです)。私個人の傾向としてPull Requestをマージした際のメッセージが未読として残る傾向にあるようです。
GUI上で一括既読できればよかったのですが、ちょっと触った感じでは見当たりませんでした(あったら教えてください)。一件一件開いて既読にするのが面倒だったので、Backlog APIを利用してスクリプトにしてみましたので紹介します。
検証環境
次の環境で検証しています。
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.14.1
BuildVersion: 18B75
$ echo $BASH_VERSION
4.4.23(1)-release
$ jq --version
jq-1.5
事前の準備
まずはBacklog APIを使用するためにAPI Keyを取得する必要があります。未取得の場合は次のエントリなどを参考に取得してください。
API Keyが取得できたら環境変数に設定しておきます。同様にBacklogのURLも設定してください。.bashrc
などに設定しておくとbash起動時に設定されるため楽できます。
export BACKLOG_API_KEY=qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM123456789000
export BACKLOG_API_ENDPOINT=https://xxx.backlog.jp/api/v2
すべて既読にするスクリプト
今回は次のようなスクリプトを作成してみました。
#!/bin/bash -eu
declare -xr api_key="apiKey=${BACKLOG_API_KEY}"
function get_unread_notifications_count() {
curl -s -X GET "${BACKLOG_API_ENDPOINT}/notifications/count?${api_key}&resourceAlreadyRead=false"
}
function get_notifications() {
declare max_id=${1:+&maxId=$1}
curl -s -X GET "${BACKLOG_API_ENDPOINT}/notifications?${api_key}${max_id}"
}
function mark_as_read() {
declare id=$1
curl -s -X POST "${BACKLOG_API_ENDPOINT}/notifications/${id}/markAsRead?${api_key}"
}
declare -xf mark_as_read
declare -i unread_count=$(get_unread_notifications_count | jq '.count')
echo "未読通知は${unread_count}件です"
(( unread_count == 0 )) && exit 0
declare last_id
while :; do
declare ns=$(get_notifications "$last_id")
[[ "$ns" == "[]" ]] && break
last_id=$(echo "$ns" | jq 'last | .id')
if [[ -n "$ns" ]]; then
echo "$ns" | jq '.[] | select(.resourceAlreadyRead==false) | .id' | tee /dev/tty | xargs -I{} -P 5 bash -c "mark_as_read {}"
fi
done
スクリプト作成にあたって調べたことなど
お知らせ関係のBacklog API
Backlog APIのドキュメントには次の4つのAPIが記載されていました。
- お知らせ一覧の取得
- 今回使用しています
- 未読のお知らせのみ取得したかったのですが、パラメーターになかったため今回は既読も含め全件取得しています
- お知らせの既読化
- 今回使用しています
- お知らせ一覧を取得した際の
id
を指定して既読にできます
- お知らせ数の取得
- 今回使用しています
- そもそも一覧取得するかどうかの判定として、最初に未読通知の件数(
resourceAlreadyRead=false
)を取得して0ではなかったら処理するようにしました - パラメーターとして
alreadyRead
とresourceAlreadyRead
があります。alreadyRead
はお知らせそのものを見たかどうかのフラグ、resourceAlreadyRead
はお知らせ元の本体を見たかどうかのフラグのようです
- お知らせ数のリセット
- 使用していません
- ドキュメントを見てもよくわからなかったんですが、試した限りは前述の
alreadyRead
をまるっとtrue
にしてくれるAPIのようです
今回やりたかったことはresourceAlreadyRead
フラグをすべてtrue
にしたかったわけですが、それをよしなにやってくれるAPIが今のところないようです。
ディスプレイに出力しつつパイプで次のコマンドにも標準出力を渡す
未読のお知らせを既読にするにあたって、何も画面に表示されないと本当に進んでいるのか不安になるので既読にしたお知らせのidを出したいなと考えました。一度変数に入れて、出力してからxargs
すればいいんですが、うまいことワンラインで実現できないか試行錯誤したところ/dev/tty
にtee
すればいけそうということになりました。
echo "$ns" | ... | tee /dev/tty | xargs ...
ただこの部分はあまり自信がない部分ですので、もっとうまいやり方があれば教えてください。
xargsで定義関数を使用する
シェルスクリプト内でmark_as_read
という関数を定義しています。これをxargs
コマンドで使用するために少し工夫が必要でした。単に呼んだだけでは No such file or directory となってしまいます。それが次の部分です。
...
declare -xf mark_as_read
...
if [[ -n "$ns" ]]; then
echo "$ns" | jq '.[] | select(.resourceAlreadyRead==false) | .id' | tee /dev/tty | xargs -I{} -P 5 bash -c "mark_as_read {}"
fi
...
定義したmark_as_read
をdeclare -xf
でエクスポートしています(export -f
でも同様)。さらに関数を呼び出すときにbash -c "mark_as_read {}"
としています。この2つをすることで、シェルスクリプト内で宣言した関数をxargs
で使用できます。
まとめ
クリック連打するのが面倒だったのでスクリプトを書いてみましたが、bashもまだまだ知らないことが多いなと実感しました。また、こうやってAPIが公開されていることで運用の自動化ができるので便利ですね。