AngularからGoogle Calendar APIでイベントを登録する
はじめに
この記事のソースコードは下記のバージョンで構成されています。
- Angular: v12.1.3
参照されるタイミングによっては動作しない可能性がありますのでご留意ください。
やりたいこと
Front(Angular)のみで、任意のユーザーにサインインさせ、サインインしたユーザーのカレンダーに、Google Calendar APIを使用してイベント登録を行いたい。
想像以上にやり方が複雑怪奇な感じになったのでメモ書き程度に残しておきます。
GCPでGoogle Calendar APIを使用するための準備
Google Calendar APIを有効にする
認証の設定
「認証情報を作成」から「OAuthクライアントID」を選択します
設定対象 | 設定内容 |
---|---|
アプリケーションの種類 | ウェブアプリケーション |
名前 | 任意 |
承認済みのJavaScript生成元 | http://localhost:4200 |
承認済みのリダイレクトURL | http://localhost:4200 |
OAuth同意画面(スコープ)の設定
「OAuth同意画面」の設定の入力項目はほぼ任意な内容です。
「スコープを追加または削除」から必要なスコープを追加します。
必要なスコープはドキュメントを参考にします。今回はカレンダーにイベントを追加したいという目的です。
必要な処理は下記の通りなので、それぞれの処理で必要なスコープを確認しましょう。
- カレンダーのリストの取得
- 1.で取得したいずれかのカレンダーにイベントを登録
上記のドキュメントから必要なスコープは下記の通りでした
Angular側の実装
index.htmlの変更
GCPのAPIをどうこうするのに使用するライブラリなんかはnpmなどで配布されていないように見受けられました。
ひとまずここは公式のドキュメント通りにスクリプトファイルをindex.htmlで読み込みます。
<!doctype html> <html lang="jp"> <head> <script defer src="https://apis.google.com/js/api.js"></script> <!--追加--> <meta charset="utf-8"> <title>LearnGoogleOAuth</title> <base href="/"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="icon" type="image/x-icon" href="favicon.ico"> </head> <body> <app-root></app-root> </body> </html>
各種@typesをインストール
とはいえTypeScriptな型の世界で開発を行いたいので、型定義をインストールします。
npm install --save-dev @types/gapi @types/gapi.auth2 @types/gapi.calendar
今回使用するGAPIのベース、認証、カレンダーAPIの型定義です。
型定義を使用したいファイル内で定義を読み込んでおきましょう
/// <reference types="gapi"/> /// <reference types="gapi.auth2"/> /// <reference types="gapi.calendar"/>
GAPIのLoad処理
GAPIのAuthやCalendarといったインスタンスはgapi
のload
やinit
で生成されるようです。
それぞれのインスタンスをLoadする処理を実装します。
export class AppSerivce { ... private authClient!: gapi.auth2.GoogleAuth; clientLoad(): void { // gapi.authインスタンスを使用できるようにロードする(scopeはOAuthの同意画面で設定したScopeを指定) gapi.load('client:auth2', () => { this.authClient = gapi.auth2.init({ client_id: environment.gapiClientId, fetch_basic_profile: true, scope: 'openid https://www.googleapis.com/auth/calendar.readonly https://www.googleapis.com/auth/calendar.events ', }); // gapi.client.calendarを使用できるようにロードする gapi.client.init({ discoveryDocs: ['https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest'] }) }); } ... }
サインイン
上記でgapi.auth
インスタンスの準備ができている場合は下記のコマンドでサインインが実行できます。
async signIn(): Promise<void> { const res = await this.authClient.signIn(); }
カレンダーリストの取得
上記でgapi.client.calendar
インスタンスの準備ができている場合は下記のコマンドでカレンダーリストの取得ができます。
getCalendarList() { // gapi.client.calendarインスタンスが生成されていると使用できる const req = gapi.client.calendar.calendarList.list() req.execute((res) => { // resにカレンダー情報が返却される }) }
イベントの登録
上記でgapi.client.calendar
インスタンスの準備ができている場合は下記のコマンドでイベントの登録が行えます。
イベント登録時に使用できるパラメータはドキュメントを参考にしてください。
registerEvents(calendarId: string): void { const event: gapi.client.calendar.EventInput = { summary: 'Test', start: { dateTime: '2021-07-31T00:00:00.000Z' }, end: { dateTime: '2021-07-31T00:00:00.000Z' } }; const req = gapi.client.calendar.events.insert({ calendarId, resource: event }); req.execute((res) => { // 結果がresに返却される console.log(res) }); } }
結果、下図のように登録を行えるようになりました。
gapi.cllient.calendar
インスタンスを生成しないやりかた
gapi.client.calendar
を介さずに、clientからリクエスト直接叩くことでもイベント登録は可能です。
registerEvents(calendarId: string): void { const event: gapi.client.calendar.EventInput = { summary: 'Test', start: { dateTime: '2021-07-31T00:00:00.000Z' }, end: { dateTime: '2021-07-31T00:00:00.000Z' } }; const req = gapi.client.request({ path: `/calendar/v3/calendars/${calendarId}/events`, method: 'POST', body: event }); req.execute((res) => { // 結果がresに返却される console.log(res) }); } }
APIに対応するインスタンスの生成ができなかった場合や、インスタンス内にインターフェースがなかった場合なんかはこっちの方法になりますね。
サクッと検証したい場合もこっちのほうが楽だったりするかもしれません。
さいごに
APIに対応するインスタンスのLoadなど変わった実装が必要なので最初は面食らいました。
見たのはカレンダーだけですが他の@typesとか見るに、Googleが提供するOAuthを伴うWebAPIの実行は同じような実装でできそう?という印象です。
今回検証で実装した全体は下記のリポジトリに格納しました。