LoginSignup
11
1

More than 5 years have passed since last update.

Google Calendar APIでイベントのidを独自に生成して登録する

Last updated at Posted at 2016-11-29

Google Calendarでスケジュール登録するときの問題

GoogleCalendarAPIでは、イベントを登録すると各イベントごとにユニークなidが自動生成されます。(以下イベントidと呼びます)ただし、これだと登録したあとに一度取得しないと登録したイベントidがわからなかったり、複数人で同じイベントを共有する場合に、それぞれでイベントidが違うので、イベント情報が更新された場合など、一括で更新するのが非常にめんどうです。

これらの問題を解決するために、イベント登録時に独自に生成したidを使う手法を取りたいと思います。
rubyでのコードがほぼなかったので、以下に紹介しておきます。

Google Calendarのイベントidのルール

Google CalendarのAPIドキュメントによると、イベントidは以下のルールに従う必要があります。

Opaque identifier of the event. When creating new single or recurring events, you can specify their IDs. Provided IDs must follow these rules:
characters allowed in the ID are those used in base32hex encoding, i.e. lowercase letters a-v and digits 0-9, see section 3.1.2 in RFC2938
the length of the ID must be between 5 and 1024 characters
the ID must be unique per calendar
Due to the globally distributed nature of the system, we cannot guarantee that ID collisions will be detected at event creation time. To minimize the risk of collisions we recommend using an established UUID algorithm such as one described in RFC4122.
If you do not specify an ID, it will be automatically generated by the server.

Note that the icalUID and the id are not identical and only one of them should be supplied at event creation time. One difference in their semantics is that in recurring events, all occurrences of one event have different ids while they all share the same icalUIDs.

イベントidはRFC2938で定義されているフォーマットに従う必要があります。
ここだとBase32encodeで用いられるa-vおよび0-9で構成された5文字以上1024文字以下の文字列です。

Rubyでidを生成する

RubyにはBase32encodeできる関数があるのでそちらを使いましょう。
生成するべき文字列は他のイベントidと衝突する可能性を避けるために出来る限りユニークにする必要があります。(自分たちがコントロールできるカレンダーなら問題ないかもしれませんが本人のprimaryのカレンダーなどだといろんなところからイベントが登録されるため)

ref: http://dnsruby.rubyforge.org/classes/Base32.html

lib/base32.rb
module Base32
  module_function

  HEX = '[0-9a-v]'

  def encode32hex(str)
    str.gsub(/\G(.{5})|(.{1,4}\z)/mn) do
      full = $1; flag = $2
      n, c = (full || flag.ljust(5, "\0")).unpack("NC")
      full = ((n << 8) | c).to_s(32).rjust(8, "0")
      if flag
        full[0, (flag.length*8+4).div(5)].ljust(8, "=")
      else
        full
      end
    end
  end

  def decode32hex(str)
    str.gsub(/\G\s*(#{HEX}{8}|#{HEX}{7}=|#{HEX}{5}={3}|#{HEX}{4}={4}|#{HEX}{2}={6}|(\S))/imno) do
      raise "invalid base32" if $2
      s = $1
      s.tr("=", "0").to_i(32).divmod(256).pack("NC")[0,(s.count("^=")*5).div(8)]
    end
  end
end
require 'google/apis/calendar_v3'
  # .....省略... 

  def get_event_uid(event_id)
    unique_id = "event#{event_id}" #seedになるべき文字列
    #末尾の=は不要なので取り除く
    Base32.encode32hex(unique_id).gsub("=","")
  end

  def add(event)
    value = {}

    #....カレンダーの情報などを設定...

    value[:id]        = get_event_uid(event["id"])
    value[:i_cal_uid] = "#{id}@google.com"
    Google::Apis::CalendarV3::Event.new(value)
  end

まとめ

Googleカレンダーのイベントidを独自で生成することができると、わざわざイベントidを保持しておく必要がなく、イベント情報の更新等がある場合に一括で更新が出来るため非常に扱いが楽になります。

11
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
1