こちらのサンプルプログラムは Java 9 以降では動作しません。
Garoon と Google Calendar とを連携させたい場合は、株式会社ノベルワークスのカレンダー連携ソリューション ガル助(有償)の利用をご検討ください。
本サンプルプログラムとの大きな違いは次のとおりです。
・Google Calendar だけでなく、Office 365 とも連携が可能
・双方向連携が可能
・複数ユーザーのスケジュール同期が可能
(著者:サイボウズ 竹内 能彦)
はじめに
Googleカレンダー使っていますか?自分の予定と他の方の予定を並べて表示したり、予定を共有したり出来てとっても便利ですよね。
そこにGaroonの予定を並べて見られたらもっと便利になると思いませんか?
そんな思い付きからGaroonの予定をGoogleカレンダーに表示する連携プログラムを作成しました。事前準備が少し大変ですが、皆さん是非使ってみてください。
概要
連携プログラムは以下の処理をコマンドラインから実行できるサンプルプログラムです。
- Garoonに登録された予定をGoogleカレンダーに登録
- Garoonで更新された予定をGoogleカレンダーに反映
- Garoonから削除された予定をGoogleカレンダーから削除
Googleカレンダーに登録する情報はGaroonの予定の「開始日時」、「終了日時」、「施設」、「メモ」、「コメント」、「参加者」です。
動作環境
- プログラム実行用端末(Java8が動作し、Garoon、Googleカレンダーにネットワーク接続できること)
2018年3月現在、Java9では動作しないことを確認しています。 - Garoon on cybozu、パッケージ版 サイボウズ ガルーン3.0.0以降
- Googleカレンダー
Garoon on cybozu、Googleカレンダーは2018年2月版で確認しています。
事前準備
実行するには連携プログラムの設定だけでなく、GoogleアカウントやGoogleカレンダーの設定が必要になります。
また、GoogleアカウントやGoogleカレンダーの設定内容を連携プログラムの設定に利用するため、メモが必要な項目はその都度注釈を入れてあります。
※現在のGGsyncはOAuth2.0にも対応していますが、本ページではサービスアカウントキー認証を利用します。
1.Googleアカウント作成
下記URLから、Googleアカウントを作成します。Googleアカウントを取得済みの方はログインしてください。
https://accounts.google.com/SignUp
2.Google APIの利用設定
下記URLから、プロジェクトを作成します。
https://console.developers.google.com/project
プロジェクト名には適当な値を入力してください。
プロジェクトの作成完了後、Google Calendar APIを検索し、
Google Calendar APIを有効にします。
認証情報を作成します。
下記画像の通りの内容を選択し、「必要な認証情報」をクリックします。
サービスアカウント名には適当な値を入力し、キーのタイプはP12を選択します。
役割なしで作成します。
自動ダウンロードされたP12キー(以下、秘密鍵(拡張子がp12))は以降の手順で利用しますので任意のフォルダに保存します。
次にサービスアカウント IDを確認します。
画面右の「サービスアカウントの管理」をクリックし、
表示されたサービスアカウント IDをメモします。(以降の手順で利用します)
3.Googleカレンダーの作成
下記URLから、Garoonのスケジュールを連携させるGoogleカレンダーを作成します。
https://www.google.com/calendar
カレンダーの作成完了後、Googleカレンダー設定の「このカレンダーを共有」タブを開きます。先ほどのメールアドレスに予定の変更権限を付与し、保存します。
Googleカレンダー設定の「カレンダー情報」タブを開き、カレンダーIDを確認します。カレンダーIDは以降の手順で利用しますのでメモしてください。
4.連携プログラムの設定
プログラム実行用端末に連携プログラムを動作させるフォルダを作成します。本設定では例として「C:/GGsync」を利用します。
秘密鍵を「C:/GGsync」に移動します。
実行ファイルと設定ファイルをダウンロードしてください。ソースはGitHubで管理しています。(外部サイトが開きます)
実行ファイル「GGsync.jar」と設定ファイル「GGsync.properties」を「C:/GGsync」に移動します。
設定ファイル「GGsync.properties」をテキストエディタで開き、コメントに従い設定します。
Googleカレンダーに登録する予定の色は1から11までの数値を指定できます。下記の色を参考に選択してください。
各カラーIDのカラーコードはこちらのコメントから確認できます。
(tomomo85さん 情報ありがとうございます)
実行手順
プログラム実行用端末でコマンドプロンプトを起動し、以下のコマンドを入力します。
> java -jar C:/GGsync/GGsync.jar C:/GGsync
コマンドの形式は「 java -jar 実行ファイルのパス 設定ファイルが存在するフォルダ」です。
「The sync completed.」と表示されればスケジュール連携に成功しています。
実行結果は設定ファイルが存在するフォルダ配下のGGsync.db(例ではC:/GGsync/GGsync.db)に保存します。GGsync.dbは次回実行時の差分反映に利用します。
プロキシ経由の実行
プロキシを経由する必要がある場合は下記のオプションを追加して実行してください。
> java -Dhttp.proxyHost=ホスト名 -Dhttp.proxyPort=ポート番号 -Dhttps.proxyHost=ホスト名 -Dhttps.proxyPort=ポート番号 -jar C:/GGsync/GGsync.jar C:/GGsync
オプションの詳細はこちら(Oracle社のドキュメントページが開きます)
セキュアアクセス利用時の実行
セキュアアクセスを利用する必要がある場合は、クライアント証明書をGGsync.jarと同じディレクトリに保存し、下記のオプションを追加して実行してください。
> java -Djavax.net.ssl.keyStore=xxxx.pfx -Djavax.net.ssl.keyStorePassword=xxxx -Djavax.net.ssl.keyStoreType=PKCS12 -jar GGsync.jar .
実行例
下記がGaroonのスケジュール、実行結果、予定が反映されたGoogleカレンダーの例になります。
・Garoonのスケジュール
・連携プログラムの実行結果
・Googleカレンダー(プライベートな予定と並べて表示)
Garoonの予定の「メモ」、「コメント」はGoogleカレンダーの「説明」にまとめて登録します。
Garoonの予定が変更された場合は、Googleカレンダーの予定を削除してから再登録します。
下記が変更時の実行例になります。
Garoonの予定が削除された場合は、Googleカレンダーの予定を削除します。
下記が削除時の実行例になります。
定期実行
タスクスケジューラなどを利用することで、定期的にGaroonの予定をGoogleカレンダーに反映できます。
是非試してみてください。
連携プログラムの更新履歴
2015/3/30 繰り返し予定が正常に登録されない不具合を改修しました。
2015/4/24 終了時間未指定の予定がエラーになる不具合を改修しました。
2015/6/18 連携失敗時に詳細なエラーを出力するように修正しました。
2015/9/16 日本語文字のアカウント名に対応しました。
2016/1/14 Googleカレンダーに「参加者」を登録する機能を追加しました。
2016/3/24 ソースコードをGitHubに移しました。
2017/3/21 セキュアアクセス利用時の実行オプションを追記しました。
2017/9/21 ソースコードにライセンス表記を追加しました。
竹内 様
ログで下記の様状態になってしまいました。
タイムアウトしているようなのですが、何が原因なのでしょうか・・・
INFO 2019/05/14 20:53:57(GGsync:main:77) The sync beginning with normal mode.
ERROR 2019/05/14 20:54:57(GGsync:main:443) Read timed out
org.apache.axis2.AxisFault: Read timed out
at org.apache.axis2.AxisFault.makeFault(AxisFault.java:430)
at org.apache.axis2.transport.http.HTTPSender.sendViaPost(HTTPSender.java:197)
at org.apache.axis2.transport.http.HTTPSender.send(HTTPSender.java:75)
at org.apache.axis2.transport.http.CommonsHTTPTransportSender.writeMessageWithCommons(CommonsHTTPTransportSender.java:396)
at org.apache.axis2.transport.http.CommonsHTTPTransportSender.invoke(CommonsHTTPTransportSender.java:223)
at org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:443)
at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:406)
at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:229)
at org.apache.axis2.client.OperationClient.execute(OperationClient.java:165)
at org.apache.axis2.client.ServiceClient.sendReceive(ServiceClient.java:555)
at org.apache.axis2.client.ServiceClient.sendReceive(ServiceClient.java:531)
at com.cybozu.garoon3.common.CBServiceClient.sendReceive(CBServiceClient.java:172)
at com.cybozu.GGsync.main(GGsync.java:162)
Caused by: java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at sun.security.ssl.InputRecord.readFully(Unknown Source)
at sun.security.ssl.InputRecord.read(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readDataRecord(Unknown Source)
at sun.security.ssl.AppInputStream.read(Unknown Source)
at java.io.BufferedInputStream.fill(Unknown Source)
at java.io.BufferedInputStream.read(Unknown Source)
at org.apache.commons.httpclient.HttpParser.readRawLine(HttpParser.java:78)
at org.apache.commons.httpclient.HttpParser.readLine(HttpParser.java:106)
at org.apache.commons.httpclient.HttpConnection.readLine(HttpConnection.java:1116)
at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$HttpConnectionAdapter.readLine(MultiThreadedHttpConnectionManager.java:1413)
at org.apache.commons.httpclient.HttpMethodBase.readStatusLine(HttpMethodBase.java:1973)
at org.apache.commons.httpclient.HttpMethodBase.readResponse(HttpMethodBase.java:1735)
at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1098)
at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398)
at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
at org.apache.axis2.transport.http.AbstractHTTPSender.executeMethod(AbstractHTTPSender.java:621)
at org.apache.axis2.transport.http.HTTPSender.sendViaPost(HTTPSender.java:193)
... 11 more
坂下 充範さん
Garoonへの接続に失敗しているのでURLが正しいか確認をお願いします。
GaroonのURLが正しい場合はネットワークに問題がありそうです。
プロキシを経由する必要がある場合は本文を参考に実行コマンドにオプションを追加してください。
竹内様
上記の手順でgaroon→googleカレンダーへの連携ができました。
手順をご提供いただき、ありがとうございます。
今後、自動化してある程度定期的にロードをしたいのですが、
batファイルが上手く起動しません。
cmdで記入している内容をbatとして起こしているのですが、
記載方法など間違っておりますでしょうか。
当方、ほとんど作成したことがないため、ご教示いただけましたら幸いです。
よろしくお願いいたします。
Manato様
ご利用ありがとうございます。
バッチファイルの記述方法やタスクスケジューラーの設定については
恐れ入りますがお答えできません。
が、ぱっと思いつくことを
まずは以下の2つのどちらかの切り分けをしていただくことが解決への近道かなと思います。
・バッチファイルが起動できていない
=>タスクスケジューラーの設定に問題がありそう
・バッチファイルは起動できているが、スケジュールが連携されない
=>バッチファイルの内容に問題がありそう
あとは短いコマンドなのでバッチファイルにせずに
タスクスケジューラーに直接実行コマンドを指定してもいいかもしれないです。
お世話になっております。
こちらのGGsyncを設定しようとしたところ、以下のエラーが表示され同期できないようです。
どこかの設定に問題があるのだと思いますが、原因を特定したく、内容を見ていただけますでしょうか。
INFO 17:50:28 The sync beginning with normal mode.
INFO 17:50:31 [ADD] Title:セミナー: ガルーン教育
ERROR 17:50:31 sun.security.validator.ValidatorException: PKIX path building fai
led: sun.security.provider.certpath.SunCertPathBuilderException: unable to find
valid certification path to requested target
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException:
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderExce
ption: unable to find valid certification path to requested target
at sun.security.ssl.Alerts.getSSLException(Unknown Source)
Daisukeさん
Google Calendarの接続でエラーになっていますね。
以下の二つを確認してください。
・Javaのバージョンが8か
8以外の場合は8をインストールしてください。
・ブラウザからGoogle Calendarにアクセスできるか
できない場合はネットワーク担当者に相談するしかないと思います。
ネットを検索するといくつか情報がヒットしますが
おそらく上記のどちらかが怪しいかなと思っています。
これで解決できない場合は私のほうでもこれ以上の助言は難しそうです。
返信ありがとうございます。
・Javaのバージョンが8か→Java 8 Update 211(64bit)ですので問題無さそうです
・ブラウザからGoogle Calendarにアクセスできるか→問題なくアクセスできています
少し調べたところ、SSL で暗号化された アプリケーション(HTTPS、LDAPS、IMAPS など)にJavaからアクセスしようとすると、証明書関連でエラーが出てしまっているようです。他の方は問題ないのになぜ自分の環境だけエラーが出てしまうのか疑問ですが、GoogleカレンダーとJavaとのアクセスの問題のようなので、もう少し調べて解決しないようなら諦めます。
こんにちは。
コマンドで下記のメッセージが出ました。
Ver対応していないということでしょうか?
----
Exception in thread "main" java.lang.UnsupportedClassVersionError: com/cybozu/GGsync (Unsupported major.minor version 52.0)
at java.lang.ClassLoader.defineClass0(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$100(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClassInternal(Unknown Source)
mmmさん
こんにちは。
Javaのどのバージョンをご利用されているのかわかりませんが、おそらく対応していないという回答になりそうです。
Java 8のインストールをご検討ください。
GGsyncを便利に使わせてもらっていたのですが、あるときから、
org.apache.axis2.transport.http.HTTPSender sendViaPost
情報: Unable to sendViaPost to url[https://XXXXXX.cybozu.com/g/cbpapi/base/api.csp]
とエラーメッセージが出ていまい、接続できなくなってしまいました。
GGsync.propertiesには、
garoon.url=https://XXXXXX.cybozu.com/g
としか指定していないのに、なぜだか余計な文字列が付加されてしまうようです。
何か、他に見なければならない設定があるのでしょうか。
H.hiro さん
エラーメッセージのURLに「xxxx.csp」が付加されるのは正しい動作となります。
エラーメッセージを見るとGaroonに接続できていないようです。
以前利用できていたということであれば、おそらくネットワーク環境に変更があったのだと思います。
ネットワーク環境やcybozu.comへの接続方法などに変更がないか確認してください。
Linuxを使用しているのですが、ブラウザからだと上記アドレスに接続できました。
もしかしたら、Garoon側でブラウザチェック等されているのではないか?
と言われましたが、そんなことあるのでしょうか。
H.hiro さん
Garoon 側ではブラウザチェックはしていません。
curlコマンドでも接続できますでしょうか。
ブラウザ接続がproxy経由の場合は本プログラムもproxy経由に変更する必要があります。
手順については本文をご確認ください。
竹内様
いつもお世話になっております。
ずっと順調だったんですが、2週間ほど(?)前から同期がされないので
よく見たところ、次のようなエラーが出ていました。
対処方法をご教示願えませんか?
INFO 08:23:32 The sync beginning with normal mode.
ERROR 08:23:36 For input string: ""
java.lang.NumberFormatException: For input string: ""
at java.lang.NumberFormatException.forInputString(Unknown Source)
自己レスです。
過去の書き込みを見たところ「ガルーン上から削除されたユーザー」と
書いてありましたので、確認してみます。
お騒がせして申し訳ありません。
T2様
そうですね。
過去のコメントと同様の現象と思われます。
GGsync.jarを本文からダウンロードして、上書き更新してください。
本文には追記済だったのですが念の為コメントにも記載しておきます。
こちらのサンプルプログラムは Java 9 以降では動作しません。
Garoon と Google Calendar とを連携させたい場合は、株式会社ノベルワークスのカレンダー連携ソリューション ガル助(有償)の利用をご検討ください。
https://www.novelworks.jp/garsche/
本サンプルプログラムとの大きな違いは次のとおりです。
・Google Calendar だけでなく、Office 365 とも連携が可能
・双方向連携が可能
・複数ユーザーのスケジュール同期が可能