【続報】GCALDaemonを使ったAipoとGoogleカレンダーの同期でエラーについて、強力な助っ人が現れて無事同期できました。ネットって素晴らしい!の巻

以前に

GCALDaemonを使ったAipoとGoogleカレンダーの一方通行同期でエラー

という記事をかいた後も、あいかわらず同期できなくて困っていますと、記事をみてくださった、ぐらさん様からコメントをいただきました。
自家製のRubyスクリプトで動かしているとのこと。
そして、ありがたいことに、ぐらさん様が作成したRubyスクリプトを頂戴することができました。

そして・・・いろいろなれないサーバいじりなどをした結果、ついに同期することができました!

というわけで、この喜びを多くの方に分かち合うために、ぐらさん様から許可をいただき、Aipo→Googleカレンダーへの同期のためのプログラムを公開させていただきます。

それが、こちらです。↓↓
ダウンロード: aipotogcal
※こちらは「ぐらさん」様より許可をいただき公開させていただいております。この場を借りて感謝を表明いたします。
m( _ _ )m
※ご承知とは思いますが、使用は自己責任でお願いしますね。

また、私が稼働させるまでの手順を下記に記述しました。
参考になれば幸いです。

Googleサービスアカウントの取得から秘密キーの入手

このプログラムでは、ブラウザを介さずにGoogleのAPIにアクセスするために、Googleのサービスアカウントを取得する必要があります。

  1. Google Developers Consoleにアクセスする。
    https://console.developers.google.com/
  2. プロジェクトを作成→任意の名前とIDを入力して作成
  3. 作成されたプロジェクトから、APIと認証の「認証情報」を開く
  4. OAuthから「新しいクライアントIDを作成」→サービスアカウントを選択して作成
  5. 秘密キーパスワードが表示されるのでメモ(※注意。一度しか表示されません)(※1)
  6. 秘密キーの表示と同時にファイルがダウンロードされる。このファイルが「秘密キー」となるので保存(※2)
  7. 作成したサービスアカウントのメールアドレスなどが表示されるので覚えておく(※3)

Googleカレンダーの設定

Aipoから同期させたいGoogleカレンダーに、プログラムからアクセスが出来るようにします。

  1. Googleカレンダーにアクセス
  2. 同期させたいカレンダーを選択(もしくは作成)
  3. カレンダーの共有設定から、上記のサービスアカウントで作成された「メールアドレス」を共有に加える(私は「変更および共有管理権限」で加えましたが、ひょっとしたら「変更権限」だけでよいかもしれません)
  4. カレンダーの設定画面から「カレンダーのアドレス」の項目に表示されている「カレンダーID」を覚えておく(※4)

プログラムの設定

Googleカレンダー側には設定ができたので、次はAipo側の設定です。

  1. Aipoの動いているサーバに「aipotogcal」をアップロード(サーバの権限によってはAipoと別のサーバでも良いかもしれません)
  2. 同じく上記※2で保存した秘密キーファイルをアップロード
  3. 「api.yaml」を編集します。
  4. key_pass:上記※1の秘密キーパスワード
  5. key_file:上記※2の秘密キーファイルの場所を記述(サンプル:/usr/local/aipotogcal/************.p12)
  6. cal_id:上記※4のカレンダーID
  7. issuser:上記※3のメールアドレス
  8. timezone:通常は”Asia/Tokyo”で問題ないはず
  9. ical_uri:AipoのiCalのURL(通常は、https://********.***/aipo/ical/calendar.ics)のはず
  10. aipo_user:Aipoのユーザ名
  11. aipo_pass:Aipoのパスワード


あとは、Rubyでちゃんと実行できるか確かめた上でCRONで定期実行させるだけです。

設置時に躓いたことメモ

※私の場合はAipoサーバ環境に問題があり、AipoのHTTPレスポンスヘッダーに文字コード指定がないために
from ASCII-8BIT to UTF-8 (Encoding::UndefinedConversionError)
というエラーがでました。本来はサーバ設定で解決すべき問題なのですが、そこまでの知識が及ばず…
対策として、66行目あたりに
ics.force_encoding(“UTF-8”)
という記述を追加して無事動かしました。本来はサーバ側の設定でHTTPヘッダを適切に処置出来るようにするのが正解だと思います。

※実は一番苦労したのが私の環境にRubyが入っていなかったために、Rubyのインストールをするところでした。
これはいろいろな環境があって一口に言えないためにあえて今回は書きません。
下記等を参考にインストールしました。
(Rubyインストールに参考になったサイト)
http://d.hatena.ne.jp/yk5656/20140324/1396158118
http://centos.bungu-do.jp/archives/000294.html

“【続報】GCALDaemonを使ったAipoとGoogleカレンダーの同期でエラーについて、強力な助っ人が現れて無事同期できました。ネットって素晴らしい!の巻” への30件の返信

  1. お世話になります。まさに求めていた情報でしたので早速Aipoとは
    別の端末でチャレンジしてみたのですが、何やら下記のようなメッセージを
    吐き止まってしまいました。

    open-uri error=,undefined method `zero?’ for “3”:String

    お恥ずかしながらrubyにはあまり触れたことがなく、Try & Errorで
    下記のように環境を作ったつもりだったのですが、、、
    もし原因が分かるようでしたらご指摘頂けると幸いです。

    # ruby –version
    ruby 2.1.5p273 (2014-11-13 revision 48405) [x86_64-linux]
    # gem install icalendar
    # gem install tzinfo
    # gem install icalendar-recurrence
    # gem install google-api-client

    1. 書き忘れましたがical_uriに記載したuriでブラウザアクセスするとicaをDL出来ています。

    2. こんにちは、実は私もrubyに触れたことがないクチでして、体当たり的に挑戦したので、インストールから動かすまでのことが結構うろ覚えなのですが、そのエラーを見たことがあります。
      全然検討違いかもしれないし、参考にならないかもしれないですが、、確か下記の時どちらかで見ました。

      ●私が最初に試した環境がテスト的な環境だったので、Aipoのical1アドレスがhttpなのに、httpsで指定してしまっていた。api.ymlのical_urlの部分です。
      ●ICALtoGCAL.rbの最初の方で読み込んでいるライブラリのうちのいくつかがインストールされていなかった。

      もっとたくさん躓いたのですが、、たしか上記のあたりで、同じようなエラーメッセージを見た記憶があるのです。。。。
      ごめんなさい。すっごくうろ覚えで。そして初歩的なやつで。
      今度時間のあるときに試してみますが、いまのところおぼろげながら思い出すのはこのくらいです。。^^;

  2. 私も”いんふらかんり”さんと同じエラーが出ます。
    open-uri error=,undefined method `zero?’ for “3”:String
    Aipoのcalendar.icsはwgetコマンドで読み込むとhttpsでもhttpでも読むことができました。
    ライブラリのインストールはgemを使って行いましたがインストールできないライブラリがいくつかありました。’date’、’yaml’など。
    どなたか解決策がわかるようならおしえてください。

  3. 結構うまくいかない人いますね。
    何か抜けてるかな?時間みつけて再度検証してみようかな・・・
    解決策わかる人募集です。

  4. 久しぶりに覗きに来てみたら、トラブってますね^^;
    もともとスクリプト書いた作った人ですm__m

    open-uriのエラーは、yamlからurlを設定する作りなので、yamlが入っていないからだと思います。

    なんでyamlが入らなかったかは・・・rubyのバージョンかも知れないですね~
    私はruby193で動かしているのです。
    ちゃんと調べて書き込みますね。

    お急ぎでしたらyamlは、固定値を外部に出しているだけなので、スクリプト内に記述してしまう方法もありますよ。
    dateは、いろいろ使っているので、ちょっと大変ですね。

  5. rubyが入ってない環境がwindowsしかなかったので、
    rubyinstaller-2.1.6にて試しました。

    yamlとdateを使った簡単なスクリプトを書いて動かしたのですが、
    標準で入っているようですね。

    rubyのインストールがビルドインストールの気がするので
    CentOsのビルド手順がのっているURL書いておきますね。
    http://www.mlte.de/ruby-centos

    dateは、ちょっと解らないので、エラーメッセージのせてください。

  6. アドバイスありがとうございます。
    スクリプトにcalendar.icsのurlを直接記入してみましたが同じエラーが返ってきました。また、wgetで落としたファイルを直接指定してみましたが同じエラーでした。
    私はrubyはよくわかりません。そのため構文が間違っているのかもしれません。変更したのは62行目で次のようにいたしました。
    1)urlを直接指定
    f = open(‘https://***/aipo/ical/calendar.ics’, {:http_basic_authentication => certs})
    2)ファイルを直接指定
    f = open(‘/home/abc/aipotocal/calendar.ics’)
    なおrubyのバージョンは’2.2.2p95’です。

  7. 先日作ったwindowsのruby216環境を使って、aipo.comから
    icsを読むところだけ作ってみました。
    gem installはしていません。
    ちょっと試してみてください。
    私のwindowsの環境がプロクシの中なので、プロクシの設定も追加してあります。
    —————————————————-

    # coding: utf-8
    
    require 'open-uri'
    require 'openssl'
    
    module OpenSSL
      module SSL
        remove_const :VERIFY_PEER
      end
    end
    
    OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
    
    uri = 'https://app.aipo.com/ical/calendar.ics'
    proxy = ["http://プロクシ:ポート", "ユーザー" ,"パスワード"]
    certs = ["AIPOのユーザー", "AIPOのパスワード"]
    
    ##串あり
    f = open(uri, {:http_basic_authentication => certs, 
    				:proxy_http_basic_authentication => proxy})
    
    ##串なし
    ##f = open(uri, {:http_basic_authentication => certs})
    
    f.each do |line|
    	puts 	line
    end
    
  8. ぐらさんお手数をおかけします。
    サンプルプログラムをプロクシ無しで実行したところcalendar.icsの中身が正常に表示されました。
    ただし、最初にプログラムを張り付けて実行したところsyntax errorとなりました。サンプルプログラムで使用している「’」と「”」のコードが違っているようでしたので書き換えて再度実行しています。

  9. 「‘」と「’」ですね。
    貼り付け前は「’」シングルクオートなんで、ブラウザかなんかの便利機能が動いたんですかね~
    ruby的にはシングルでもダブルでもOKです。
    詳しくはこの辺りを
    http://blog.quellencode.org/post/78599028005/ruby
    さて本題が解決していませんね。
    このプログラムは、ICSを読むところのエラートラップを外しただけなのです。
    ずらずらとエラーがでる予定だったのですが、動いちゃいましたか~^^;

  10. ブログ管理人をしているものです。ぐらさん様がコメント欄に書いてくださったコードについて、Wordpressの機能でシングルクォートが変換されているっぽかったので、ちゃんとコードとして表示されるようにしてみました。
    ご迷惑をお掛けしました。m( _ _ )m

  11. 悪い箇所はわかりました。

    TIMEOUTの書き換えが上手くいっていないようですね。
    ないとRuby標準のタイムアウトになるような覚えがあるので、致命的な問題にはならないハズなので、
    61行目と76行目をコメントにしてください。
    61行目
    # timeout(TIME_OUT) do
    76行目
    # end

    ちゃんとした理由がわかったら書き込みますね。

  12. わかると納得・・・失礼しました。
    api.yaml中の
    timeout_time : ‘3’の
    クォートをはずしてください。
    正解
    timeout_time : 3

    undefined method `zero?’ for “3”:String
    は、この3のことを言っていたんですね。

  13. 「timeout_time : ‘3’のクォートをはずしてください。」

    はずして実行したところ、
    undefined method `zero?’ for “3”:String
    エラーが出なくなりました。ありがとうございます。
    上記エラーは亡くなったのですが、次のメッセージが出て実行できません。何かミスをしているようなので調査中です。
    とりあえずご報告いたします。

    /usr/local/lib/ruby/2.2.0/json/common.rb:223:in `generate’: “xE7” from ASCII-8BIT to UTF-8 (Encoding::UndefinedConversionError)
    from /usr/local/lib/ruby/2.2.0/json/common.rb:223:in `generate’
    from /usr/local/lib/ruby/2.2.0/json/common.rb:394:in `dump’
    from ICALtoGCAL.rb:217:in `block in ‘
    from ICALtoGCAL.rb:107:in `each’
    from ICALtoGCAL.rb:107:in `’

  14. 文字コード系ですね。
    この板の「設置時に躓いたことメモ」の対策はしていてでました?

    もしくは、aipoのicsを取得する時のレスポンスヘッダーのcontentの
    文字コードを確認してみてください。
    こんなヤツですね。
    Content-Type: plain/text; charset=UTF-8;
    ↓はChromeでの確認方法です。
    http://dev.ontheroad.jp/archives/11970

  15. calendar.icsのレスポンスヘッダーは次の通りです。
    Content-Type:text/html; charset=iso-8859-1
    次に「設置時に躓いたことメモ」に指摘されているように、ICALtoGCAL.rbの66行目に
    ics.force_encoding(‘UTF-8’)
    を追加して実行したところ先ほどのエラーは無くなりましたが、新たに次のエラーが出てきました。
    open-uri error=,incompatible character encodings: UTF-8 and ASCII-8BIT

  16. 早くopen-uriの処理抜けたいですね^^;
    文字コード系は、いろいろパターンがいろいろあるので、データ送って!と
    いいたいところですが、そうもいかないので、想像で・・・
    6/24のエラーはopen-uriを抜けてgoogle-apiのimportで起きてるとして、
    6/26はopen-uriの中の単純なエラー
    とすると
    charset=iso-8859-1なので、
    f = open(uri, {:http_basic_authentication => certs})
    fの中身はASCII-8BITでしょう。
    f.each do |line|
        line.force_encoding(“UTF-8”) <– ここに追加 
        if line[0,15] == "BEGIN:VTIMEZONE"
            writefl = 0
        end
    で、いいんではないですかね?

    1. 自力解決ができなくてご迷惑をおかけします。

      66行目に挿入した
      ics.force_encoding(‘UTF-8′)
      をご指摘のように
      line.force_encoding(“UTF-8″)
      に変更したところ先ほどのエラーは無くなりました。
      しかし、新たに次のエラーが出てきました。
      GAPI import err status=,403,{“summary”:* * * *
      GAPI import err status=,403,{“summary”:* * * *
      /usr/local/lib/ruby/gems/2.2.0/gems/autoparse-0.3.3/lib/autoparse/instance.rb:315:in `method_missing’: undefined method `iCalUID’ for # (NoMethodError)
      from /usr/local/lib/ruby/gems/2.2.0/gems/autoparse-0.3.3/lib/autoparse.rb:123:in `block (2 levels) in generate’
      from ICALtoGCAL.rb:262:in `block (2 levels) in ‘
      from ICALtoGCAL.rb:260:in `catch’
      from ICALtoGCAL.rb:260:in `block in ‘
      from ICALtoGCAL.rb:259:in `each’
      from ICALtoGCAL.rb:259:in `’

  17. 403はhttpレスポンスの403です googleが返してきてます
    Uidの加工がうまくいってないようですね
    コード変換の場所が悪くて改行こわれちゃったかな~(>_<)
    puts で変数の中身みれますので、UIDの中身確認してみてください

    1. ICALtoGCAL.rbの179行、str_uidでよろしいですか。
      puts(str_uid)を挿入して表示された内容は
      23191@fe80:0:0:0:5054:5ff:fe00:3197%2
      でした。

  18. それです。
    aipo.comもそんなUIDが作られていたので、
    変換でずれたことは、なさそうですね。

    もうひとつ確認ですが、
    GAPI import err status=,403,{“summary”:* * * *

    {“summary”:* * * *
    は長いから省略しているんですよね?
    件名や内容や開始日、終了日もでていますよね?

      1. rubyのエラーダンプが出ているのが、よくわからなくてjsonの中身が
        おかしいのかと思いましたが、まず403をヒントにチェックしますかね。
        403はGoogleカレンダーに対しての権限がないってことです。
        APIに権限がない、カレンダーに権限がない、イベントに権限がないが考えられます。
        とりあえずAPIを使ってGoogleカレンダーが読めるか確認しましょう。
        229行目(events = [])~248行目(end while・・・)は、読み込むだけのロジックです。
        importのロジック107行目(ical.events.each・・・)~224行目(end)までをそっくりコメントにしてしまいましょう。
        =begin ##追加
        ・・・107行目
        ・・・224行目
        =end ##追加
        で範囲コメントです。
        257行目以降も動作してほしくないので、
        exit ##追加
        ・・・257行目~

        読めたら何か表示したいので
        ・・・248行目
        events.each do |event|
        puts event_start_date(event),event.summary
        end
        を追加

        これで、完成です。
        このかと、Googleカレンダーに画面からスケジュールを追加して読めるか確認してください。

        1. 返信が遅くなりまして申し訳ありませんでした。

          Google Developers Consoleでプロジェクトを作り直して再実行したところ、AipoカレンダーよりGoogleカレンダーへの登録ができるようになりました。
          今までうまく動かなっかった原因はGoogleカレンダーでのカレンダー共有設定のメールアドレス登録で権限の設定が間違っていたためでした。
          予定の変更を可能に設定したところ正常に動作するようになりました。
          うまく動くようになり感激しています。
          大変お世話なりました。ありがとうございました。

          1. よかったです。

            こんな教え方でわかるかな~と思っていたところだったので
            本当にひと安心です^^

            実は逆バージョンも作ってあるのですが、さらに動作環境作るのが過酷なので、やめときます(^^;

  19. aipo.comからとりこんだjsonの中身です。
    result = client.execute(:api_method => service.events.import,
    の前で
    puts JSON.dump(event)
    を追加して書き出しています。
    正常終了していますので、参考までに。

    {“summary”:”日指定で無期限スケジュール”,”location”:null,”description”:null,”iCalUID”:”38@fe80:0:0:0:2000:aff:febd:2486%eth0″,”start”:{“dateTime”:”2015-03-30T00:00:00.000+09:00″,”timeZone”:”Asia/Tokyo”},”end”:{“dateTime”:”2015-03-30T00:00:00.000+09:00″,”timeZone”:”Asia/Tokyo”},”recurrence”:[“RRULE:FREQ=DAILY”]}
    {“summary”:”繰り返し確認”,”location”:null,”description”:null,”iCalUID”:”39@fe80:0:0:0:2000:aff:febd:2486%eth0″,”start”:{“dateTime”:”2015-03-30T00:05:00.000+09:00″,”timeZone”:”Asia/Tokyo”},”end”:{“dateTime”:”2015-03-30T00:05:00.000+09:00″,”timeZone”:”Asia/Tokyo”},”recurrence”:[“RRULE:FREQ=DAILY”]}
    {“summary”:”繰り返しテスト”,”location”:null,”description”:null,”iCalUID”:”37@fe80:0:0:0:2000:aff:febd:2486%eth0″,”start”:{“dateTime”:”2015-04-07T11:30:00.000+09:00″,”timeZone”:”Asia/Tokyo”},”end”:{“dateTime”:”2015-04-07T14:30:00.000+09:00″,”timeZone”:”Asia/Tokyo”},”recurrence”:[“RRULE:FREQ=WEEKLY;BYDAY=TU”]}
    {“summary”:”saigen a”,”location”:null,”description”:null,”iCalUID”:”26@fe80:0:0:0:2000:aff:febd:2486%eth0″,”start”:{“dateTime”:”2015-04-01T00:00:00.000+09:00″,”timeZone”:”Asia/Tokyo”},”end”:{“dateTime”:”2015-04-01T00:00:00.000+09:00″,”timeZone”:”Asia/Tokyo”},”recurrence”:[“RRULE:FREQ=WEEKLY;UNTIL=20150429T000000Z;BYDAY=WE”]}

  20. 今の件には、関係ないのですが気がついたこと!
    aipo.comのUIDですが、@マーク以降も変化してますね~
    例えば
    20150628T043938Z-25@fe80:0:0:0:2000:aff:feba:17b9%eth0

    20150626T143312Z-25@fe80:0:0:0:2000:aff:febd:24d7%eth0

    前半の日付っぽい部分は、今のスクリプトで対策してあるのですが、
    後半のfeba:17b9→febd:24d7は対策していません。

    このままだと、importのたびにイベントが増えていきますね。
    この部分、OSS版だとホスト名なのです。
    ユニークが保てればいいので、@以降を固定値で置き換えてしまって
    ください。
    例)
    25@glass-sun

  21. はじめまして。
    知りたかった情報なのでaipotogcal.zipをダウンロードしようと思ったのですが、リンク先にファイルがないようです。
    お手数とは思いますが、再度公開していただけないでしょうか?
    よろしくお願いいたします。

    1. 管理者です。
      リンクが間違っていたので取り急ぎ修正いたしました。申し訳ございません。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です