kintoneのデータをGoogleスプレッドシートで見たい、シートに溜まった申込をkintoneに入れたい、という相談は多いです。kintoneの標準機能には、スプレッドシートと自動で同期する設定はありません。つなぐ方法は、CSVを手で受け渡す、Apps ScriptからREST APIを呼ぶ、連携サービスを入れる、iPaaSを使う、の4つです。この記事では、どちらを正にするかを先に決めたうえで、CSVの手順、Apps Scriptで取得と登録をするコード、定期実行、制限まで通して書きます。アプリ管理権限があり、kintoneのスタンダードコース以上を契約していることを前提にしています。
この記事の内容
なぜスプレッドシートとつなぐのか
つなぎたい理由は、だいたい次の3つです。理由によって向きと方法が変わります。
| 理由 | 向き | よくある例 |
|---|---|---|
| 集計 | kintone → シート | 案件の金額を担当者別、月別に好きな形で集計する。ピボットテーブルや関数で加工する |
| 共有 | kintone → シート | kintoneのアカウントを持たない社外の人や役員に、決まった列だけを見せる |
| 外部とのやり取り | シート → kintone | 取引先や別部署がシートに書いた申込、フォームの回答をkintoneに取り込む |
集計と共有はkintoneからシートへ、外部とのやり取りはシートからkintoneへの一方通行で足ります。両方向を自動でつなぐ必要がある場面は、実際にはほとんどありません。
先に決めること
どちらを正にするか
一番大事なのはここです。同じデータが2か所にあるとき、食い違ったらどちらを信じるかを決めておきます。正にするのはkintoneです。
シートは誰でもセルを書き換えられ、並べ替えや削除の記録も残りにくい道具です。kintoneはアクセス権で編集できる人を絞れて、レコードごとに変更履歴が残ります。シートを正にすると、誰がいつ数字を変えたのかが追えなくなります。
決めるルールは次の3つです。
- kintoneから書き出したシートは、見るための写しにする。シートで値を直しても、kintoneには戻さない
- 値を直すときはkintoneで直し、次の書き出しでシートに反映させる
- シートからkintoneに入れる場合、シートは受付の入口にすぎない。kintoneに入った時点で、正はkintoneに移る
写しのシートは保護をかけて編集できる人を絞り、シート名に「kintoneの写し」と入れておきます。
向きは片方向にする
両方で編集でき、どちらで直しても相手に反映される作りは避けます。同時に直したときにどちらを残すか、消したら相手も消すのか、という判断を全部コードで書くことになり、壊れたときに直せる人がいなくなります。向きは1本のつなぎごとに片方向にします。
方法を選ぶ
| 方法 | 向いている場面 | 手間 | 費用 |
|---|---|---|---|
| 手動(CSVの書き出しと取り込み) | 月に数回、決まった人が更新する | 毎回の手作業 | 追加なし |
| Apps Script+REST API | 毎日や毎時の自動更新。社内にコードを読める人がいる | 最初の作り込み | 追加なし |
| 連携サービス(プラグインや外部の連携製品) | コードを持ちたくない。サポートが欲しい | 設定のみ | 製品ごとの月額 |
| iPaaS(ZapierやPower Automateなど) | Googleとkintone以外のサービスもまとめてつなぐ | 画面で組む | サービスごとの月額 |
迷ったら、まずCSVで1か月回します。手作業が負担になったころには、何をどの頻度で動かしたいかがはっきりしているので、同じことをApps Scriptで自動にします。
コースを確かめる
APIトークン、Webhook、Power Automateとの連携は、ライトコースでは使えません。kintoneの料金ページでも、外部サービス連携やプラグインなどの拡張機能はライトコースが非対応、スタンダードコースとワイドコースが対応と書かれています。料金は1ユーザーあたり月額でライトコースが1,000円、スタンダードコースが1,800円(どちらも税抜、最小10ユーザー)です。ライトコースのままなら、この記事の方法のうち使えるのは手動のCSVだけです。
設計表
この記事では2つのつなぎを例にします。1つは「案件管理」アプリの案件を毎朝シートに書き出して集計するつなぎ、もう1つはシートに溜まる問い合わせを「問い合わせ管理」アプリに登録するつなぎです。
案件管理(kintone → シート)
| フィールド名 | 種類 | 設定 |
|---|---|---|
| 案件名 | 文字列(1行) | 必須 |
| 顧客名 | 文字列(1行) | 顧客マスタがあるならルックアップ |
| 担当者 | ユーザー選択 | 必須 |
| 金額 | 数値 | 桁区切りの表示は任意。書き出しには影響しない |
| 受注予定日 | 日付 | 月別の集計に使う |
| 進捗 | ドロップダウン | 見込み/提案中/受注/失注 |
| 更新日時 | 更新日時 | 差分だけ取るときの条件に使う |
フィールドコードはスクリプトの中で使います。フィールド名と同じ文字にそろえておくと、コードを読むときに迷いません。
問い合わせ管理(シート → kintone)
| フィールド名 | 種類 | 設定 |
|---|---|---|
| 受付ID | 文字列(1行) | 必須。「値の重複を禁止する」をオン。二重登録を防ぐキー |
| 受信日時 | 日時 | シートの受信日時を入れる |
| 氏名 | 文字列(1行) | 必須 |
| メールアドレス | 文字列(1行) | 返信に使う |
| 問い合わせ内容 | 文字列(複数行) | |
| 対応状況 | ドロップダウン | 未対応/対応中/完了。初期値は未対応 |
受付シートの列
| 列 | 中身 | 誰が書くか |
|---|---|---|
| 受信日時 | 問い合わせを受けた日時 | 入力者、またはフォーム |
| 氏名、メールアドレス、問い合わせ内容 | 本文 | 入力者、またはフォーム |
| 受付ID | 1行ごとに一意な番号 | スクリプト(空なら振る) |
| kintone登録 | 登録した日時 | スクリプト(入っている行は送らない) |
受付IDとkintone登録の2列は、人が書かない列です。列の見出しに色を付けるか、保護をかけて、入力者が触らないようにします。
手動でつなぐ(CSVの書き出しと取り込み)
kintoneから書き出す
書き出されるのは、レコードの一覧画面に出ているレコードです。先に一覧や絞り込みで、必要なレコードだけが出ている状態にします。
- 案件管理のレコードの一覧を開き、書き出したいレコードが出ている一覧を選びます。
- 右上の「オプション」アイコンをクリックします。
- 「ファイルに書き出す」をクリックします。
- 「先頭行を項目名にする」にチェックが入っていることを確かめます。
- 「文字コード」を選びます。スプレッドシートで開くならUTF-8かBOM付きUTF-8にします。
- 「区切り文字」で「カンマ」を選びます。
- 書き出すフィールドをドラッグして並べます。全部なら「すべて追加」をクリックします。
- 「書き出す」をクリックします。
- 「出力されたファイル」の画面が開くので、処理が終わったらファイル名をクリックしてダウンロードします。
「ファイルに書き出す」が出てこないときは、アプリのアクセス権で「ファイル書き出し」の権限がありません。初期状態ではアプリの作成者にしかこの権限がないので、書き出す担当者に付けておきます。

「出力オプション」には、ユーザーや組織を表示名で出す「ユーザー、組織、グループを表示名で出力する」があります。シートで人に見せるならチェックを入れます。ただし表示名で書き出したファイルは、ユーザー選択の値としてkintoneに読み込み直せません。読み込みに使うファイルは、ログイン名のまま書き出します。
文字コードは、BOM付きUTF-8がExcel向け、UTF-8が異体字や記号、絵文字を含むデータ向けと案内されています。スプレッドシートならUTF-8系を選んでおけば困りません。
書き出したファイルの仕様
シートに取り込んでから「列が多い」「行が増えた」と慌てないように、書き出しの仕様を押さえておきます。
| 項目 | 書き出され方 |
|---|---|
| 対象のレコード | レコードの一覧に出ているレコード。閲覧権限のないレコードとフィールドは出ない |
| 数値、計算 | 桁区切りと単位記号は付かない |
| チェックボックス、複数選択 | 選択肢ごとに1列。選ばれていれば「1」 |
| 日付、日時 | 月と日は0埋め。並びは書き出した人の表示言語で変わる(日本語なら年/月/日) |
| テーブル | 1レコードが複数行になる。1列目に「*」がある行がレコードの始まり |
| ラベル、添付ファイル、関連レコード一覧、変更履歴 | 書き出せない |
| ファイルの大きさ | 100MBを超えると書き出しに失敗する |
| 保存期間 | 書き出しを始めてから3日間ダウンロードできる |
テーブルのあるアプリは、テーブル以外の値が行ごとに繰り返されるので、そのままシートで合計すると金額が行数ぶん重なります。テーブルの明細を集計したいときは、テーブルの列だけを使い、親の値の合計は「*」のある行だけで取ります。
スプレッドシートに取り込む
- 集計用のスプレッドシートを開きます。
- 「ファイル」から「インポート」をクリックします。
- 書き出したCSVを選びます。
- 読み込みオプションで「現在のシートを置換する」を選びます。
- 区切り文字はカンマにします。
- 「インポート」をクリックします。
「現在のシートに行を追加する」を選ぶと、前回の行の下に今回の全件が足され、同じ案件が2回数えられます。集計の式やピボットテーブルは、取り込み用のシートとは別のシートに置き、取り込み用のシートを参照させます。置換しても集計の側が壊れません。
【画面:スプレッドシートのインポートの画面。読み込みオプションで「現在のシートを置換する」を選んだ状態】
シートからkintoneへ戻す
シートの行をkintoneに入れるときは、シートをCSVでダウンロードして、kintoneで読み込みます。
- スプレッドシートで、読み込みたい行だけのシートを開きます。
- ファイルのメニューからCSV形式でダウンロードします。
- 問い合わせ管理のレコードの一覧で「オプション」アイコンをクリックし、「ファイルから読み込む」を選びます。
- 「ファイルを選択」でダウンロードしたCSVを指定します。
- 「先頭行をファイルの列名として扱う」を確かめます。
- 「読み込むファイルのプレビュー」で文字化けと列ずれがないか見ます。化けていたら「文字コード」を変えます。
- 「アプリへの反映方法」で「レコードの更新と追加」を選びます。
- 「更新キー」に受付ID、「対応するファイルの列」に受付IDの列を選びます。
- 各フィールドに読み込む列を対応付け、読み込まないフィールドは「(指定しない)」にします。
- 「読み込む」をクリックします。
「レコードの更新と追加」にして受付IDを更新キーにしておくと、同じファイルを2回読み込んでも、既にある受付IDは上書きになり、レコードは増えません。更新キーにレコード番号以外を使うには、そのフィールドで「値の重複を禁止する」がオンになっている必要があります。CSVは1ファイル100MB、10万行まで、Excel形式は1MB、1,000行までです。
エラー行の扱いは「読み込みを継続する(エラー行のみスキップします)」と「読み込みを中止する(エラー行以降の行は読み込みません)」から選びます。どちらでもエラーより前の行は読み込まれるので、取り消しにはなりません。読み込む前に、いまのレコードを書き出してバックアップを取っておきます。読み込みには、アプリのアクセス権で「ファイル読み込み」の権限が要ります。

Apps Scriptでkintoneからシートへ書く
ここからは自動にします。Apps Scriptはスプレッドシートに付いているスクリプトの仕組みで、サーバーを用意せずにREST APIを呼べます。
APIトークンを作る
- 案件管理のレコードの一覧で、右上の歯車の「アプリを設定」をクリックします。
- 「設定」タブを開きます。
- 「カスタマイズ/サービス連携」の「APIトークン」をクリックします。
- 「生成する」をクリックします。
- 「アクセス権」で、レコードの閲覧だけにチェックを入れます。
- 「メモ」に「スプレッドシート連携(案件の書き出し)」のように用途を書きます。
- 「保存」をクリックします。
- 「アプリを更新」をクリックし、確認の画面でもう一度「アプリを更新」をクリックします。
最後の「アプリを更新」を忘れると、トークンは効きません。トークンは1アプリ20個まで作れます。用途ごとに分けておくと、1つのつなぎを止めたいときにそのトークンだけ消せます。
トークンの権限は、アプリやレコード、フィールドのアクセス権より優先されます。閲覧だけで足りるつなぎに、編集や削除まで付けたトークンを使い回さないようにします。

トークンをスクリプトに置く
- 集計用のスプレッドシートを開きます。
- 「拡張機能」から「Apps Script」を選びます。
- 左の「プロジェクト設定」を開きます。
- 「スクリプト プロパティ」に、プロパティ名を
KINTONE_TOKEN_ANKEN、値を生成したトークンにして追加し、保存します。
コードに直接書くと、スクリプトのコピーや画面共有で一緒に出回ります。コードからは名前で読みます。
【画面:Apps Scriptのプロジェクト設定。スクリプト プロパティにトークンを追加した状態】
取得して書き込むコード
サブドメインとアプリIDはダミーの値です。自分の環境の値に置き換えます。アプリIDは、アプリを開いたときのURLの /k/ の後ろの数字です。
const SUBDOMAIN = 'example'; // https://example.cybozu.com の example
const ANKEN_APP_ID = 123;
function fetchAllRecords_(appId, token, fields, condition) {
const records = [];
let lastId = 0;
while (true) {
const q = (condition ? '(' + condition + ') and ' : '') +
'$id > ' + lastId + ' order by $id asc limit 500';
let url = 'https://' + SUBDOMAIN + '.cybozu.com/k/v1/records.json' +
'?app=' + appId + '&query=' + encodeURIComponent(q);
fields.forEach(function (f, i) {
url += '&' + encodeURIComponent('fields[' + i + ']') + '=' + encodeURIComponent(f);
});
const res = UrlFetchApp.fetch(url, {
method: 'get',
headers: { 'X-Cybozu-API-Token': token },
muteHttpExceptions: true
});
if (res.getResponseCode() !== 200) {
throw new Error('kintoneの取得に失敗: ' + res.getContentText());
}
const batch = JSON.parse(res.getContentText()).records;
batch.forEach(function (r) { records.push(r); });
if (batch.length < 500) break;
lastId = Number(batch[batch.length - 1].$id.value);
}
return records;
}
function exportAnken() {
const token = PropertiesService.getScriptProperties().getProperty('KINTONE_TOKEN_ANKEN');
const fields = ['$id', '案件名', '顧客名', '担当者', '金額', '受注予定日', '進捗', '更新日時'];
const records = fetchAllRecords_(ANKEN_APP_ID, token, fields, '進捗 not in ("失注")');
const header = ['レコードID', '案件名', '顧客名', '担当者', '金額', '受注予定日', '進捗', '更新日時'];
const rows = records.map(function (r) {
return [
Number(r.$id.value),
r['案件名'].value,
r['顧客名'].value,
r['担当者'].value.map(function (u) { return u.name; }).join(','),
r['金額'].value === '' ? '' : Number(r['金額'].value),
r['受注予定日'].value || '',
r['進捗'].value,
new Date(r['更新日時'].value)
];
});
const sheet = SpreadsheetApp.getActive().getSheetByName('kintoneの写し_案件');
sheet.clearContents();
sheet.getRange(1, 1, 1, header.length).setValues([header]);
if (rows.length > 0) {
sheet.getRange(2, 1, rows.length, header.length).setValues(rows);
}
}
書き終えたら exportAnken を選んで実行します。初回は求められる許可を与えます。
【画面:Apps Scriptのエディタ。exportAnkenを選んで実行し、実行ログに完了が出た状態】
コードの読み方
取得は、レコードを一括取得するAPI(GET /k/v1/records.json)を使います。1回で取れるのは500件までで、limit を書かないと100件しか返りません。件数が多いアプリで offset を増やしながら取る書き方をすると、offset の上限が10,000なので1万件を超えたところで取れなくなります。
そこで、レコードID($id)の昇順に並べ、前回取った最後のIDより大きいものを次に取る書き方にしています。cybozu developer networkで「シーク法」として紹介されている取り方で、件数がいくら増えても止まりません。取得した件数が500未満になったら最後のページです。
fields は取るフィールドの指定です。$id は次の取得の起点なので必ず入れます。
返ってくる値は、数値もレコード番号も文字列です。Number() で数に直してから書かないと、シートで文字として扱われ、SUMで合計できません。日時は 2026-10-01T00:30:00Z のような協定世界時の形で返るので、new Date() に通してからシートに書きます。シートの表示はスプレッドシートのタイムゾーンの時刻になります。ユーザー選択はユーザーコード(code)と表示名(name)の組の配列なので、名前だけを取り出してつないでいます。
シートへの書き込みは1行ずつではなく、配列にまとめて setValues で一度に書きます。シートの操作は回数が多いほど遅くなります。
シートからkintoneへ登録する
二重登録を防ぐキー
シートからkintoneへ送るつなぎで一番起きる事故は、同じ行が2回登録されることです。スクリプトが途中で止まり、kintoneには登録したのにシートに「登録済み」と書く前に終わった、というのが典型です。次の実行で同じ行がもう一度送られます。
防ぎ方は2段構えにします。
- 行ごとに一意な受付IDを持たせ、kintoneの受付IDで「値の重複を禁止する」をオンにする
- 登録は「追加」ではなく、受付IDをキーにした「更新、なければ追加」で送る
レコードを更新するAPI(PUT /k/v1/records.json)には、updateKey でキーのフィールドを指定し、upsert を true にすると、キーが一致するレコードがあれば更新、なければ追加する動きがあります。同じ行を2回送っても2回目は上書きになるので、レコードは増えません。updateKey に指定できるのは、重複禁止を設定した文字列(1行)か数値だけです。
受付IDに行番号をそのまま使うと、並べ替えや行の挿入で別の問い合わせを指すようになります。最初にスクリプトが振った値をシートに書き込み、以後は変えません。
APIトークンと登録のコード
問い合わせ管理のアプリで、レコード追加とレコード編集にチェックを入れたAPIトークンを作ります。upsert を使うとき、更新の権限に加えて追加の権限も要るためです。スクリプト プロパティに KINTONE_TOKEN_TOIAWASE として置きます。
const TOIAWASE_APP_ID = 124;
function pushInquiries() {
const token = PropertiesService.getScriptProperties().getProperty('KINTONE_TOKEN_TOIAWASE');
const sheet = SpreadsheetApp.getActive().getSheetByName('問い合わせ受付');
const values = sheet.getDataRange().getValues();
const header = values[0];
const c = {
at: header.indexOf('受信日時'),
name: header.indexOf('氏名'),
mail: header.indexOf('メールアドレス'),
body: header.indexOf('問い合わせ内容'),
key: header.indexOf('受付ID'),
done: header.indexOf('kintone登録')
};
const targets = [];
for (let i = 1; i < values.length; i++) {
const row = values[i];
if (row[c.done] !== '' || row[c.name] === '') continue;
if (row[c.key] === '') {
row[c.key] = 'Q' + Utilities.formatDate(new Date(row[c.at]), 'Asia/Tokyo', 'yyyyMMddHHmmss') + '-' + (i + 1);
sheet.getRange(i + 1, c.key + 1).setValue(row[c.key]);
}
targets.push({ rowNo: i + 1, row: row });
}
for (let s = 0; s < targets.length; s += 100) {
const chunk = targets.slice(s, s + 100);
const body = {
app: TOIAWASE_APP_ID,
upsert: true,
records: chunk.map(function (t) {
return {
updateKey: { field: '受付ID', value: String(t.row[c.key]) },
record: {
'受付ID': { value: String(t.row[c.key]) },
'受信日時': { value: Utilities.formatDate(new Date(t.row[c.at]), 'UTC', "yyyy-MM-dd'T'HH:mm:ss'Z'") },
'氏名': { value: String(t.row[c.name]) },
'メールアドレス': { value: String(t.row[c.mail]) },
'問い合わせ内容': { value: String(t.row[c.body]) }
}
};
})
};
const res = UrlFetchApp.fetch('https://' + SUBDOMAIN + '.cybozu.com/k/v1/records.json', {
method: 'put',
contentType: 'application/json',
headers: { 'X-Cybozu-API-Token': token },
payload: JSON.stringify(body),
muteHttpExceptions: true
});
if (res.getResponseCode() !== 200) {
throw new Error('kintoneの登録に失敗: ' + res.getContentText());
}
const now = new Date();
chunk.forEach(function (t) {
sheet.getRange(t.rowNo, c.done + 1).setValue(now);
});
}
}
登録も更新も、1回のリクエストで送れるのは100件までなので、100件ずつに分けて送っています。1回のリクエストの中で1件でも失敗すると、そのリクエストの100件は全部取り消されます。kintone登録の列に日時を書くのは、レスポンスが成功で返ってきた後だけにしています。失敗したら列は空のまま残り、次の実行でもう一度送られます。受付IDで上書きになるので、送り直しても増えません。record の中にも受付IDを入れているのは、新しく登録されるレコードに受付IDを確実に持たせるためです。受付IDは必須にしているので、ここが空だと登録で止まります。
日時のフィールドには、協定世界時に直した 2026-10-22T01:00:00Z の形で送ります。シートの日時をそのまま文字にして送ると、9時間ずれたり、形式が合わずにエラーになったりします。
対応状況はシートから送りません。送ると、kintoneで「対応中」に変えたあとに送り直したとき、初期値で上書きされます。送るのは受付の時点で決まっている値だけです。
【画面:問い合わせ受付のシート。受付IDとkintone登録の列にスクリプトが値を書いた状態】

定期実行する
手で実行して動くことを確かめたら、時間で動くトリガーを付けます。
- Apps Scriptのエディタで、左の「トリガー」をクリックします。
- 右下の「トリガーを追加」をクリックします。
- 実行する関数に
exportAnkenを選びます。 - 時間で動く種類を選び、毎日の時刻か、何時間おきかを選びます。
- 「保存」をクリックします。
コードで作ることもできます。次の関数を一度だけ実行すると、pushInquiries を6時間おきに動かすトリガーができます。
function createTrigger() {
ScriptApp.newTrigger('pushInquiries').timeBased().everyHours(6).create();
}
時間で動くトリガーの時刻は、少しずらされることがあります。毎日9時に設定しても、9時から10時のあいだのどこかで動き、その後は毎日ほぼ同じ時刻になります。朝礼の9時ちょうどに最新にしておきたいなら、8時に設定します。
トリガーは、作った人のアカウントで動きます。作った人が異動や退職でそのアカウントを使えなくなると、トリガーも動かなくなると考えておきます。共有のアカウントで作るか、作った人をつなぎの一覧に書いておきます。
スクリプトがシートに書き込んでも、シートの編集で動くトリガーは動きません。スクリプトやAPIの操作ではトリガーが動かない仕様だからです。kintoneから書き出したシートの更新をきっかけに、続けて別の処理を動かす作りはできません。続けたい処理は同じ関数の中で順に呼びます。
【画面:Apps Scriptのトリガーの一覧。exportAnkenとpushInquiriesの2つが並んだ状態】
件数が増えたら差分にする
件数が増えて時間がかかるようになったら、前回の実行時刻をスクリプト プロパティに保存し、更新日時 > "2026-10-21T22:00:00Z" のような条件で取得して、シートの同じレコードIDの行を差し替えます。ただし差分の取り方では、kintoneで削除されたレコードがシートに残り続けます。週に一度は全件を取り直す関数を別に用意して、写しを作り直します。
連携サービスとiPaaSを使う
コードを持ちたくない会社は、連携サービスかiPaaSを使います。
連携サービスは、kintoneとスプレッドシートをつなぐための製品やプラグインで、サイボウズ以外の会社が提供しています。選ぶときは、向き、同期の頻度、キーを指定した上書きができるか、エラーがどこで分かるか、の4点を比べます。キーで上書きできない製品をシートからkintoneへの登録に使うと、二重登録の対策を別に考えることになります。
iPaaSは、複数のサービスを画面上でつなぐ道具です。Zapierにはkintoneの「New Record」をきっかけにする機能と、「Create Record」「Update Record by Update Key」などの登録と更新の機能があり、Googleスプレッドシートの行の追加や更新と組み合わせられます。Microsoft Power Automateは、kintoneヘルプに連携の設定方法が載っていて、レコードの追加や更新をきっかけにできます。Power Automateは有償プランの契約が要り、ゲストスペースのアプリとは連携できません。cybozu.comの管理者が共通管理で連携を許可しておく必要もあります。
どちらを使っても、APIのリクエスト数はkintone側で数えられ、同じアプリにつないだ仕組みの合計で上限に近づきます。
応用
Webhookでレコードの追加をすぐ送る
定期実行では、最大でトリガーの間隔ぶん遅れます。kintoneにレコードが追加されたらすぐシートに行を足したい、という場合は、kintoneのWebhookとApps Scriptのウェブアプリを組み合わせます。
- Apps Scriptに
doPost(e)の関数を書き、e.postData.contentsに届いたJSONからrecordを取り出してシートに1行足す処理にします。 - 右上の「デプロイ」から「新しいデプロイ」を選び、種類をウェブアプリにしてデプロイし、URLを控えます。
- kintoneの「アプリの設定」の「設定」タブで、「カスタマイズ/サービス連携」の「Webhook」をクリックします。
- 「追加する」をクリックし、「Webhook URL」に控えたURLを貼ります。先頭の
https://は外します。 - 「通知を送信する条件」で「レコードの追加」にチェックを入れます。
- 「保存」をクリックし、「アプリを更新」をクリックします。
届くJSONの type には ADD_RECORD や UPDATE_RECORD が入り、record はレコードを取得するAPIと同じ形です。
Webhookには注意点が3つあります。ExcelやCSVの読み込み、一括削除、REST APIでの一括の登録や更新では送られません。1ドメインあたり1分間に60件までで、それを超えた操作の分は送られません。1アプリに設定できるのは10個までです。送られない操作があるので、Webhookだけに頼らず、1日1回の全件の取り直しと組み合わせます。
制限
つなぎを作る前に、上限を確かめておきます。Apps Scriptの実行時間から下はGoogle側の上限です。
| 項目 | 上限 |
|---|---|
| 1アプリあたりのAPIリクエスト数 | スタンダードコースは1日1万、ワイドコースは1日10万 |
| 同時に送れるAPIリクエスト | 1ドメインにつき100まで |
| 1回に取得できるレコード | 500件まで(limit の初期値は100件) |
取得の offset | 10,000まで |
| 1回に登録、更新できるレコード | 100件まで |
| APIトークン | 1アプリ20個まで。1回のリクエストに指定できるのは9個まで |
| ファイルの読み込み | CSVは100MB、10万行まで。Excel形式は1MB、1,000行まで |
| ファイルの書き出し | 100MBを超えると失敗 |
| Apps Scriptの1回の実行時間 | 6分 |
| トリガーで動いた合計時間 | 個人のGoogleアカウントは1日90分、Google Workspaceは1日6時間 |
| UrlFetchAppの呼び出し | 個人のGoogleアカウントは1日2万回、Google Workspaceは1日10万回 |
| トリガーの数 | 1ユーザー1スクリプトあたり20 |
| スプレッドシートの大きさ | 2,000万セルまたは100MBまで |
1日1万リクエストは普通の使い方なら余裕があります。2万件を500件ずつ全件取っても1回40リクエストで、1時間おきでも1日960です。危ないのは1件ずつ送るループで、1,000行のシートなら1回で1,000リクエストを使います。必ずまとめて送ります。
6分の実行時間は、シートに1行ずつ書いているときに当たりやすい制限です。まとめて書いても当たるなら、差分の取得に切り替えます。
できないことと、その代わり
| やりたいこと | 標準でできるか | 代わりの手 |
|---|---|---|
| kintoneとシートを自動で同期する | できない。標準の設定は無い | Apps Script、連携サービス、iPaaS |
| ライトコースでAPIトークンを使う | できない | CSVの書き出しと取り込みで回す。自動にするならスタンダードコースへ |
| 添付ファイルをCSVで書き出す | できない | APIでファイルを取得するスクリプトを書く。シートにはファイル名だけ載せる |
| 関連レコード一覧をCSVで書き出す | できない | 参照先のアプリを別に書き出し、シートで突き合わせる |
| 計算フィールドやルックアップのコピー先にAPIで値を入れる | できない | 計算の元のフィールドに値を入れる。ルックアップはキーの値を送る |
| ファイルの読み込みやAPIの一括処理でWebhookを送る | 送られない | 定期実行で全件を取り直す |
| シートの編集をスクリプトの書き込みで連鎖させる | できない | 続く処理を同じ関数の中で呼ぶ |
| 削除を差分で検知する | 差分の取得ではわからない | 週に一度、全件で作り直す |
| 両方向の自動同期を安全に回す | 作れるが勧めない | 向きを片方向にし、正をkintoneに置く |
よく詰まるところ
| 症状 | 原因 | 直し方 |
|---|---|---|
| 「ファイルに書き出す」が出てこない | アプリのアクセス権で「ファイル書き出し」の権限がない | アプリの管理者に権限を付けてもらう |
| シートに取り込むと文字化けする | Shift-JISで書き出している | 「文字コード」をUTF-8かBOM付きUTF-8にして書き出し直す |
| トークンを作ったのにエラーになる | 「アプリを更新」をしていない、またはトークンに必要な権限がない | アプリを更新する。登録ならレコード追加とレコード編集にチェックを入れる |
| 100件しか取れない | limit を書いていない | limit 500 を書き、500件ずつ繰り返す |
| 1万件を超えると取れなくなる | offset の上限が10,000 | $id の昇順で前回の最後のIDより大きいものを取る |
| シートで金額が合計できない | APIの数値は文字列で返る | Number() で数にしてから書く |
| 日時が9時間ずれる | APIの日時は協定世界時 | 取得は new Date() に通す。登録は協定世界時に直して送る |
| 同じ問い合わせが2件登録される | 追加のAPIで送っていて、途中で止まった行を送り直した | 受付IDで重複禁止にし、updateKey と upsert で送る |
updateKey を指定するとエラーになる | キーのフィールドが重複禁止になっていない、または種類が文字列(1行)か数値でない | 受付IDを文字列(1行)にして「値の重複を禁止する」をオンにする |
| 100件まとめて登録できない | 1件の不正な値でリクエスト全体が取り消される | エラーの本文で該当の行を探して直す。必須フィールドの空も確かめる |
| ルックアップのキーを送るとエラーになる | 参照先のアプリのトークンも要る | 両方のアプリのトークンをカンマ区切りで X-Cybozu-API-Token に入れる |
| 実行が6分で止まる | シートへの書き込みを1行ずつしている、または件数が多い | setValues でまとめて書く。差分の取得にする |
| ある日から自動で動かなくなった | トリガーを作った人のアカウントが使えなくなった | 実行の記録を見て、共有のアカウントで作り直す |
| 社外からつながらない | cybozu.comでIPアドレスの制限をかけている | システム管理者に、Apps Scriptからの接続をどう通すか相談する |
次にやること
APIの呼び方そのもの、トークンの権限の考え方、クエリの書き方を一通り押さえたいときは「kintone REST APIの使い方。APIトークンの発行からレコードの取得・登録まで」が続きです。いまシートやExcelで回している管理表をkintoneに移してからつなぐなら、「Excelの管理表をkintoneに移す手順。取り込みで崩れない整え方」を先に読むと、取り込みで列が崩れるのを避けられます。予定をカレンダーに出したいときは「kintoneとGoogleカレンダーの連携。予定を二重に入れない作り方」、kintoneの画面の側でボタンを押したときにシートへ送る、といった動きを入れたいときは「kintoneのJavaScriptカスタマイズ入門。最初の1本を動かすまで」に進みます。