【Python/JWT】LINE WORKS の BOT の AccessToken を取得する
今回、LINE WORKS に新しく BOT を導入することになった。BOTの用途は、通知用であり、インタラクティブである必要はない。
通常の LINE の BOT を作成したことはあったが、LINE WORKS での BOT 作成は初だったので、備忘録として残しておく。
システム概要
今回、LINE WORKS + Power Automate(Teams)であるカレンダーの予定を抽出して、BOT で通知させることを想定している。概略図は以下の通りである。
今回の記事では、LINE WORKS のセットアップ部分、特にAccess_Tokenの取得について紹介する。
LINE WORKS の BOT 作成手順
公式ドキュメントに事細かに丁寧に書かれているので、詳細な手順は公式ドキュメントを是非見てほしい。
そして、1 の Server Token の発行手順は以下のようになっている。
今回、(Power Automate に組み込む前に)Python で access_token
の取得及びメッセージ送信試験を行った。(access_tokenは、24 時間以内利用されない場合には自動的に失効する。今回のシステムの仕様では、毎日使用するため、access_tokenが失効する可能性は低い。access_tokenを取得して、そのまま Power Automate に組み込むことを想定している。)
なお、実装したサンプルコードは GitHub に公開している。 pipenv を使って、Python仮想環境(開発環境)を即座に構築するだけで、サンプルプログラムの動作確認ができるようにしているので、どうぞ。
pipenv に関しては、以前の【Python】Pipenvを用いたPython仮想環境(開発環境)を参考にして欲しい。
プログラムを実行する前に、グローバル変数、LINE WORKSのBOTに使用する以下の設定パラメータを追記する必要がある。
# グローバル変数 DOMAIN_ID = "" API_ID = "" SERVER_API_CONSUMER_KEY = "" SERVER_LIST_ID = "" SERVER_LIST_PRIVATEKEY = "" BOT_NO = ""
それぞれの値は、Developer Console で確認することができる。(事前に、BOTなどもこの時点で作成しておく必要がある。)
SERVER_LIST_PRIVATEKEY
には、Server List(ID登録タイプ)の認証キーを設定するが、Developer Consoleではprivate_[日付].key のファイルがダウンロードされ、以下のように数行になっている。
-----BEGIN PRIVATE KEY----- MIIEvgIBADANBgkqhkiG9w0B 〜省略〜 +juq+vKHrY7+CQgr/7bjZqmR -----END PRIVATE KEY-----
このままだとグローバル変数に登録することができないので、改行されている部分を全て改行コードに書き換えて、一行とする。
$ cat private_20201229171641.key | sed -e :loop -e 'N; $!b loop' -e 's/\n/\\n/g' | pbcopy
上記のコマンドを実行することで、クリップボードにコピーされた状態になるので、そのままグローバル変数の部分にペーストする。
SERVER_LIST_PRIVATEKEY = "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0B (省略)+juq+vKHrY7+CQgr/7bjZqmR\n-----END PRIVATE KEY-----"
全ての設定が完了次第、python get_token.py
を実行することで BOT から「Hello World」と通知されれば完璧である。
ログから、access_tokenを確認することもできる。
$ python get_token.py {'action': 'create jwt', 'status': 'success', 'message': 'JWT:eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJiYTY3M2ZhOTBiNjQ0YWU2OGI4MjliNzIxM2MxMjFkYiIsImlhdCI6MTYwOTI2OTg3MiwiZXhwIjoxNjA5MjcxNjcyfQ.TlA5A86qKH6cQ4vKmKtpulhBYxZbxIg6fSLLYLNePqFb59uXpnte0etG0jsv2AyDquDcFZlUg62baHQil8V0mngo_OUcX51llQK3-Cx5BBahYSuMVU_FwMcTrtwJfBp0zLHRxpy5hrifTnafuzrRXbhrPixELnxYVoRGHglDbn39kmbylU-1zg5Fr1w__obiwUOSC2J80WmuwO8ugjoLx67xKYCuInFpyMGAG7zdRJLeoyeAuRBy7wA99LSLMS9vzdrDvGnzZjlP5etF2pDo7ZUbQOUSqFNin9CHVPdlOmW2rifQxRMsO5ZnNAtAZoHXpZBjgFQwei8xjuoYW0sILA'} {'action': 'get access token', 'status': 'success', 'message': 'access_token:AAABCVee9HJEVlsdbn/egcTZVN+Cw3+c2VydmVySWQ+O8Up4ja2mud53VSj911kHu70OZ5CJ5Bi6bRcwPJE87ExNCZ/BGo4b13uYu4vsFn9qHUD5zZpILYKFb1c8k2mUUrLnc7PMooaWqyOAagGNugfiOepzWzdaMGNEWD2Dg/85wFO7rKjoUrsNiZOUCIKWR25vvbpEoKF2WW1xAYl8yZPFTwbPn9VfgTGsPoPtOlsEBPjUjp6e1WBTedVTsYlV3B17zz59Yb7n2iNYzMubw1/DAbEznTQYPsvoeiSggVMt3t6IguUGuXJIocD+qpZ59rmxIXO9tZ2yFj3BudqTo5uz5AHD07J2nTl9LJJC3wr6jtCqjnm/tTxH6TVPG'}
JWT とは
JWT とは、JSON Web Tokenの略である。(ジョットと読むらしい。)以下の3つの要素から構成され、それぞれは「.」で結合されている。また、それぞれは Base64
でエンコードされている必要がある。
[ヘッダー].[クレーム情報].[署名]
JWTの作り方
1. アルゴリズムとTokenタイプをヘッダに設定して、Base64でエンコードする
$ echo -n '{"alg": "RS256", "typ": "JWT"}' | base64 eyJhbGciOiAiUlMyNTYiLCAidHlwIjogIkpXVCJ9
$ echo -n '{"iss":"ba673fa90b644ae68b829b7213c121db","iat": 1609274027, "exp": 1609275827}' | base64 eyJpc3MiOiJiYTY3M2ZhOTBiNjQ0YWU2OGI4MjliNzIxM2MxMjFkYiIsImlhdCI6IDE2MDkyNzQwMjcsICJleHAiOiAxNjA5Mjc1ODI3fQ==
パラメータ | 説明 |
---|---|
iat | JWT 生成日時(UNIX、単位:sec) |
exp | JWT 満了日時(UNIX、単位:sec) |
iss | LINE WORKSで発行されたサーバーIDなど |
事前に用意されているのは、こちらのパラメータ である。
3. ヘッダとペイロードを . (ドット) で結合し、署名なしTokenを生成する
eyJhbGciOiAiUlMyNTYiLCAidHlwIjogIkpXVCJ9.eyJpc3MiOiJiYTY3M2ZhOTBiNjQ0YWU2OGI4MjliNzIxM2MxMjFkYiIsImlhdCI6IDE2MDkyNzQwMjcsICJleHAiOiAxNjA5Mjc1ODI3fQ==
4. 署名なしTokenに対し、秘密鍵を用いて署名を生成する
openssl dgst
で電子署名を生成する。
$ echo -n 'eyJhbGciOiAiUlMyNTYiLCAidHlwIjogIkpXVCJ9.eyJpc3MiOiJiYTY3M2ZhOTBiNjQ0YWU2OGI4MjliNzIxM2MxMjFkYiIsImlhdCI6IDE2MDkyNzQwMjcsICJleHAiOiAxNjA5Mjc1ODI3fQ==' | \ openssl dgst -sha256 -sign private_20201229171641.key -binary | \ base64 W//2sawtLzg3GfH6GkeS1nw947ec5qiynl2pibztjVycpe73KcENXt6Z4aftfUgMEjHRvX3N8i754E9rBffI4gfarQzY+nhUVdxP9zFXSxr7YPXoPx9A9bL4bjNRvkKJV2BRLlJkOQ6g9TY1Uu5mtPsyTZ6zy2+hXa8h8tn0dSfsLF4uH0nOiEt6p44tNz6U8/0jUlPNd3tt3W7F4MZy038nMazYQ6g5e1W7tfgqCtV0NVQUGpZdKKh0HvWf8qiqE5cTJ6y+eREENZMAEjPY6rxx19PVix1tipZ18MYm1MpCAAzFhZFXsOU+/FK295/tvIJ3g6ehgU7cHRraiGQzbg==
5. 署名なしTokenと署名を . (ドット) で結合する
eyJhbGciOiAiUlMyNTYiLCAidHlwIjogIkpXVCJ9.eyJpc3MiOiJiYTY3M2ZhOTBiNjQ0YWU2OGI4MjliNzIxM2MxMjFkYiIsImlhdCI6IDE2MDkyNzQwMjcsICJleHAiOiAxNjA5Mjc1ODI3fQ==.W//2sawtLzg3GfH6GkeS1nw947ec5qiynl2pibztjVycpe73KcENXt6Z4aftfUgMEjHRvX3N8i754E9rBffI4gfarQzY+nhUVdxP9zFXSxr7YPXoPx9A9bL4bjNRvkKJV2BRLlJkOQ6g9TY1Uu5mtPsyTZ6zy2+hXa8h8tn0dSfsLF4uH0nOiEt6p44tNz6U8/0jUlPNd3tt3W7F4MZy038nMazYQ6g5e1W7tfgqCtV0NVQUGpZdKKh0HvWf8qiqE5cTJ6y+eREENZMAEjPY6rxx19PVix1tipZ18MYm1MpCAAzFhZFXsOU+/FK295/tvIJ3g6ehgU7cHRraiGQzbg==
これで完成である。
上記をまとめると、以下のようになる。
$ header=`echo -n '{"alg":"RS256","typ":"JWT"}' | base64` $ claim=`echo -n '{"iss":"ba673fa90b644ae68b829b7213c121db","iat": 1609274027, "exp": 1609275827}' | base64` $ signature=`echo -n $header.$payload | openssl dgst -sha256 -sign private_20201229171641.key -binary | base64` $ echo $header.$claim.$signature
この処理を簡単に実装できるのが、pyjwt
というライブラリである。
とても使いやすく、わかりやすかった。本当に感謝である。
(おまけ)Power Automate の設定
とても簡単に連携の設定ができたので、こんなこともできるのかと、誰かの参考になれば嬉しい。
今回は、カレンダーに入っている予定の内「打ち合わせ」をタイトルに含んでいた場合は、その予定表のリンクを LINE BOT に通知してもらうようにした。ノーコードで細かく色々と設定できるのは本当に使いやすいと思えた。設定に関しては、言葉で説明するより、実際に画面をみてもらう方が早いと思うので、参考までに共有しておく。(「予定しているイベントが間もなく開始されるとき (V3)」というトリガーのお陰で、本当に簡単に実装することができた。)
まとめ
今回は、LINE WORKS の BOT の API を試してみた。JWT でのToken リクエストに関しても、理解を深めることができた。
それでは、ステキな開発ライフを。