らいふうっどの閑話休題

興味のあることをゆる~く書いていく

Integrating Google APIs with Angular の翻訳

Angular In DepthIntegrating Google APIs with Angular の翻訳です。

f:id:ic_lifewood:20200103001443p:plain

💡動機

タスク:プライベート Google カレンダーのイベントにアクセス/表示する必要があります。
問題:プライベートカレンダーを iframe に入れたり、 API キーだけを使用してそのイベントをクエリしたりすることはできません。 要件:Angularと互換性があり、 TypeScript サポート(サービスラッパー/クラスおよびデータモデルタイプ)
解決策:必要なものすべてを提供する google-api-nodejs-client があります

Google APIにアクセスするためにGoogleが公式にサポートしているNode.jsクライアントライブラリ。 OAuth 2.0、APIキー、およびJWTによる承認と認証のサポートが含まれています。

次に Node.js パーツを Angular に置き換える方法を見つけます。

🛠️統合

残念ながら、このライブラリは NodeJS 用であり、"Webpackビルドアプリ" に統合する際にわずかな問題があり、ブラウザには NodeJS の一部に依存するため、 Angular が含まれます。 回避策があります(ここで説明します)ので、私たちを止めることはできません。

まず、 Webpack ビルドを拡張する必要があります。

$ npm i -D @angular-builders/custom-webpack

次に、 angular.json プロジェクトアーキテクト構成ファイルのビルダーを置き換える必要があります。また、オプションにカスタム Webpack 構成へのパスを含めます。

"architect": {
  "build": {
    "builder": "@angular-builders/custom-webpack:browser",
    "options": {
      "customWebpackConfig": {
        "path": "./extra-webpack.config.js"
      },
      ...
    },
    ...
  },
  "serve": {
    "builder": "@angular-builders/custom-webpack:dev-server",
    ...
  },
}

説明は、 Angular のビルダードキュメントにあります。

🔨“ハック”

さて、実際の「ハック」とは何ですか? この NodeJS ライブラリに必要なこれらすべてのことをブラウザーに存在するように振る舞います。

  1. グローバルやバッファーなどの NodeJS ランタイム内部の一部をシミュレートします。
  2. ランタイム fschild_processhttps-proxy-agent などいくつかライブラリのモックが必要です。

global および Buffer のフォールバックを提供する

src/polyfills.ts のアプリケーションインポートの下に次のポリフィルを追加します。

import * as process from 'process';
(window as any).process = process;

import { Buffer } from 'buffer';
(window as any).Buffer = Buffer;

パッケージ npm i -D process buffer インストールすることを忘れないでください。

これを index.html <head> タグに追加します。 global にアクセスすることに関連するエラーは、 window で置き換えられるため、削除されます。

<script>
  if (global === undefined) {
    var global = window;
  }
</script>

ライブラリのモック

const path = require('path');module.exports = {
  resolve: {
    extensions: ['.js'],
    alias: {
      fs: path.resolve(__dirname, 'src/mocks/fs.mock.js'),
      child_process: path.resolve(
        __dirname,
        'src/mocks/child_process.mock.js'
      ),
      'https-proxy-agent': path.resolve(
        __dirname,
        'src/mocks/https-proxy-agent.mock.js',
      ),
    },
  },
};

何が起こっているのかという説明は、あるインポート(ファイル)を別のインポート(ファイル)に置き換えるようWebPackに指示しているということです。
すべての “mock” ファイルを src/mock に配置しているので、プロジェクトで作業している同僚にとってこれらのファイルが何であるかを簡単に理解できます。

これらのモック内のコードはかなり単純です。 使用されるが必須ではないメソッドをいくつか追加するまで、何も「実行」しません。
fschild_process は両方ともこのようになります。

module.exports = {
  readFileSync() {},
  readFile() {},
};

https-proxy-agent はさらに単純で、 module.exports = {}; のみです。

🔑アクセスの設定

  1. 新しい GCP プロジェクトを作成するか、既存の GCP プロジェクトを使用します。
  2. GCP コンソールでプロジェクトを選択し、[ライブラリ]タブに移動して、使用するAPIを有効にします(この場合は Google カレンダーと分析)
  3. OAuth 同意画面のカスタマイズ(名前、制限など)
    • 必要な Scopes for Google APIs を設定します(カレンダー、分析など)
  4. OAuth 認証情報を作成する
    • プライベートデータ(カレンダーイベントや分析など)にアクセスする場合に必要
  5. 認証に進み、公開および秘密の OAuth キーを使用します

🔓認証

API キーを使用すると、 API から簡単に多くの公開データにアクセスできます。 パブリックカレンダーのようなものですが、プライベートデータ(プライベートカレンダーなど)が必要な場合は、認証する必要があります。 これは、 OAuth クライアントを介して実行できます。

app.module.ts 内のプロバイダー配列で GoogleOAuth2Client を提供します。 次のようになります。

{
  provide: OAuth2Client,
  useValue: new OAuth2Client( // You get this in GCP project credentials
    environment.G_API_CLIENT_ID,
    environment.G_API_CLIENT_SECRET, // URL where you'll handle succesful authentication
    environment.G_API_REDIRECT,),
},

リダイレクトベースの認証を使用するため、次は認証 URL を生成します。

window.location.href = this.oauth2Client.generateAuthUrl({

  // 'offline' also gets refresh_token  
  access_type: 'offline',// put any scopes you need there, 

  scope: [
    // in the first example we want to read calendar events
    'https://www.googleapis.com/auth/calendar.events.readonly',
    'https://www.googleapis.com/auth/calendar.readonly',

    // in the second example we read analytics data
    'https://www.googleapis.com/auth/analytics.readonly',
  ],
});

refresh_token のおかげで、OAuthClient はトークンの有効期限が切れた後でもトークン交換を処理できるようになるため、トークンの有効期限が切れてから1時間ごとに Google の認証画面を表示する必要がなくなります。

️⌨️使用例

ドキュメントを探索したい場合は、google-apis docs にアクセスするか、以下の例で使用されているカレンダーをご覧ください。

📅Calendar Service SDKの使用

Permissions

使用しているアカウントが、イベントを読み取りたいカレンダーにアクセスできることを確認してください。

コードサンプル

Calendar クラスにデフォルトの認証メソッドを提供します。この場合は OAuth です。
これで app.module.ts 内のプロバイダー配列を拡張します。

{
  provide: calendar_v3.Calendar,
  useFactory: 
    (auth: OAuth2Client) => new calendar_v3.Calendar({ auth }),
  deps: [OAuth2Client],
},

これで、完全に型指定された SDK インターフェイスを使用して、 Google カレンダー API 機能の完全なセットにアクセスできます。
他の Angular サービスと同じようにカレンダーを取得し、コンストラクターパラメーターとして使用すると、依存関係の注入によってカレンダーが提供されます。

constructor(
  private calendar: calendar_v3.Calendar,
) {}

特定のカレンダーのイベントのリストを取得する方法の例を次に示します。
また、「今日」で削除/キャンセルされていないイベントのみをフィルタリングします。

this.calendar.events.list({
  // required, it is an email, or email like id of a calendar
  calendarId: CALENDAR_ID,

// optional, arguments that let you filter/specify wanted events
  timeMin: startOfDay(today).toISOString(),
  timeMax: endOfDay(today).toISOString(),
  showDeleted: false,
  singleEvents: true,
}),

イベントの作成などの他のタスクを実行することもできますが、認証で適切な範囲の要求を忘れないでください。

📊Analytics SDKの使用

permissions の設定

⮕ Analytics Console ⮕ Admin ⮕ Account column ⮕ User Management ⮕
⮕ Select the user ⮕ Activate the "Read & Analyze" checkbox

"View ID" の取得

⮕ Analytics Console ⮕ Admin ⮕ View column ⮕ View Settings ⮕
⮕ Copy the "View ID" number

コードサンプル

前の例と同じように、プロバイダーが必要です。Analytics クラスにデフォルトの認証方法を提供します。 app.module.ts 内のプロバイダー配列を拡張します。

{
  provide: analytics_v3.Analytics,
  useFactory:
    (auth: OAuth2Client) => new analytics_v3.Analytics({ auth }),
  deps: [OAuth2Client],
},

繰り返しますが、 DI によって任意の注入可能クラスに注入する準備ができています。

constructor(
  private analytics: analytics_v3.Analytics,
) {}

この例では、目的の時間範囲の指定されたメトリックを取得します。 この場合、過去30日間の合計ページビューが表示されます。

this.analytics.data.ga.get({
  ids: 'ga:xxxxxxxxx', // replace xxxxxxxxx with your view ID
  'start-date': '30daysAgo',
  'end-date': 'today',
  metrics: 'ga:pageviews',
})

📋まとめ

API の完全に型指定された SDK を持つことは、ドキュメント、特にデータモデルですべてを見つける必要があることと比較して大きな違いです。 問題の Auth の部分も非常に便利に処理されるため、その方法がわからない、またはそれを管理したくない人のためのショーストッパーではありません。 全体として、プロジェクト環境とツールを適切に設定すると、機能を作成するのがはるかに簡単になります。

・・・・・・

詳細や更新情報については、こちらまたは Twitter でフォローしてください。 質問がある場合は、お気軽にご連絡ください。

medium.com