はじめに
NeoMuttからGmailを使うには、OAuth2.0による認可が必要。
Neomuttの設定ファイルでOAuth2.0の「アクセストークン」を更新するコマンドを指定すればいいらしい。
そこで、使えるコマンドを探してみたら、下のPythonのスクリプトを見つけた。
だけれども、今後しばらく使うであろうメール環境。
わざわざPythonに依存したくない。保守したくない。
それなら作ろうシェルスクリプト。
ということで、Google APIで利用するOAuth2.0の「アクセストークン」と
「リフレッシュトークン」を取得、更新するシェルスクリプトを作ってみたよ。
そもそもOAuth2.0とはなんぞやという人は下の記事を読んでみてね。
作るもの
以下の機能に対応する。
[USAGE] ggl-oauth2 -g [-b browser] [-nv] <Account-file> # 認可ページのURIを生成 ggl-oauth2 -i <token> | <Account-file> # 指定トークンに関する情報取得 ggl-oauth2 -n [-v] <Account-file> # 新規トークンの取得 ggl-oauth2 -r <token> | <Account-file> # 指定トークンを削除 ggl-oauth2 -u [-v] <Account-file> # 指定トークンの更新 ggl-oauth2 [-hV] # ヘルプ/バージョンの表示
ちなみに、curl
には依存しちゃうので、インストールしておいてね。
# FreeBSDの場合
$ sudo pkg install curl
事前準備
1.クライアントの登録
まず、対象のGoogleアカウントでOAuthを利用するアプリケーションをクライアントとして登録しておく必要がある。
下の記事を参照されたし。
2. アカウント情報ファイルの作成
登録が終わったら、今回のスクリプトで利用する以下のフォーマットの<Acount-file>
を用意する。
ファイル名は好きにしてね。
# OAuth2.0 Client setting SCOPE=https://mail.google.com/ CLIENT_ID=登録時に発行されたID CLIENT_SECRET=登録時に発行されたシークレット
ファイルのアクセス権は600
(自分以外読み書き不可)が好ましいかと。
$ chmod 600 "<Account-file>"
コード
今回のコードは長めなので抜粋で機能ごとに説明する。
今回のコード全体は下に置いた。
下のコマンドとかでローカルに落として下さいまし。
$ git clone https://github.com/hacolab/google-oauth2-sh.git
認可ページのURIを生成
-g
オプションで認可用のURIを生成する。
生成したURIはデフォルトだと標準出力に出力するだけ。
これをブラウザにコピペしてアクセスする感じ。
ブラウザでの認可の手順は以下を参考にされたし。
該当のコードは以下。
# Generate authorization-code if [ -n "$MODE_GENERATE_AUTH_URI" ]; then "$BROWSER_CMD" "${AUTH_END_POINT}?client_id=${CLIENT_ID}&scope=${SCOPE}&response_type=code&access_type=offline&redirect_uri=${REDIRECT_URI}" fi
-b <Browser>
オプションで指定したコマンドが$BROWSER_CMD
に入る。
${CLIENT_ID}
は事前準備で用意した<Account-file>
から読み取っている。
他の変数は、ソースの上の方で定義している。
新規トークンの取得
-n
オプションで、認可コードを入力待ち状態になる。
認可時に表示された認可コードを認可してReturnキーを押してねと。
入力された認可コードで「アクセストークン」と「リフレッシュトークン」を取得する。
該当のコードは以下。
# Get new access-token & refresh-token if [ -n "$MODE_AUTHORIZATION" ]; then printf "please input authorization-code: " read auth_code [ -z "$auth_code" ] && error_exit "not input authorization-code!" # get access-token & refresh-token curl -s --verbose \ -d grant_type=authorization_code \ -d client_id=$CLIENT_ID \ -d client_secret=$CLIENT_SECRET \ -d redirect_uri=$REDIRECT_URI \ -d code=$auth_code \ $TOKEN_END_POINT > "$HTTP_LOG" 2>&1 check_response "$HTTP_LOG" "authorization faild!" ACCESS_TOKEN=$(pickup_value access_token < "$HTTP_LOG") REFRESH_TOKEN=$(pickup_value refresh_token < "$HTTP_LOG") write_config "$ACCOUNT_FILE" REFRESH_TOKEN "$REFRESH_TOKEN" fi
正しい認可コードが確認できてら、「アクセストークン」を標準出力に出力し、
「リフレッシュトークン」を<Account-file>
に追記・更新する。
-v
オプションを指定すれば、curl
コマンドのログと「リフレッシュトークン」も標準出力に出力する。
elif [ -n "$VERBOSE_LOG" ]; then # Print infomation [ -f "$HTTP_LOG" ] && cat "$HTTP_LOG" | grep ^ echo "access_token: $ACCESS_TOKEN" echo "refresh_token: $REFRESH_TOKEN"
トークンの更新
-u
オプションで、新しい「アクセストークン」を取得できる。
該当のコードは以下。
# Update access-token if [ -n "$MODE_UPDATE_TOKEN" ]; then curl -s --verbose \ -d grant_type=refresh_token \ -d client_id=$CLIENT_ID \ -d client_secret=$CLIENT_SECRET \ -d refresh_token=$REFRESH_TOKEN \ $TOKEN_END_POINT > "$HTTP_LOG" 2>&1 check_response "$HTTP_LOG" "access_token update faild!" ACCESS_TOKEN=$(pickup_value access_token < "$HTTP_LOG") fi
-v
オプション指定時はcurl
のログと「リフレッシュトークン」を標準出力に出力する。
取得済トークンに関する情報取得
-i
オプションで、指定の「アクセストークン」の情報を取得できる。
引数には「アクセストークン」を指定するか、<Account-file>
を指定する。
該当のコードは以下。
if [ -n "$MODE_INQUIRE_SCOPE" ]; then # Inquire infomation curl -s "https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=${ACCESS_TOKEN}" \ | grep "^"
grep
をつけているのは、出力に改行をつけるため。
出力は以下みたいな感じ。
返ってきたHTTPレスポンスのJSONをそのまま出力。
{ "issued_to": "123456789012-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com", "audience": "123456789012-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com", "scope": "https://mail.google.com/", "expires_in": 2466, "access_type": "offline" }
現在のトークンを削除
-r
オプションで、指定の「アクセストークン」と、それに紐付けられた「リフレッシュトークン」を削除する。
引数には「アクセストークン」か<Account-file>
を指定する。
該当のコードは以下。
elif [ -n "$MODE_REVOKE_TOKEN" ]; then # Revoke access-token & refresh-token curl -s "https://accounts.google.com/o/oauth2/revoke?token=${ACCESS_TOKEN}" \ | grep "^"
grep
をつけているのは、出力に改行をつけるため。
削除成功後は同じトークンを使えないため、ブラウザによる認可作業から行う必要がある。
さいごに
長くなったので今回はここまで。
ちょっと変数を増やしすぎたのは反省点ではあるけれども、ま、いっか。
そして、POSIXには無いsed
の-i
オプションを使ってしまっていることに気付く。。。
気が向いた時にこっそり直そう。
ちなみに下のように認可エンドポイントのURIにバージョン(v2)が含まれているっぽいけど、
どのバージョンを使うべきなのかよく分からんとです。
ご存知の方がいらっしゃいましたら、コメント頂けると助かります。
AUTH_END_POINT=https://accounts.google.com/o/oauth2/v2/auth
さて次回は、このスクリプトを利用するサンプルスクリプトを作ってみよう。
以上。
確認環境
PC | Thinkpad X1 Carbon 2nd Gen |
OS | FreeBSD 12.1-RELEASE-p8 |