Node.js
googleapi

チャットでGoogle Calendarを使ってみるの巻

記念すべき初投稿(備忘録)なのにこんな内容でいいのだろうか…

1. 何故作った…

仕事の合間に、なんとなく「チャットアプリでGoogle Calendarを操作できないかね」と言われる。

1-1. 何故REST API

GCMは苦手で、ちょうどAzure Functionを触っていたのでその延長で。

1-2. どんなものを作ろうとした?

テキストを自然言語分析 → Functionで分けてGoogle Calendar APIのメソッドを実行
→ チャットに結果を表示

2. 大まかな構成

2-1. Google APIs

まずAPIを有効化し、サービスアカウントを作ることでここで使うprivatekeyを作ります。

スクリーンショット 2017-11-06 18.31.41.png

ここでGoogle Calendar APIを選択し、有効化することで、既存のプロジェクトや新しいプロジェクトでAPIが使用可能になります。

スクリーンショット 2017-11-06 18.38.57.png

コンソールで認証可能な場合、OAuthキーの発行 → その他を選ベば、google-auth-libraryで使う client_secret.jsonを発行できます。今回はコンソールで打ち込むのは無理なのでサービスアカウント作成へ。
作成が済めば、自動的にトークンなどが記入されているjsonファイルがダウンロードされるのでprivatekey.jsonに命名。
アップロードしておきましょう。

2-2. Azure Function

Web App自体はなんでもいいです。筆者、プログラミング初年度でNode.jsの基礎くらいしかわかっておらぬ状態。
Google Apisは Firebaseを推奨していますが、今回Azureのサンプルを流用するため、こちらに。
今後サンプル作成するならデプロイまで簡単なGCMがおすすめ。

ともかく、Example通り作ろうとしたら、google-auth-libraryとやらで認証しなければならない
が、これはコンソールでトークンを打ち返す必要があり、相互作用できない(筆者の能力不足かもですが)Function APPや組み込み済みのアプリケーションのために用意されたJWTを使用。

NPMに用意されているgoogleapisモジュールをインポートし、最初の認証を。

Functionのindex.js
let jwtClient = new google.auth.JWT(
  privatekey.client_email,
  null,
  SCOPES: ['https://www.googleapis.com/auth/calendar.readonly'],
  null
); 

jwtClient.authorize(function (err, tokens) {
  if(err) { 
    console.log("auth err: " + err);
    return;
  } else { 
    console.log("auth done"); 
    {APIsに用意されているメソッド)
  }
});    

JWT(Json Web Token)は、OAuth2などで用意したプライベートキーを持って認証元とやりとりを行う役割。
詳しくは、こちらを参照
JWT(JSON Web Token)を使った認証を試みる
Using OAuth 2.0 for Server to Server Applications

そして、メソッドは APIs Explorer で指定している値をJSONで渡せます。

Sample_Method.js
function listEvents(auth) {
  console.log("listing Events");
  var calendar = google.calendar('v3');

  calendar.events.list({
    auth: auth,
    calendarId: {カレンダーのID},
    timeMin: (new Date()).toISOString(),
    maxResults: 10,
    singleEvents: true,
    orderBy: 'startTime'
  }, function(err, response) {
    if (err) {
      console.log(err);
      return;
    } else {
      var events = response.items;
      if (events.length == 0) {
        console.log('No upcoming events found.');
      } else {
        async.each(events, (i, next) => {
          var event = i;
          var startTime = event.start.dateTime.slice(11,-6);
          var startMsec = new Date(event.start.dateTime).getTime();
          var endTime = event.end.dateTime.slice(11,-6);
          var endMsec = new Date(event.end.dateTime).getTime();
          var during = ((endMsec - startMsec)/60000) + " MIN";
          var start = event.start.dateTime || event.start.date;
          var eventId = event.id;
          console.log('%s (%s) - %s (%s)', startTime, during, event.summary, eventId);
        }, (err) => {
           if(err) throw err;
        });
      }
    }
  });
}

2-3. Google Calendar

・古いUI

スクリーンショット 2017-11-06 18.55.47.png

・新しいUI
スクリーンショット 2017-11-06 18.56.05.png

カレンダーIDは、カレンダーの設定で確認してください。

権限は、calendar.events.listなどは閲覧までで、insertなどを行うためにはwriter以上の権限が必要です。
スクリーンショット 2017-11-06 18.57.42.png

SCOPEもreadonlyを外す必要があります。何度か変更し忘れたので注意。

3. 感想

わざわざチャットでカレンダーを使うなんて、なかなかないなーと思いつつ、Google APIsの勉強になったとは思いました。以上。