コンテンツにスキップ

Googleスプレッドシートと連携する

Googleスプレッドシートに追加されたデータを Google Apps Script(GAS)で定期的に読み取り、nocall の公開 API から自動架電できます。

Googleフォームを回答元にする場合は、回答直後に実行できる Googleフォーム連携 を使用してください。このページは Studio など、外部サービスがスプレッドシートへ行を追加する連携向けです。

1 行目を見出しにして、次の順番で列を用意します。「処理結果」列は二重架電を防ぐために必要です。

A B C D E
電話番号 氏名 メールアドレス 会社名 処理結果

外部サービスがすでに列を作成している場合は、末尾に「処理結果」列を追加し、後述する列番号を実際のシートに合わせて変更します。

  1. 対象のスプレッドシートで「拡張機能」→「Apps Script」を開きます。
  2. 「プロジェクトの設定」→「スクリプト プロパティ」に次の値を保存します。
プロパティ
NOCALL_API_KEY nocall で発行した API キー
NOCALL_AGENT_ID 架電に使うエージェント ID
NOCALL_USER_GROUP_ID 登録先のコンタクトグループ ID
  1. 次のスクリプトを追加し、SHEET_NAME を対象シートの名前へ変更します。
const SHEET_NAME = "シート1";
const FIRST_DATA_ROW = 2;
const PHONE_COLUMN = 1;
const NAME_COLUMN = 2;
const EMAIL_COLUMN = 3;
const COMPANY_COLUMN = 4;
const RESULT_COLUMN = 5;
function processPendingRows() {
const lock = LockService.getScriptLock();
if (!lock.tryLock(1000)) return;
try {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_NAME);
if (!sheet) throw new Error(`${SHEET_NAME}が見つかりません`);
const lastRow = sheet.getLastRow();
if (lastRow < FIRST_DATA_ROW) return;
for (let row = FIRST_DATA_ROW; row <= lastRow; row += 1) {
const phoneNumber = sheet.getRange(row, PHONE_COLUMN).getDisplayValue().trim();
const resultCell = sheet.getRange(row, RESULT_COLUMN);
const currentResult = resultCell.getDisplayValue().trim();
if (!phoneNumber || currentResult) continue;
// API実行前に印を付け、同じ行の同時実行や自動再送を防ぎます。
resultCell.setValue(`処理中: ${new Date().toISOString()}`);
SpreadsheetApp.flush();
try {
const result = callNocall({
phoneNumber,
name: sheet.getRange(row, NAME_COLUMN).getDisplayValue(),
email: sheet.getRange(row, EMAIL_COLUMN).getDisplayValue(),
company: sheet.getRange(row, COMPANY_COLUMN).getDisplayValue(),
});
resultCell.setValue(`送信済み: ${result.callTaskId}`);
} catch (error) {
resultCell.setValue(`エラー: ${String(error)}`);
}
}
} finally {
lock.releaseLock();
}
}
function callNocall(values) {
const payload = {
phoneNumber: toE164Japan(values.phoneNumber),
agentId: getRequiredProperty("NOCALL_AGENT_ID"),
userGroupId: getRequiredProperty("NOCALL_USER_GROUP_ID"),
attributions: [
{ label: "氏名", value: values.name },
{ label: "メールアドレス", value: values.email },
{ label: "会社名", value: values.company },
],
};
const response = UrlFetchApp.fetch(
"https://api.nocall.ai/api/v1/end-users/add-and-call",
{
method: "post",
contentType: "application/json",
headers: { "x-api-key": getRequiredProperty("NOCALL_API_KEY") },
payload: JSON.stringify(payload),
muteHttpExceptions: true,
},
);
if (response.getResponseCode() >= 300) {
throw new Error(`nocall API error: ${response.getContentText()}`);
}
return JSON.parse(response.getContentText());
}
function toE164Japan(value) {
const normalized = String(value).replace(/[\s()-]/g, "");
if (normalized.startsWith("+")) return normalized;
if (normalized.startsWith("0")) return `+81${normalized.slice(1)}`;
throw new Error("電話番号は0または+から始めてください");
}
function getRequiredProperty(name) {
const value = PropertiesService.getScriptProperties().getProperty(name);
if (!value) throw new Error(`${name}が設定されていません`);
return value;
}
  1. Apps Script で processPendingRows を一度手動実行し、権限を許可します。
  2. 左メニューの「トリガー」を開きます。
  3. 「トリガーを追加」を選択します。
  4. 実行する関数に processPendingRows を指定します。
  5. イベントのソースに「時間主導型」を指定します。
  6. 時間ベースのトリガーで「分ベースのタイマー」、間隔で「1分おき」を指定して保存します。

外部サービスや API によるスプレッドシート更新では、Apps Script の編集・変更トリガーは実行されません。そのため、このガイドでは時間主導型トリガーで未処理行を確認します。通常は行が追加されてから約 1 分以内に処理されますが、Google側の実行状況により遅れる場合があります。

  1. 発信してよいテスト用電話番号を入力し、「処理結果」を空欄にした行を追加します。
  2. processPendingRows を手動実行します。
  3. 「処理結果」が 送信済み: ctt_... になり、nocall の通話履歴が作成されることを確認します。
  4. 同じ行でもう一度実行し、二重架電されないことを確認します。

列の順序が異なる場合は、先頭の PHONE_COLUMN などの列番号を変更します。コンタクト属性を追加する場合は、列番号を定義して attributions{ label, value } を追加してください。label はエージェントのカスタム変数と一致させます。

Apps Script の「トリガー」画面から processPendingRows の時間主導型トリガーを削除します。トリガーを削除しても、すでに nocall へ登録された架電は取り消されません。

詳細は Google Apps Script のインストール型トリガー を参照してください。