cybozu developer network

カテゴリー内の他の記事

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

(Author : Fuji Business International Mamoru Fujinoki)

はじめに

アンケートやイベントの出欠など Google フォーム を使うと容易に作成、送信が出来ます。今回は、Google Apps Script を使って、その回答を素早くkintoneに登録してみたいと思います。

1. 事前に必要なもの

  • Googleアカウント
  • kintoneアカウント ※開発者ライセンスの取得方法はこちら

2. 開発の流れ

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

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

3. Googleフォームの作成

Step 1

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

001.png

Step 2

Googleフォームの作成画面が表示されるので、フォームのタイトル、フォームの詳細を以下の例のように入力します。
例:
[フォーム名]
Kintone Connect-to-Play LA Vol.1 −Cybozu サイボウズ−
[フォームの説明・詳細等]
Date: 7/13/2017, 6:30 PM - 9:00 PM
Event Address: 21515 Hawthorne Boulevard, Torrance, CA, 90503, US

002.png

Step 3

設定アイコンをクリックして、「メールアドレスを収集する」をチェックし、変更を保存します。

003.png

Step 4

次に「無題の質問」について、メニューより質問のタイプとして「ラジオボタン」を選択し、質問欄に質問を入力、回答の選択肢を以下のように入力します。
※記号[?]は半角で入力してください。

[質問]参加しますか?
[解答例]
• はい、参加します
• いいえ、参加できません

004.png


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

005.png

Step 5

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

  • [タイプ]記述式、[質問]参加人数、[必須選択]
  • [タイプ]段落、[質問]参加者の名前を記入してください

006.png

 

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

4. kintoneアプリの作成

Step 6

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

010.png

 

フィールドの種類 フィールド名 フィールドコード
リンク(入力値の種類:メールアドレス) メールアドレス Email
ラジオボタン 参加しますか? attend
数値 参加人数 number_of_attendee
文字列(複数行) 参加者名 name_of_attendee

Step 7

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

008.png

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

009.png

 

アプリの設定画面に戻ったら、「アプリを公開」をクリックして、作成したアプリを公開します。

011.png

 

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

5. プログラムの作成

Step 8

上記で作成したGoogleフォームを再び開き、「その他」メニューから「スクリプトエディタ」をクリックします。

012.png

 

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

013.png

Step 9

kintone API呼び出しのライブラリが公開されているので、今回はこれを利用させていただきます。
Qiita Tip: kintone とGoogle Apps Script連携

「ライブラリを追加」をクリックします。
Google Apps Script Library for kintone の README.md にある「Script ID (For New editor)」の値を「スクリプト ID」欄に入力し、「検索」ボタンでライブラリを検索します。
ライブラリが表示されたら、最新のバージョンを選択し、「追加」をクリックします。

script_id.png

Step 10

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

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

015.png

 

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

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

016.png

Step 11

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

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

 

【解説】

[Google フォームの回答を取得]

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

e.response.getItemResponse();

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

e.reponse.getRespondentEmail();

kintoneへ送信するリクエストデータのJSON形式の詳細はこちらを参照してください。

 

[kintoneへデータを送信]

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

先ほど設定したkintone API連携用ライブラリを初期化し、上記関数で作成した、Google フォームの回答データを文字列からJSON形式に変換し、kintone へデータを送信します。

レスポンスのコードが200であれば送信成功です。

Step 12

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

017.png

 

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

018.png

 

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

6. 動作の確認

作成したGoogle フォームの右上の送信ボタンをクリックし、「フォームを送信」画面にて送信先のメールアドレス、件名、メッセージを入力し、送信ボタンでフォームを送信します。

019.png

 

メールに届いたGoogleフォームへのリンクより、回答を入力し送信します。

020.png

 

送信後、回答したデータがkintoneに記録されました。

021.png

7. まとめ

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

8. 参照サイト

更新履歴

  • 2020/2/18
    • Google Formsの仕様変更により、
      OAuth scope の記載が必要となったため、manifest ファイルに OAuth scope の記載を追加
  • 2021/4/6
    • Google Apps Script の UI 変更に伴い、画像を差し替え

記事に関するフィードバック

記事のコメント欄は記事に対するフィードバックをする場となっております。
右の記事フィードバックのためのガイドを参照してコメントしてください。
記事のリンク切れなど、気になる点がある場合も、こちらのフォームからフィードバックいただけますと幸いです。

Avatar
NORTH

お世話になります。
まさにGoogleFormsからkintoneに格納できないかと探っていたところこの記事にたどり着き、格納することが出来ました。
ありがとうございます。

そこで一点ご質問なのですが、この記事で言うとGoogleForms側の「参加者の名前を記入してください」のところ、
段落のタイプで複数行を想定されているかと思うのですが、ここに複数行のテキストを入力し送信すると
「SyntaxError: String contains control character」といわれてkintoneに格納できませんでした。
改行しないで送信すると格納可能です。

おそらく受け渡されるデータの型がJESONと合っていないものと思われますが、
いい解決方法はございますでしょうか?

いい解決法をご存知でしたらご教示いただけましたら幸いです。

Avatar
cybozu Development team

NORTH 様

お世話になっております。

返事が遅くなりまして申し訳ございません。

38行の後、次のように改行コードを変換するソースコードを追加することでkintoneに登録できることを確認しました。
var str = getFormResponse(e);
str = str.replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t");
var records = JSON.parse(str);// JSON形式に変換

ご確認お願い致します。

Avatar
NORTH

cybozu Development team さま

お世話になります。ご回答いただきありがとうございました。
頂きました件テストをしてみたところ無事格納出来ることを確認いたしました。

ありがとうございました!
ぜひ活用させていただきたく存じます。

Avatar
hide

Cybozu Development team さま

お世話になります。

記事を参考にしながら行なっているのですが、どうしても下記のメッセージが表示され先に進む事ができません。

お手数お掛けしますが、解決方法をご教授頂けませんでしょうか。




Avatar
cybozu Development team

hide 様

お世話になっております。

cybozu developer network 事務局です。

該当のエラーですが、変数「e」はイベントオブジェクトであり、

トリガーで選択した、「フォームからフォーム送信時」に値が入る変数です。

(実際にフォームに情報が入力され、回答が送信されたときにイベントオブジェクトが発生します。)

 

ですので、エラーに関してはそのままで次のステップに進んで問題ありません。

 

なお、仕様以外の技術的な質問に関してはコミュニティをご活用いただければ幸いです。

Avatar
hide

cybozu Development team 様

お世話になります。
内容了解いたしました。
仕様以外でのコミュニティへの投稿も了解いたしました。申し訳ございません。

Avatar
Satoshi Oda

Cybozu Development team 様

お世話になります。

追加でチェックボックスを使ってカスタマイズすると、Kintoneへデータが追加できません。

チェックボックスに何もチェックせずに登録するとうまく出来ます。

対処法はありますでしょうか。初心者なものですみません。

Avatar
cybozu Development team

Oda様

本記事を参考に、

Step6にフィールドを追加し、Step 10のサンプルコードの23行目以降にコードを追加すれば動作すると思いますが、

kintoneアプリ側に追加したフィールドコードにお間違いはないでしょうか。

なお、デバッグなど、仕様以外の技術的な質問に関してはコミュニティをご活用いただければ幸いです。

 

Avatar
Satoshi Oda

Cybozu Development team 様

 無事に動作できました。

 コードの部分に細かい誤りがありました…。

 Googleフォーム上チェックボックスは、Kintoneではチェックボックスではなくて記述欄にしないと飛ばせないんですね。

 ありがとうございました。

Avatar
H_ishi
お世話になります。
アンケート結果を反映したいと考えていますが、記事の手順に従ってもうまく反映がされていません。
お手数をお掛けしますが、解決方法をご教授願えますでしょうか?
以下コードです。
 
function getFormResponse(e) {
    'use strict';
    var itemResponses = e.response.getItemResponses();// アンケートの回答を取得
    var records = '[';
    // 回答者のEmailアドレスの取得
    records += Utilities.formatString('{"Email": { "value": "%s" }', e.response.getRespondentEmail());
 
    for (var i = 0; i < itemResponses.length; i++) {
        var itemResponse = itemResponses[i];
        records += ',';
        switch (itemResponse.getItem().getTitle()) {
            case '参加しますか?':
                records += Utilities.formatString('"attend" : { "value": "%s" }',
                    itemResponse.getResponse());// 質問に対する回答を取得
                break;
            case '参加人数':
                records += Utilities.formatString('"number_of_attendee" : { "value": "%s" }',
                    itemResponse.getResponse());// 質問に対する回答を取得
                break;
            case '参加者の名前を記入してください':
                records += Utilities.formatString('"name_of_attendee" : { "value": "%s" }',
                    itemResponse.getResponse());// 質問に対する回答を取得
                break;
        }
    }
    records += '}]';
    Logger.log('Response JSON is "%s"', records);
    return records;
}
 
function sendToKintone(e) {
    'use strict';
    Logger.log('Form submitted');
    var subdomain = '36';// サブドメイン名
    var apps = {
        YOUR_APPLICATION1: { appid:2, name: 'kintone Meetup 参加者', token: 'fXmGQaLcJ9aaO0dLwRwKIBN' }
    };
    var manager = new KintoneManager.KintoneManager(subdomain, apps);// ライブラリーの初期化
    var str = getFormResponse(e);
    str = str.replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t");
    var records = JSON.parse(str);// JSON形式に変換
    var response = manager.create('YOUR_APPLICATION1', records);// kintone レコードの生成
    // ステータスコード
    // 成功すれば200になる
    var code = response.getResponseCode();
    Logger.log('Response code is "%s"', code);
}
Avatar
cybozu Development team

H_ishi 様

お世話になっております。developer network事務局です。

記述していただいたプログラムを見たところ、サブドメインの指定が間違っているように見受けられました。

 

34行目 「var subdomain = '36';// サブドメイン名」

のところですが、こちら36というサブドメインで合っていますでしょうか。

サブドメインはブラウザでkintoneを開いて頂いたときのURL「○○.cybozu.com」の○○部分にあたります。

 

また、こちらのコメント等に記載する際は、サブドメインは伏せ字で記載していただくことをおすすめします。

 

お手数をおかけして申し訳ありません。

上記の内容について、ご確認のほどよろしくお願いいたします。

Avatar
H_ishi

Cybozu Development team 様

ありがとうございます。また、返事が遅くなり申し訳ありません。

サブドメインについては当方のサブドメインを使用しています。

書き込んだものは架空のものを使用しております。説明が足らず申し訳ありません。

コードがあっているとすると、他の問題ということでしょうか?

一度こちらでもやってみたいと思います。

Avatar
cybozu Development team

H_ishiさま

お世話になっております。cybozu developer network事務局です。

ご確認いただきありがとうございました。

弊社環境でも確認した結果、フォームのデータは取得できているもののkintoneに反映されないという現象を確認いたしました。

大変申し訳ございません。

これから詳細な確認を行いますが、場合によってはお時間がかかる可能性がございます。

ご不便をおかけして申し訳ございませんが、今しばらくお待ちいただけますようお願い申し上げます。

 

Avatar
H_ishi

Cybozu Development team 様

ありがとうございます。

よろしくお願いいたします。

Avatar
cybozu Development team

H_ishi様

お世話になっております。cybozu developer network事務局です。

大変お待たせいたしました。ソースコードを修正し、記事に反映しました。
お手数ですがご確認よろしくお願いいたします。

Avatar
H_ishi

Cybozu Development team 様

遅くなって申し訳ありません。

変更内容確認できました。

ありがとうございました。

Avatar
RYOSUKE

すみません、追加で質問をさせていただきます。

Step9 のところで、プロジェクトキーが使用できないようなので、スクリプトIDから、添付画像の KintoneLib を選択しました。

35行目は以下としました。subdomain, appsの設定は間違いないと思います。

var manager = new KintoneLib.KintoneLib(subdomain, apps);// ライブラリーの初期化

としても、kintoneアプリ側にはデータが収集されない状態です。

Google回答側には、きちんとデータは集計されております。

何かご指摘などありましたら、ご教授願います。

 

Avatar
cybozu Development team

RYOSUKE 様

お世話になっております。cybozu developer network事務局です。

こちらで動作確認を行ったところ、「KintoneManager」というライブラリが正しく追加されました。

入力されたプロジェクトキーは、

MDT2NQ9jkAGYJ-7ftp_A0v08CaFRWuzzx

でお間違いないでしょうか?

また、RYOSUKE 様が使用されている添付画像の「KintoneLib」というライブラリは、
記事で使用している「KintoneManager」とは異なるライブラリです。
「KintoneLib」をご利用される場合は、コードの書き換えが必要となります。
ご質問はcybozu developer コミュニティをご活用ください。

Avatar
s-oono

kinntone側にレコード登録されないのですが、

間違っている箇所はございますでしょうか。

 

お知恵をお借りできますと幸いです。

 

function getFormResponse(e) {
'use strict';
var itemResponses = e.response.getItemResponses();//フォームの入力内容を取得
var records = '[';
for (var i = 0; i < itemResponses.length; i++) {
var itemResponse = itemResponses[i];
switch (itemResponse.getItem().getTitle()) {
case "メールアドレス":
records += Utilities.formatString(',"メールアドレス" : { "value": "%s" }',
itemResponse.getResponse());//質問に対する回答を取得
break;
case "お名前":
records += Utilities.formatString(',"お名前" : { "value": "%s" }',
itemResponse.getResponse());//質問に対する回答を取得
break;
case "フリガナ":
records += Utilities.formatString(',"フリガナ" : { "value": "%s" }',
itemResponse.getResponse());//質問に対する回答を取得
break;
case "ご住所":
records += Utilities.formatString(',"ご住所" : { "value": "%s" }',
itemResponse.getResponse());//質問に対する回答を取得
break;
case "電話番号":
records += Utilities.formatString(',"電話番号" : { "value": "%s" }',
itemResponse.getResponse());//質問に対する回答を取得
break;
}
}
records += '}]';
Logger.log('Response JSON is "%s"', records);
return records;
}

function sendToKintone(e) {
'use strict';
Logger.log('Form submitted');
var subdomain = 'サブドメイン';//サブドメイン名
var apps = {
"YOUR_APPLICATION1": { appid:アプリID, name: 'アプリ名', token: 'トークンID' }
};
var manager = new KintoneManager.KintoneManager(subdomain, apps);// ライブラリーの初期化
var str = getFormResponse(e);
str = str.replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t");
var records = JSON.parse('"str"');//JSON形式に変換
var response = manager.create("YOUR_APPLICATION1", records);//kintone レコードの生成
// ステータスコード
// 成功すれば200になる
var code = response.getResponseCode();
Logger.log('Response code is "%s"', code);
}

Avatar
cybozu Development team

s-oono様

function getFormResponse()の内容が記事と異なるようですので、

記事のシナリオと異なる場合のご質問はcybozu developer コミュニティをご活用ください。

また、質問の際は、開発者ツールでどのようなエラーが出ているか提示すると返信がつきやすいかと存じます。

エラーの確認方法は、こちらの記事 を参考にしてください。

Avatar
s-oono

ご連絡ありがとうございます。コミュニティにて質問してみます。

Avatar
R_KATA

1)Googleフォームでラジオボタンを設置。

 

2)Googleスクリプトで以下を記述。

 

3)Kintoneアプリ上でラジオボタンを設置。

 

 

4)以下の結果となります。

その他、上記以外の質問項目は正常にレコードが追加されますが、

ラジオボタン(他のラジオボタンも同様)の質問のみ、すべて「いいえ」で回答しても

レコード追加時には、「はい」で追加されてしまう。

Kintoneのフォーム設定で初期値を「はい」にしているためでしょうか。

何か解決策ががあればご教授ください。

またGoogleフォームの回答自体は、「いいえ」で得られております。

Avatar
cybozu Development team

R_KATA様

お世話になっております。cybozu developer network事務局です。

返事が遅くなり申し訳ありませんでした。

 

弊社環境でも確認した結果、常にラジオボタンの初期値で登録される現象を確認いたしました。

原因はサンプルソースコード9行目、「case "参加しますか?":」の?が全角になっていたことを判明しました。

?は半角でないとなりません。

サンプルソースコードを修正いたしましたので、

お手元のソースコードも同じ修正していただいてから再度ご確認いただけますでしょうか。

よろしくお願いいたします。

 

Avatar
R_KATA

cybozu developer network事務局様

ご対応ありがとうございます。

解決いたしました。

句読点などは全角で問題ないのですね。

ありがとうございました。

Avatar
Takeshi Komiya

お世話になります。
こちらの記事を参考に弊社では問い合わせフォームを作らせていただきました。

ご質問なのですが、弊社の問い合わせフォームでは社内用のためメールアドレスの収集が不要になっております。そのため、メールアドレスの入力が不要の方法をご教授願えないでしょうか。

よろしくお願いいたします。

Avatar
cybozu Development team

Takeshi Komiya 様

お世話になっております。cybozu developer network運営チームです。

メールアドレスの収集が不要の場合、

  • Googleフォーム
  • kintoneアプリ
  • Google Apps Script

のそれぞれの設定の変更が必要になります。

申し訳ございませんが、記事とシナリオと異なる場合、コミュニティでの質問をお願いしております。

恐れ入りますが、以下のコミュニティで再度ご投稿いただけますでしょうか
JavaScript developer向けフォーラム
https://developer.cybozu.io/hc/ja/community/topics/20003434

よろしくお願い申し上げます。

Avatar
Takeshi Komiya

cybozu Development team

かしこまりました。

コミュニティにてお聞きしたいと思います。

Avatar
本田翔也

お世話になります。

こちらのドキュメントを参考にしながら、

kintoneとgoogleフォームの連携を行い、

成功したのですが、

googleの検証ツールのコンソールに

「Uncaught Could not establish connection. Receiving end does not exist.」という

エラーが表示され続けます。

サンプルコードに忠実にコードを書き、

何点か思いつく修正もしたのですが改善はされませんでした。

kintoneにデータの記録ができていることを考えると、

このエラーはkintoneから返された値をgoogleフォームで表示できないという

エラーではないかを予想しました。

これはそのような解釈で良いでしょうか。

 

こちらがコードです

 

 

Avatar
cybozu Development team

本田翔也 様

お世話になっております。cybozu developer network運営チームです。
返信遅くなり申し訳ございません。

こちら確認をしたところ、GoogleForms側に仕様変更があり、エラーが出ているようでした。
現在調査中ですので、少々お待ちください。詳細分かり次第、再度ご連絡いたします。

Avatar
本田翔也

cybouz Deveklopment team 様

お世話になっています。

エラーの件、了解いたしました。

 

 

 

 

 

 

サインインしてコメントを残してください。