mcommit's message

ソフトウェア開発の仕事をしているsimotinといいます。記事の内容でご質問やご意見がありましたらお気軽にコメントしてください\^o^/

Google Calendar API Rubyでイベントを登録する

Google Calendar APIを使ってカレンダーにイベントを登録するコードを書きました。

APIのドキュメントを読みながら作りましたが思ったようにうまくいかなくて時間がかかったのであげておきたいと思います。

■目次

準備

GoogleAPIを使うにはGoogle Developer ConsoleでAPIを使うための設定が必要になります。
こうしてみると、GoogleのサービスのほとんどでAPIが提供されていることがよく分かりますね。
ちなみに、APIによっては使用量が一定量を超えると有料になるAPIもあるので注意が必要です。
※calendar APIでは特にそういった制限はないようですが。
f:id:simotin13:20160418181356j:plain

google developer consoleにログインして、GoogleCalendar APIの使用を有効化し、認証設定を作成します。
f:id:simotin13:20160418181418j:plain


APIを呼び出す際に必要になるので認証情報が書かれたJSONファイルもダウンロードしておきます。
f:id:simotin13:20160418181612j:plain

注意事項

認証で使う情報やカレンダーのID等は他人に知られないようにしておく必要があります。

API呼び出しの流れ

Googleが提供するAPIの呼び出しの流れは、大きく

  1. 認証
  2. API呼び出し

の2フェーズがあります。

最初にdeveloper consoleでいろいろ準備したのは1.の認証のために必要な準備といっていいでしょう。

rubyAPIを呼び出す

今回、私はRubyAPIを呼び出したかったのですが、Googleが認証やAPI呼び出し用のライブラリを提供してくれています。

認証で使うライブラリ

認証処理のライブラリとしてはこちらのライブラリが提供されていました。
github.com

レポジトリの説明に書いてありますが、


$ gem install googleauth1


require 'googleauth'

で使えるようになります。

今回は私はサンプルコードの
https://github.com/google/google-auth-library-ruby#example-command-line

を参考にさせて頂きました。

準備段階でダウンロードした認証情報が書かれたJSONを手元において、とりあえずこのサンプルを動かしてみると、認証のイメージがなんとなく理解できました。
※こちらのサンプルコードはあくまで認証処理までですので、実際のAPIの呼び出しは別のマニュアルやサンプルを確認する必要があります。

API呼び出しのサンプル

Google APIのクライアント用ライブラリは

github.com

こちらにあります。

Basic Usageでは、ローカルのファイルをアップロードしてダウンロードするという機能のサンプルになっています。
GitHub - google/google-api-ruby-client


drive.authorization = ... # See Googleauth or Signet libraries

と書いてある通り、認証の処理は認証のライブラリを参考にしてねということで、この繋がりを理解するのに(というよりコードを実装するのに)時間がかかりました。

私がやりたかったのは

Googleカレンダーの任意の日に任意のイベントを登録したい!

というものでしたが、いろいろ調べた結果以下のようなコードで実現できました。
同じようなことをされようとしている方の参考になれば幸いです。

require 'googleauth'
require 'googleauth/stores/file_token_store'
require 'google/api_client/client_secrets'
require 'google/apis/calendar_v3'

class GCalAPI
  APPLICATION_NAME = 'hogehoge-app'
  USER_ID = 'googleのアカウント' # 例). hoge@gmail.com
  TIME_ZONE = 'Japan'

  # CalendarID
  GCAL_ID = '登録したいカレンダーのID'
  # callback URL
  OOB_URI = 'urn:ietf:wg:oauth:2.0:oob'

  # 事前認証
  class << self
    def authorize
      dir_path = File.dirname(__FILE__)
      client_id = Google::Auth::ClientId.from_file("#{dir_path}/client_secrets.json")
      token_store = Google::Auth::Stores::FileTokenStore.new(
        file: "#{dir_path}/tokens.yaml")
      scope = 'https://www.googleapis.com/auth/calendar'
      authorizer = Google::Auth::UserAuthorizer.new(client_id, scope, token_store)
      credentials = authorizer.get_credentials(USER_ID)
      if credentials.nil?
        raise "credentials is none..."
      end
      credentials
    end

    # Google Calendar への登録
    def insert_gcal_event(gcal_type, evt_start, evt_end, summary, description, location)
      service = Google::Apis::CalendarV3::CalendarService.new
      service.client_options.application_name = APPLICATION_NAME
      service.authorization = self.authorize

      # 登録するイベント内容
      h_tmp = {
        summary: summary,
        description: description,
        location: location,
        start: {
          date_time: evt_start.iso8601,
          time_zone: TIME_ZONE
        },
        end: {
          date_time: evt_end.iso8601,
          time_zone: TIME_ZONE 
        }
      }

      event = Google::Apis::CalendarV3::Event.new(h_tmp)
      service.insert_event(GCAL_ID, event)
    end
  end
end

補足

コード中に、GCAL_IDという定数がありますが、これはイベントを登録したいカレンダーのIDになります。
googleカレンダーを開いて、左側に出てくる"マイカレンダー"から、"カレンダー設定"を押して表示されるページに記載されています。
「カレンダーのアドレス」という項目のところですね。


登録する内容については、今回私はシンプルにイベントの

  • 開始時間
  • 終了時間
  • 見出し
  • 説明
  • 場所

のみを登録できるようにしてみましたが、リマインダーの設定や繰り返しなど、細かく色々な情報を登録できるようになっています。
APIの仕様については、こちら

developers.google.com

で確認することができます。

認証ライブラリの不具合修正

どうも認証のライブラリに不具合があるみたいです。
環境によって発生したり、しなかったりがあると思いますが、

github.com

こちらにかかれている通り、パッチを当てれば解決できます。
/signet-0.7.2/lib/signet/oauth_2/client.rbの


when Fixnum

when Fixnum, Bignum

にすればよいみたいです。
Timeオブジェクトを数値化した時に32bitに収まらない場合があるという(というか32bit以上になることを想定していない)のが原因みたいですね。

感想

  • 最近、APIがバージョンアップされたらしく色々な情報があって混乱しました。
  • 認証方法も、今回使ったライブラリを使湧ないやり方での認証があったり、いろいろなやり方があってどれが正しいのかよく分かりませんでした。
  • 提供されているrubyのライブラリやサンプルコードはところどころ間違っているところがあって100%信じてはダメだなという感じでした。

最近、サービスのAPI呼び出しのコードばっかり書いている気がするなぁ。
ただ、一般のサービスと自前のサービスを統合することによって作業効率が上がったりするので、こういうコードを書くというのにはニーズもあり喜んでもらえることなのであまり不満はないですが。

いろんなAPIが提供されているのをみると、「このAPIとこのAPIを組み合わせればこんなこともできるなぁ~」というパズルで遊ぶような感覚もあるのでそういう意味でもまぁなんというか悪くはないですね。


今回はRubyでイベントを登録するコードを書いたのですが、.Net(C#)でもカレンダーAPIを呼び出すコードをかかないといけない。
今回いろいろと調査してノウハウもたまったので.Netの方のコードを書くときはもう少しすんなりいくはずだ。