Google Calendar API はまりどころ
公式ドキュメント
まずは公式のドキュメントを見ながら進めていきます。
Develop on Google Workspace | Google Workspace for Developers | Google Developers
などを色々読み進めていって
Create access credentials | Google Workspace for Developers | Google Developers
credentials.json
のファイルをダウンロードしないといけないみたいです。
Calendar APIを有効にします。
ナビゲーションメニュー > APIとサービス > 認証情報
をクリック
認証情報を作成をクリック
「OAuth 2.0 クライアント ID 」を選択
「デスクトップクライアント」を選択
公式ドキュメントの選択肢にWEBがなく「デスクトップクライアント」しかないので選択
WEBなのになぜ?って戸惑わせるところがハマりどころのポイントでもあるかと思います。
後述のOauthでログインでまんまとハマってしまいこの時はWEBの選択がなかったのに対してOauthログインではWEBを選択しないと動かないって仕様です。
なかなか困らせる公式ドキュメントです。
ちなみに今回のCalendarAPIに関してはWEBでもできるしデスクトップクライアントでも動きました。
サービスがいいんだか悪いんだか。。
作成後にjsonをダウンロード
サンプルで動かしてみるも
次はサンプルを用いて、実際にカレンダーの情報が取得できるのか試してみます。
Go quickstart | Google Calendar API | Google Developers
Goを使うのでGoのサンプルで試す。
前提条件でGOの最新推奨と、Googleのライブラリのインストールが必要
環境を揃えて、サンプルコードをコピペ
ダウンロードしたjsonを実装したGo言語に取り入れてテスト
しかし、サンプルのコードが動かない
Jsonファイルが間違っていると思っていて、どのjsonをダウンロードしないといけないのかで約半日はすぎました。。
エラー内容は
Unable to parse client secret file to config: oauth2/google: no credentials found
このエラーでググっても、スコープが足りないだので路頭に迷いました。
Google APIのページを巡回、回り回っても解決できず、1日が終わりました。
Googleのドキュメント通りに進めて、実行してなぜ動かない!?
間違えたサンプルを公式のドキュメントに記載したままにしてる!?
答えがでず焦ってました。
PHPで動かしてみる
Google Calendar APIを使用してみる #1 - Qiita
のページを見る限り Javascriptであればすんなり上手くいってるようなので、試しにPHPでサンプルを動かしてみた。
なんと動いた!?
しっかり、カレンダー内のスケジュールここでいうeventが取得できました。
じゃぁ、Goのサンプルが悪い!?
って事になります。
何度か繰り返してもやはり同じクレデンシャルでPHPではOKでGoでは無理
PHPとの違いを調査
手順を比べてみたら、Goの場合はドキュメントのサンプルを使っているのに対して
PHPはGithubのサンプルコードで動かしています。
ではGoも同じくGithubのサンプルコードで試しました。
するとGmailのAPIを有効化してくれとのメッセージが
PHPでは聞かれなかったのに。。
と思いながら、言われるがままGmailを有効化
もう一度、実行すると
データが取れた!?
と思いきやGmailのデータを取得???
あれれ?
よく見るとGmailのサンプルじゃありませんか?
なぜかGmailのサンプルに誘導されてたので、github上でcalendarのサンプルを探します。
改めてGoサンプルで挑戦
見つけて、そのサンプルを実行。
実行すると以下のメッセージが表示されるのでメッセージに従いコピーしてURLに直接アクセスします
Go to the following link in your browser then type the authorization code: https://accounts.google.com/o/oauth2/auth?access_type=offline&client_id=53479****-aqic9roil***14fkj7rvun4rara1.apps.googleusercontent.com&redirect_uri=https%3A%2F%2Fappoint.quigen.info%2FCalendarAuth2%2F&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar&state=state-token
アクセスするといわゆるOauthログインででてくるような同意画面が出てきます。
この画面から同意して自分自身のアカウントであるメールをクリックするとリダイレクトされます
特にリダイレクト先を登録していなければhttp://localhost/にいくつかの引数を引きずってリダイレクトされます。
http://localhost/?state=state-token&code=4%2F0A***PTLUHV8hUUWQ7wQ&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar
このcodeの引数のデータが今回は重要でこのコードをコピーします。
ちなみにlocalhostにWEBが立っているわけでもないので、この画面自体はエラーになっていますが、そこは今の時点で気にしなくてもいいかと思います
Go to the following link in your browser then type the authorization code:のコンソールに戻って先ほどコピーしたコードを貼り付けてエンタを押します
n: 400 Bad Request
Response: {
"error": "invalid_grant",
"error_description": "Malformed auth code."
}
exit status 1
のエラーがでてしまいました。
ググって検索するとURLがエンコードされているデータなので、URLデコードしてあげてもう一回試します
リフレッシュトークンが消えた
何回かcalendar oauthのテストをしていてきづいた所がトークンの期限が切れてしまうところ
あれ??
https://t.co/ZqYP9p1D4I
— なんでもやるフルスタックエンジニア (@komikoma) August 10, 2022
これを見る限りちょっとやそっとのことで期限が切れないみたいだけども、、かなり心配💦
ここでもつぶやいた通り期限って無期限じゃなかったはず?
トークンを改めて確認するとリフレッシュトークンがない
前見たときはあったのになぜ今ない?
スクトップアプリとしてのクレデンシャルのJSONをダウンロードしたからと思い新たにデスクトップアプリとしてJSONをダウンロード
して、そのクレデンシャルを元にトークンを生成
フレッシュトークンはありました
Bアプリだとリフレッシュトークンは生成されない?
ant_typeに付与? access_typeがofflineの他に何かあるのか?
ど色々調べましたが、どれも上手くいかない
なみに、access_typeはoffline, onlineと2種類あるらしくofflineが期限が長いとの事なので、現時点の設定はあってます
こで見つけたのがこのリンク
めの同意のみにリフレッシュトークンが付与されて、それ以降はアクセストークンのみだそう。。
たトリッキーな仕様
証情報を作り直して試してリフレッシュトークンがあることを確認できました
見事動いた
見事スケジュール情報が取得できました✨
とほほ。
次に以前Googleカレンダーの公開方法で設定したIDを取得したいと思います。
そのIDをコードに入れて取得できるか試してみます。
srv.Events.List("primary").ShowDeleted(false).
SingleEvents(true).TimeMin(t).MaxResults(10).OrderBy("startTime").Do()
このコードのprimaryの部分にIDを入力するみたいです。
すんなり、スケジュール取得できました。
このコードのGoのこの書き方って何?ってなりました。
他にGoのドキュメント見てもこんな書き方してる所がなかったので
関数を数珠つなぎにしてる!!
???
ってなったけども、たぶん戻り値を左から右に渡しているのだろうって感じだけって事にしておきます。
あとでゆっくり、勉強がてらに作ってみます。
今はこういうドットで関数を繋ぐ方法を何て呼ぶのかすらわかりません。
誰か知ってたら教えてください。
WEBアプリに組み込む
今まではただサンプルを自分が作ったクレデンシャルで動かしただけなので、WEBアプリに組み込んでみます
とりあえずはできあがりのサンプル
公式のサンプルはファイルの読み込みなどもあって複雑なので、こちらの方が幾分簡単だと思います
ようやくするとCalendarAuth1でパラメータを渡して同意画面にリダイレクトされて同意したらCalendarAuth2にcodeのパラメータ付きでリダイレクトして戻ってくるという仕組み
このコードだけみるとなんてことない簡単なコードですが、ここまでたどり着くのが大変でした 😭
前提としてはGCP上でリダイレクト先を設定したクレデンシャルを利用しないといけないです
リダイレクトの設定は
APIとサービス ➡ 認証情報 ➡ OAuth 2.0 クライアント ID ➡ クレデンシャルの作成 ➡ アプリケーションの種類でウェブアプリケーションを選択 ➡ 承認済みのリダイレクト URI にリダイレクト先を設定 今回の場合は「https://appoint.quigen.info/CalendarAuth2/」 ➡ 保存してクレデンシャルのJSONダウンロードしてそれを利用
という手順注意点
1.どのタイプの認証情報を作成するのかで迷わされるし、やり方は色々あるみたいだけどもなかなか上手くOauth以外だと上手くいきませんでした
2.アプリケーションの種類でデスクトップにするとリダイレクト先が設定できない
ダウンロードしたJSONにlocalhostにリダイレクトされると記載があるので、それを自アプリのURLに書き直してトークン取得を試みるも
同意画面でredirect URI is mismatch
って出て何がいけないのかわかるのに時間がかかりました
画像を張ってわかりやすく説明しようと思ったけどもGCPってUIすぐ変わってしまうので、画像張ったところで費用対効果ないのかなぁって思い諦めました
登録日:
更新日: