Googleフォームとkintoneを連携してみよう!

著者名:Mamoru Fujinoki( Fuji Business Software Inc. (External link)

目次

はじめに

アンケートやイベントの出欠、コンタクト情報の収集や各種申し込みフォームなど Googleフォーム (External link) を使うと容易に作成、送信ができます。
今回は、 Google Apps Script (External link) を使って、その回答をすばやくkintoneに登録してみたいと思います。

事前に必要なもの

開発の流れ

  • Googleフォームの作成
  • kintoneアプリの作成
  • Google Apps Scriptによるプログラムの作成

以上の手順で開発していきます。

Googleフォームの作成

Step 1

Googleアカウントにログイン後、右トップメニューのGoogleアプリアイコンより、Googleフォームを選択し(または、 https://docs.google.com/forms/ (External link) から直接ログイン)、「新しいフォームを作成」ー「空白のフォーム」の「+」サインをクリックします。

Step 2

Googleフォームの作成画面が表示されるので、フォームのタイトル、フォームの詳細を以下の例のように入力します。

  • [フォーム名]
    • 求職アプリケーションフォーム
  • [フォームの説明・詳細等]
    • 求職者向けアプリケーションフォームです。

Step 3

設定タブをクリックして、「回答」設定を開き、「メールアドレスを収集する」設定から「回答者からの入力」を選択します。

Step 4

次に「質問」タブをクリックし、「質問設定」に戻ります。
「無題の質問」について、メニューより回答欄のフィールドタイプとして「記述式(短文)」を選択し、質問欄に質問を入力します。

  • [質問]氏名

回答を必須にしたい場合、以下のように「必須」を選択します。

Step 5

以下の画像を参考に質問を追加します。

  • [タイプ]日付、[質問]生年月日
  • [タイプ]チェックボックス、[質問]希望職種、[選択肢]人事、営業、受付、購買
  • [タイプ]プルダウン、[質問]就業形態、[選択肢]正社員、契約社員、パートタイム
  • [タイプ]時刻、[質問]希望就業開始時刻

  • [タイプ]ラジオボタン、[質問]就業経験、[選択肢]有、無
  • [タイプ]ファイルのアップロード、[質問]履歴書

以上でGoogleフォームの完成です。

kintoneアプリの作成

Step 1

kintoneのアプリ作成画面より、「はじめから作成」を選択し、以下の画像を参考にフィールドを追加します。

フィールドの種類 フィールド名 フィールドコード 備考
文字列(1行) 氏名 name 必須項目
文字列(1行) メールアドレス email 必須項目
日付 生年月日 dob
チェックボックス 希望職種 department 選択肢:人事、営業、受け付け、購買
ドロップダウン 就業形態 employment 選択肢:正社員、契約社員、パートタイム
時刻 希望就業開始時刻 start_time
ラジオボタン 就業経験 experience 選択肢:有、無
添付ファイル 履歴書 resume

Step 2

次にアプリの設定画面より、「APIトークン」を作成します。

「APIトークン」設定画面より、「生成する」ボタンをクリックし、「アクセス権」に「レコード追加」をチェックして「保存」します。

アプリの設定画面に戻ったら、「アプリを更新」をクリックして、変更した設定をアプリに反映します。

以上で、アプリの完成です。

プログラムの作成

Step 1

上記で作成したGoogleフォームを再び開き、「その他」メニューから「Apps Script」をクリックします。

以下の画面が開くので、プロジェクト名、ファイル名を入力します。

Step 2

manifestファイルに、OAuth scopeを記載します。

プロジェクトの設定ボタンから 「appsscript.json」マニフェスト ファイルをエディタで表示する にチェックを入れます。

エディタに戻り、appsscript.jsonに、次のようにOAuth scopeを追加します。

最後の要素に追記する場合には、末尾のカンマ(,)は不要です。

1
"oauthScopes": ["https://www.googleapis.com/auth/forms","https://www.googleapis.com/auth/forms.currentonly", "https://www.googleapis.com/auth/script.external_request","https://www.googleapis.com/auth/drive"],

Step 3

下記を参考にコーディングします。

 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
/*
 * Googleフォームとkintoneを連携するサンプルプログラム
 * Copyright (c) 2025 Cybozu
 *
 * Licensed under the MIT License
 * https://opensource.org/license/mit/
 */
// フォームの回答を取得する関数
function getFormResponse() {
  // アクティブなフォームを取得
  const form = FormApp.getActiveForm();
  // フォームの回答を取得
  const formResponses = form.getResponses();
  // 最新のフォームの回答を取得
  const latestResponse = formResponses[formResponses.length - 1];
  const records = {};
  // 回答者のEmailアドレスの取得
  records.email = {value: latestResponse.getRespondentEmail()};
  // フォーム内の質問回答事項を取得
  const itemResponses = latestResponse.getItemResponses();
  // ループして質問事項と各回答を取得
  itemResponses.forEach(itemResponse => {
    switch (itemResponse.getItem().getTitle()) {
      case '氏名':
        records.name = {value: itemResponse.getResponse()};// 氏名の回答を取得
        break;
      case '生年月日':
        records.dob = {value: itemResponse.getResponse()}; // 生年月日の回答を取得
        break;
      case '希望職種':
        records.department = {value: JSON.parse(JSON.stringify([].concat(...itemResponse.getResponse())))}; // 希望職種の複数回答を取得
        break;
      case '就業形態':
        records.employment = {value: itemResponse.getResponse()}; // 就業形態の回答を取得
        break;
      case '希望就業開始時刻':
        records.start_time = {value: itemResponse.getResponse()}; // 希望就業開始時刻の回答を取得
        break;
      case '就業経験':
        records.experience = {value: itemResponse.getResponse()}; // 就業経験の回答を取得
        break;
      case '履歴書':
        // 質問のタイプがファイルアップロードかチェック
        if (itemResponse.getItem().getType() === FormApp.ItemType.FILE_UPLOAD) {
          const fileIds = itemResponse.getResponse(); // ファイルIDの配列を取得
          // Google Driveよりファイルの詳細を取得
          const file = DriveApp.getFileById(fileIds[0]);
          // ファイル内容をBlob形式で取得
          const blob = file.getBlob();
          const fileKey = uploadFile(blob);
          if (fileKey !== null) {
            fileKey.contentType = blob.getContentType();
            fileKey.name = blob.getName();
            fileKey.size = blob.getBytes().length;
            records.resume = {value: [fileKey]};
          }
        }
        break;
    }
  });
  return records;
}
// フォームの回答をkinotneに送信する関数
function sendToKintone() {
  Logger.log('Form submitted');
  const subdomain = '{subdomain}.cybozu.com/k/v1/records.json';// リソースURL
  // フォームの回答を取得
  const formResponse = getFormResponse();
  const records = {app: アプリID, records: [formResponse]};
  // POSTリクエストを作成
  const options = {
    method: 'post',
    contentType: 'application/json',
    // JavaScriptオブジェクトをJSON文字列に変換
    payload: JSON.stringify(records),
    headers: {'X-Cybozu-API-Token': 'kintoneアプリのAPIトークン'},
  };
  // POSTリクエストを実行
  const response = UrlFetchApp.fetch(subdomain, options);
  Logger.log('Response is "%s"', response.getContentText());
}
// 添付ファイルをkintoneにアップロードする関数
function uploadFile(blob) {
  const formData = {
    file: blob
  };
  const url = '{subdomain}.cybozu.com/k/v1/file.json';// リソースURL
  const options = {
    method: 'post',
    payload: formData,
    headers: {'X-Requested-With': 'XMLHttpRequest', 'X-Cybozu-API-Token': 'kintoneアプリのAPIトークン'},
  };
  const response = UrlFetchApp.fetch(url, options);
  return JSON.parse(response.getContentText()); // FileKeyをリターン
}

コーディング終了後、保存します。

解説
Googleフォームの回答を取得

以下のAPI関数でまず、アクティブなフォーム(回答が送信されたフォーム)を取得します。

FormApp.getActiveForm()

12
13
// アクティブなフォームを取得
const form = FormApp.getActiveForm();

以下のAPI関数で、フォーム送信時の回答のデータを取得します。

form.getResponses();

14
15
16
17
// フォームの回答を取得
const formResponses = form.getResponses();
// 最新のフォームの回答を取得
const latestResponse = formResponses[formResponses.length - 1];

kintoneへ送信するJSON形式のデータを作成します。
回答者のメールアドレスは以下のAPI関数により取得できます。

latestResponse.getRespondentEmail();

17
18
19
const records = {};
// 回答者のEmailアドレスの取得
records.email = {value: latestResponse.getRespondentEmail()};

フォーム内の質問回答事項の詳細を取得します。

latestResponse.getItemResponses();

21
22
// フォーム内の質問回答事項を取得
const itemResponses = latestResponse.getItemResponses();

ループして、各質問事項と回答を取得します。

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
// ループして質問事項と各回答を取得
itemResponses.forEach(itemResponse => {
  switch (itemResponse.getItem().getTitle()) {
    case '氏名':
      records.name = {value: itemResponse.getResponse()};// 氏名の回答を取得
      break;
    case '生年月日':
      records.dob = {value: itemResponse.getResponse()}; // 生年月日の回答を取得
      break;
    case '希望職種':
      records.department = {value: JSON.parse(JSON.stringify([].concat(...itemResponse.getResponse())))}; // 希望職種の複数回答を取得
      break;
    case '就業形態':
      records.employment = {value: itemResponse.getResponse()}; // 就業形態の回答を取得
      break;
    case '希望就業開始時刻':
      records.start_time = {value: itemResponse.getResponse()}; // 希望就業開始時刻の回答を取得
      break;
    case '就業経験':
      records.experience = {value: itemResponse.getResponse()}; // 就業経験の回答を取得
      break;
    // ***
    // ***
  }
});

kintoneへ送信するリクエストデータのJSON形式の詳細は 1件のレコードを登録する を参照してください。

Googleドライブにアップロードされたファイルデータを取得

Google Driveにアップロードされたファイルデータを取得し、kintoneへアップロードしてFile Keyを設定します。

44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
// 質問のタイプがファイルアップロードかチェック
if (itemResponse.getItem().getType() === FormApp.ItemType.FILE_UPLOAD) {
  const fileIds = itemResponse.getResponse(); // ファイルIDの配列を取得
  // Google Driveよりファイルの詳細を取得
  const file = DriveApp.getFileById(fileIds[0]);
  // ファイル内容をBlob形式で取得
  const blob = file.getBlob();
  const fileKey = uploadFile(blob);
  if (fileKey !== null) {
    fileKey.contentType = blob.getContentType();
    fileKey.name = blob.getName();
    fileKey.size = blob.getBytes().length;
    records.resume = {value: [fileKey]};
  }
}
ファイルデータをkintoneにアップロード

Googleドライイブから取得したファイルデータをkintoneにアップロードします。
取得したFile Keyをリターンします。

85
86
87
88
89
90
91
92
93
94
95
96
97
98
// 添付ファイルをkintoneにアップロードする関数
function uploadFile(blob) {
  const formData = {
    file: blob
  };
  const url = '{subdomain}.cybozu.com/k/v1/file.json';// リソースURL
  const options = {
    method: 'post',
    payload: formData,
    headers: {'X-Requested-With': 'XMLHttpRequest', 'X-Cybozu-API-Token': 'kintoneアプリのAPIトークン'},
  };
  const response = UrlFetchApp.fetch(url, options);
  return JSON.parse(response.getContentText()); // FileKeyをリターン
}
kintoneへデータを送信

上記で作成したkintoneアプリの情報を設定します。

65
66
67
68
69
70
71
72
73
74
75
const subdomain = '{subdomain}.cybozu.com/k/v1/records.json';// リソースURL
// ***
const records = {app: アプリID, records: [formResponse]};
// POSTリクエストを作成
const options = {
  method: 'post',
  contentType: 'application/json',
  // JavaScriptオブジェクトをJSON文字列に変換
  payload: JSON.stringify(records),
  headers: {'X-Cybozu-API-Token': 'kintoneアプリのAPIトークン'},
};

次のAPI関数でkintoneへデータを送信します。

UrlFetchApp.fetch(url, options);

82
const response = UrlFetchApp.fetch(url, options);

次の形式でレスポンスが返ってくれば成功です。

{"ids":["レコードID"],"revisions":["リビジョン番号"]}

83
Logger.log('Response is "%s"', response.getContentText());

Step 4

トリガーの設定画面を表示し、[トリガーを追加]からトリガーを追加します。

イベント発生時に実行する関数、トリガーとなるイベントを設定し、保存します。

以上でGoogle Apps Scriptの設定は完了です。

動作の確認

作成したGoogleフォームの右上の「公開」ボタンをクリックし、「フォームの公開」画面にて「公開」ボタンをクリックします。

再び「公開」ボタンをクリックし、「回答者へのリンクをコピー」をクリックし、「コピー」をクリックします。

新しいブラウザーを開き、コピーしたリンクを貼り付け、回答者向けGoogleフォームを開きます。

回答を入力し、「送信」ボタンをクリックして、回答を送信します。

送信後、回答したレコードがkintoneに登録されていれば動作確認完了です。

まとめ

Googleフォームを使うとアンケートやイベントの出欠、コンタクト情報の収集や各種申し込みフォームなど簡単に作成できる上、EmailやSNSで送信したり、自社のサイトにフォームを埋め込むことも可能です。
その回答をkintoneアプリに自動的に記録することによって結果を効率的に管理できるのではないでしょうか。

参照サイト

information

このTipsは、2025年3月版kintoneで動作を確認しています。