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 で管理しているさまざまな業務データを社内共有できます。