kintoneアプリのイベント・フェアカレンダーを利用して、イベントの日程をGoogle WorkspaceのGoogleカレンダーに連携して社内で共有します。
有料のGoogle WorkspaceのGoogleカレンダーの場合、社内でイベントの日程を管理し、承認後に社内でカレンダー日程をセキュアに共有したい場合などに利用できます。
また、設定で一般公開すれば、社外にもEメール等でイベントの告知とカレンダー日程の同期が可能になります。
- Google Workspaceアカウント(有料アカウント)
- kintoneアカウント
-
Googleカレンダーの作成・設定
-
kintoneアプリの設定・変更
-
JavaScriptによるプログラムの作成
-
動作の確認
以上の手順で開発していきます。
1. Googleカレンダーの作成・設定
固定リンクがコピーされました
Google.com
より、ログインし、右上Googleアプリアイコンより、カレンダーを選択します。
左サイドメニューの他のカレンダーの右側の「+」をクリックして、「新しいカレンダーを作成」を選択します。
カレンダー名を入力し、「カレンダーを作成」ボタンをクリックし、カレンダーを作成します。
次に左メニューより、新しく作成されたカレンダーのオーバーフローメニューより、「設定と共有」を選択します。
「アクセス権限」のセクションにおいて、「{組織名}で利用できるようにする」をチェックします。
ドロップダウンより「予定の表示(すべての予定の詳細)」を選択します。
次に「特定ユーザーとの共有」設定で、「ユーザーを追加」をクリックし、組織内のユーザーのメールアドレスを追加します。
また「権限」のドロップダウンで「予定の変更」を選択します。
「送信」ボタンをクリックすると指定したユーザーに招待状が送信されます。
指定したユーザーが招待状を承認することにより、作成した「イベント・フェアカレンダー」が共有できます。
「設定」画面で下にスクロールすると、「カレンダーの統合」の項目内に「カレンダーID」が表示されているので、メモしておきます。
後のプログラミングで必要です。
次にGoogle APIを利用するためにGoogleカレンダーAPIの認証情報を設定します。
まず、
Google APIのデベロッパーコンソール
にログインします。
ダッシュボード画面が表示されたら、下の画像のように右上の「プロジェクト作成」をクリックします。
プロジェクト名を入力し、「作成」ボタンをクリックすると、新規プロジェクトが作成されます。
「APIとサービスの有効化」をクリックして、「APIライブラリ」設定画面へ移行します。
G Suiteカテゴリーより、「Google Calendar API」を選択します。
「有効にする」をクリックして、Google Calendar APIを有効にします。
右上の「認証情報を作成」をクリックします。
使用するAPIに「Google Calendar API」を選択し、次の内容を入力します。
- APIを呼び出す場所:Webブラウザー(JavaScript)
- アクセスするデータの種類:ユーザーデータ
入力したら「必要な認証情報」をクリックします。
「OAuth同意画面の設定」が表示されるので、「同意画面を設定」をクリックします。
アプリを使用するユーザーのタイプを選択し、「作成」をクリックします。
今回は、「内部」を選択しました。なお、このオプションは、有料アカウントの場合のみ選択可能です。
OAuth同意画面にて、「同意を求めるアプリの名前」を入力し、「ユーザーサポートメール」を選択します。
「承認済みドメイン」にお使いのkintoneのドメイン名を入力(例:cybozu.com)し、「デベロッパーの連絡先情報」にメールアドレスを入力、「保存して次へ」をクリックします。
スコープに「Google Calendar API」を選択し、「更新」をクリックします。
内容を確認して、「保存して次へ」をクリックします。
アプリ登録の概要を確認し、「ダッシュボードに戻る」をクリックし、「OAuth同意画面」の設定を完了します。
認証情報設定の画面に戻り、OAuth 2.0クライアントに適当な名前を入力します。
また、それぞれ次の情報を入力します。
- 承認済みのJavaScript生成元:kintoneのURL(例;https://{サブドメイン}.cybozu.com)
- 承認済みのリダイレクトURL:kintoneアプリのURL(例:https://{サブドメイン}.cybozu.com/k/{アプリケーションID}/)
kintoneアプリは後で作成します。
最後に「OAuthクライアントIDの作成」ボタンをクリックして、クライアントIDを生成します。
クライアントIDが作成されますので、メモしておきます。(後のカスタマイズのプログラミングで使用します)
「完了」ボタンをクリックして、終了します。
再び、「認証情報を作成」メニューから、今度は、「APIキー」を選択します。
APIキーが作成されますので、メモしておきます。
左サイドメニューの「認証情報」をクリックすると生成した認証情報が確認できます。
以上でGoogleカレンダー側の設定は終了です。
2. kintoneアプリの設定・変更
固定リンクがコピーされました
今回は、kintoneアプリの「イベント・フェアカレンダー」を元にアプリを設定・変更します。
kintoneアプリストアより、左サイドメニュー上部のアプリストア検索欄に「イベント」と入力し、検索します。
「イベント・フェアカレンダー」が表示されますので、「このアプリを追加」をクリックします。
アプリを開いて、右上のギアアイコンをクリックして、アプリの設定画面に移行します。
下記テーブルを参考にして、フォームにフィールドを追加・変更します。
フィールドの種類 |
フィールド名 |
フィールドコード |
日付 |
開催日 |
event_date |
文字列(1行) |
イベント名 |
event_name |
日時 |
開催日時 |
start_datetime |
日時 |
終了日時 |
end_datetime |
文字列(複数行) |
開催場所 |
event_location |
文字列(複数行) |
イベント詳細 |
event_description |
スペース |
− |
publish_button_space |
文字列(1行) |
GoogleイベントID |
event_id |
フィールドの設定、変更後、「フォームを保存」し、最後に「アプリを更新」します。
これで、kintoneアプリの設定は終了です。
3. JavaScriptによるプログラムの作成
固定リンクがコピーされました
下記サンプルコードを参考にプログラムを作成します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
(function() {
'use strict';
// APIキー
const api_key = 'Your Google API key';
// クライアントID
const client_id = 'Your Google Client ID';
// カレンダーID
const calendar_id = 'Your Google Calendar ID';
// 認証用URL(読み取り/更新)
const scope = 'https://www.googleapis.com/auth/calendar https://www.googleapis.com/auth/calendar.events';
// Discovery Docs
const discovery_docs = ['https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest'];
// APIクライアントライブラリの初期化とサインイン
function initClient() {
gapi.client.init({
apiKey: api_key,
discoveryDocs: discovery_docs,
clientId: client_id,
scope: scope
}, (error) => {
alert('Googleへの認証に失敗しました。: ' + error);
});
}
// APIクライアントとOAuth2ライブラリのロード
gapi.load('client:auth2', initClient);
// レコード詳細画面の表示後イベント
kintone.events.on('app.record.detail.show', (event) => {
// 増殖バグ回避
if (document.getElementById('publish_button') !== null) {
return event;
}
// 画面下部にボタンを設置
const publishButton = document.createElement('button');
publishButton.id = 'publish_button';
publishButton.innerHTML = '公開する';
publishButton.className = 'button-simple-cybozu geo-search-btn';
publishButton.style = 'margin-top: 30px; margin-left: 10px;';
publishButton.addEventListener('click', () => {
publishEvent();
});
kintone.app.record.getSpaceElement('publish_button_space').appendChild(publishButton);
return event;
});
kintone.events.on(['app.record.create.show', 'app.record.edit.show'], (event) => {
// フィールドを編集不可へ
event.record.event_id.disabled = true;
return event;
});
async function publishEvent() {
// レコードのデータの取得
const record = kintone.app.record.get().record;
if (record) {
// Google認証済みのチェック
if (!gapi.auth2.getAuthInstance().isSignedIn.get()) {
// Google認証の呼び出し
await gapi.auth2.getAuthInstance().signIn();
}
// APIリクエスト
// リクエストパラメータの設定
const params = {
// イベントのタイトル
summary: record.event_name.value,
start: {
// 開始日・時刻
dateTime: record.start_datetime.value,
timeZone: 'Asia/Tokyo'
},
end: {
// 終了日・時刻
dateTime: record.end_datetime.value,
timeZone: 'Asia/Tokyo'
},
// 場所の指定
location: record.event_location.value,
// イベントの説明
description: record.event_description.value
};
let request;
// リクエストメソッドとパラメータの設定
if (record.event_id.value) { // 公開済みイベントを更新
request = gapi.client.calendar.events.update(
{
calendarId: calendar_id,
eventId: record.event_id.value,
resource: params
});
} else { // 未公開のイベントを追加
request = gapi.client.calendar.events.insert(
{
calendarId: calendar_id,
resource: params
});
}
// Googleカレンダーへのイベント登録の実行
request.execute((resp) => {
if (resp.error) {
alert('イベントの登録に失敗しました。' + resp.error.message);
} else {
const body = {
app: kintone.app.getId(),
id: record.$id.value,
record: {
event_id: {
value: resp.result.id
}
}
};
return kintone.api(kintone.api.url('/k/v1/record', true), 'PUT', body).then((success) => {
alert('カレンダーにイベントを登録しました。');
location.reload();
}).catch((error) => {
alert('GoogleイベントIDの登録に失敗しました。' + error);
});
}
return true;
}, (error) => {
alert('GoogleイベントIDの登録に失敗しました。' + error);
});
}
}
})();
|
コードのアップロード
固定リンクがコピーされました
作成したコードに適当な名前をつけ、保存します。(例:google-calendar.js)
保存したコードを「アプリの設定」から、「JavaScript/CSSでカスタマイズ」を選択し、アップロードします。
また、Google APIのJavaScriptクライアントを以下のURLを指定して参照します。
https://apis.google.com/js/api.js
設定を「保存」して、「アプリを更新」します。
上記で作成したイベント・フェアカレンダーのアプリを開き、新規イベントを追加します。
イベント情報を入力して、「保存」します。
保存後、「公開する」ボタンをクリックするとGoogleアカウントへの認証画面が表示されるので、メールアドレスとパスワードを入力してGoogleアカウントへログインします。
認証に成功すると登録したイベントがGoogleカレンダーに公開され、GoogleイベントIDが設定されます。
Googleカレンダーを確認するとイベント情報が公開されています。
公開済みのイベントをGoogleカレンダーに同期するには、イベント・フェアカレンダーでイベント情報を更新し、公開ボタンを再びクリックします。
なお、このコードでは削除機能を実装していません。
Google API認証情報の設定
固定リンクがコピーされました
Googleカレンダーの作成・設定
で取得した値を変数にセットします。
api_key
:Google APIキー
client_id
:クライアントID
calendar_id
:カレンダーID
1
2
3
4
5
6
7
8
9
10
|
// APIキー
const api_key = 'Your Google API key';
// クライアントID
const client_id = 'Your Google Client ID';
// カレンダーID
const calendar_id = 'Your Google Calendar ID';
// 認証用URL(読み取り/更新)
const scope = 'https://www.googleapis.com/auth/calendar https://www.googleapis.com/auth/calendar.events';
// Discovery Docs
const discovery_docs = ['https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest'];
|
スコープとディスカバリードックの情報の詳細は
Google Calendar APIのガイド
を参照してください。
Google APIクライアントとOAuth2.0ライブラリ
固定リンクがコピーされました
Google APIのJavaScriptクライアントとOAuth2.0モジュールのライブラリーをロードし、ロード完了時に呼び出すコールバック関数を設定しています。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
// APIクライアントライブラリの初期化とサインイン
function initClient() {
gapi.client.init({
apiKey: api_key,
discoveryDocs: discovery_docs,
clientId: client_id,
scope: scope
}, (error) => {
alert('Googleへの認証に失敗しました。: ' + error);
});
}
// APIクライアントとOAuth2ライブラリのロード
gapi.load('client:auth2', initClient);
|
JavaScriptクライアントとOAuth 2.0の認証情報の詳細に関しましては、
OAuth 2.0 for Client-side web applications
を参照してください。
レコード詳細画面の表示後イベント
固定リンクがコピーされました
レコード詳細画面の表示後イベントは以下の関数内に記述します。
1
|
kintone.events.on('app.record.detail.show', (event) => {});
|
Googleカレンダーにイベントを公開するためのボタンを画面下部スペースに設置します。
イベントリスナーには、ボタンのクリック時に呼び出される関数を設定しています。
1
2
3
4
5
6
7
8
9
10
|
// 画面下部にボタンを設置
const publishButton = document.createElement('button');
publishButton.id = 'publish_button';
publishButton.innerHTML = '公開する';
publishButton.className = 'button-simple-cybozu geo-search-btn';
publishButton.style = 'margin-top: 30px; margin-left: 10px;';
publishButton.addEventListener('click', () => {
publishEvent();
});
kintone.app.record.getSpaceElement('publish_button_space').appendChild(publishButton);
|
レコード追加時、編集時の表示後イベント
固定リンクがコピーされました
GoogleカレンダーのイベントIDは自動設定されるので、レコード追加時および編集時には編集できないように設定しています。
1
2
3
4
5
|
kintone.events.on(['app.record.create.show', 'app.record.edit.show'], (event) => {
// フィールドを編集不可へ
event.record.event_id.disabled = true;
return event;
});
|
Googleカレンダーへのイベント公開
固定リンクがコピーされました
まずは、イベント・フェアカレンダーで設定したレコードのデータを取得します。
1
|
const record = kintone.app.record.get().record;
|
レコードのデータ取得後、Googleアカウントへ認証済みかチェックし、認証済みでない場合は、Google認証画面を呼び出します。
Google APIへの認証は、非同期となるため、非同期関数として宣言し、認証処理を待ちます。
1
2
3
4
5
6
7
8
9
10
|
async function publishEvent() {
// レコードのデータの取得
const record = kintone.app.record.get().record;
if (record) {
// Google認証済みのチェック
if (!gapi.auth2.getAuthInstance().isSignedIn.get()) {
// Google認証の呼び出し
await gapi.auth2.getAuthInstance().signIn();
}
// ...
|
次にGoogleカレンダーへ送るイベントデータのパラメーターをJSON形式で設定します。
イベントデータのパラメーターの設定は、
Google Calendar API ReferenceのEventの項目
を参照してください。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
// リクエストパラメータの設定
const params = {
// イベントのタイトル
summary: record.event_name.value,
start: {
// 開始日・時刻
dateTime: record.start_datetime.value,
timeZone: 'Asia/Tokyo'
},
end: {
// 終了日・時刻
dateTime: record.end_datetime.value,
timeZone: 'Asia/Tokyo'
},
// 場所の指定
location: record.event_location.value,
// イベントの説明
description: record.event_description.value
};
|
イベント・フェアカレンダーのデータに、Google Event IDが設定済みかをチェックします。
設定済みならGoogle Event IDをもとにデータを更新し、未設定ならイベントを追加します。
Googleカレンダーの操作に関するドキュメントは、次を参照してください。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
let request;
// リクエストメソッドとパラメータの設定
if (record.event_id.value) { // 公開済みイベントを更新
request = gapi.client.calendar.events.update(
{
calendarId: calendar_id,
eventId: record.event_id.value,
resource: params
});
} else { // 未公開のイベントを追加
request = gapi.client.calendar.events.insert(
{
calendarId: calendar_id,
resource: params
});
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
// Googleカレンダーへのイベント登録の実行
request.execute((resp) => {
if (resp.error) {
alert('イベントの登録に失敗しました。' + resp.error.message);
} else {
const body = {
app: kintone.app.getId(),
id: record.$id.value,
record: {
event_id: {
value: resp.result.id
}
}
};
return kintone.api(kintone.api.url('/k/v1/record', true), 'PUT', body).then((success) => {
alert('カレンダーにイベントを登録しました。');
location.reload();
}).catch((error) => {
alert('GoogleイベントIDの登録に失敗しました。' + error);
});
}
return true;
}, (error) => {
alert('GoogleイベントIDの登録に失敗しました。' + error);
});
|
上記で設定したリクエストを実行します。Googleカレンダーへの登録実行後、生成されたGoogleカレンダー側のイベントIDを取得し、kintone APIを呼び出し、event_id
フィールドを更新しています。
今回は、kintoneのイベント・フェアカレンダーを使って管理しているイベントの情報を、社内で共有できるようにGoogleカレンダーへ連携してみました。
他のGoogle Workspaceのサービスもkintoneと連携して、kintoneで管理しているさまざまな業務データを社内共有できます。