REST APIを使ってユーザーのメールアドレスとコードを一括で更新する(GASサンプルコード)

この記事では、Google Apps Script(GAS)を使用して、ユーザーのメールアドレスとコードを一括更新するサンプルコードと手順を紹介します。
管理画面からは1件ずつしか変更できないメールアドレスとコードを、スプレッドシートにまとめてAPIで一括更新できます。ドメイン変更など、大量のユーザー情報を変更する際にご活用ください。

  • この記事のコードはサンプルです。動作を保証するものではありません。ご利用の前に、少数のユーザーで動作をテストしてください。kickflow APIの仕様変更により、予告なく動作しなくなる場合があります。
  • この操作はユーザー情報を直接更新します。実行前に対象ユーザーと変更内容を必ず確認してください。
  • GASには1回あたりの実行時間に上限があります。詳細はGoogle サービスの割り当て(外部サイト)を参照してください。大量のユーザーをまとめて処理すると上限を超えてエラーになる場合があります。その際は、対象を分割して複数回に分けて実行してください。

事前準備

1. Personal Access Tokenを発行する

ユーザーの管理権限を持つアカウントでkickflowにログインし、Personal Access Token(PAT)を発行します。

手順はREST APIを使用するをご確認ください。

2. スプレッドシートにスクリプトを設定する

  1. Googleスプレッドシートを新規作成します
  2. シート名を「ユーザー一括更新」に変更します
  3. スプレッドシート上部の「拡張機能」→「Apps Script」を開きます
  4. エディタが開いたら、既存のコードをすべて削除し、後述のサンプルコードをすべて貼り付けます
  5. フロッピーディスクアイコンをクリックしてファイルを保存します

スプレッドシートの編集者は、GASのコードやトークンを閲覧・編集できてしまうため、権限設定にご注意ください。

3. トークンをスクリプトプロパティに登録する

コードにトークンを直接書かず、スクリプトプロパティに登録します。

  1. Apps Scriptエディタ左メニューの「プロジェクトの設定」をクリックします
  2. 「スクリプトプロパティ」→「スクリプトプロパティを追加」をクリックします
  3. 以下を入力して保存します
プロパティ名 値
KICKFLOW_API_TOKEN 手順1で発行したPersonal Access Token

4. メニューを表示する

スプレッドシートをブラウザで再読み込みすると、上部メニューに「kickflow」が表示されます。

使い方

ステップ1: シートに変更内容を入力する

「ユーザー一括更新」シートの1行目はヘッダー行として、2行目以降に1行1ユーザーで入力します。

A列(ユーザーUUID) B列(新しいメールアドレス) C列(新しいコード) D列(実行結果)
a1b2c3d4-xxxx-... new@example.com EMP-1001 (自動記入)
  • A列: 必須。「管理センター>ユーザー>ユーザー」のCSVエクスポートでダウンロードできます。エクスポートしたCSVの id カラムの値がUUIDです
  • B列・C列: 変更する場合のみ入力。空欄の場合は変更されません
  • D列: 入力不要。実行後に自動で記入されます

コードを変更する作業では識別子に「コード」を使うと変更前後で混乱します。UUIDは変更されないため、A列の識別子としてUUIDを使用してください。

ステップ2: 実行する

  1. 上部メニュー「kickflow」→「ユーザーを一括更新」をクリックします
  2. 「○行のユーザーを更新します。よろしいですか?」という確認ダイアログが表示されるので、内容を確認して「OK」をクリックします
  3. 処理が進むにつれてD列に結果が表示されます
  4. 完了すると「成功: ○件 / 失敗: ○件」と表示されます

初回実行時は「このアプリはGoogleで確認されていません」等の承認ダイアログが表示されます。画面の指示に従い、自分のGoogleアカウントで権限を許可してください。2回目以降は表示されません。

ステップ3: 結果を確認する

D列の表示で結果を確認します。

D列の表示 意味 対応
OK(2026-06-12 14:30:00) 更新成功 対応不要
スキップ(UUID未入力) A列が空 UUIDを入力して再実行
スキップ(変更項目なし) B列・C列が両方空 変更内容を入力して再実行
失敗 HTTP422: ... 入力値が不正(重複・形式エラー等) エラー内容を確認して修正
失敗 HTTP404: ... UUIDのユーザーが見つからない UUIDを確認
失敗 HTTP401/403: ... 権限・トークンの問題 Personal Access Tokenを再確認
失敗 HTTP429: ... APIの実行回数制限を超過 時間をおいて再実行。多数のユーザーを処理する場合は待機時間(REQUEST_INTERVAL_MS)を長くする
通信エラー: ... ネットワーク等の一時的な問題 時間をおいて再実行

サンプルコード

/**
 * kickflow ユーザー一括更新ツール(メールアドレス / コード)
 *
 * 【事前準備】
 *   1. スプレッドシートを開き、拡張機能 > Apps Script でこのコードを貼り付け
 *   2. メニュー「プロジェクトの設定」>「スクリプト プロパティ」で
 *      プロパティ名: KICKFLOW_API_TOKEN
 *      値:          発行した Personal Access Token
 *      を登録(コードに直接トークンを書かないこと)
 *   3. シート構成(1行目はヘッダー):
 *      A列: ユーザーUUID / B列: 新メールアドレス / C列: 新コード / D列: 実行結果
 *   4. シートを開き直すと「kickflow」メニューが表示されます
 */

// ===== 設定 =====
const KICKFLOW_API_BASE = 'https://api.kickflow.com';
const SHEET_NAME = 'ユーザー一括更新'; // 対象シート名(任意で変更)
const DATA_START_ROW = 2;             // データ開始行(1行目はヘッダー)
const REQUEST_INTERVAL_MS = 2000;      // APIレート制限対策の待機時間

// 列番号(1始まり)
const COL = {
  uuid: 1,   // A
  email: 2,  // B
  code: 3,   // C
  result: 4, // D
};

/**
 * スプレッドシートを開いたときにカスタムメニューを追加する
 */
function onOpen() {
  SpreadsheetApp.getUi()
    .createMenu('kickflow')
    .addItem('ユーザーを一括更新', 'bulkUpdateUsers')
    .addToUi();
}

/**
 * シートの内容に従ってユーザーを一括更新するメイン関数
 */
function bulkUpdateUsers() {
  const ui = SpreadsheetApp.getUi();
  const token = PropertiesService.getScriptProperties().getProperty('KICKFLOW_API_TOKEN');
  if (!token) {
    ui.alert('スクリプト プロパティ「KICKFLOW_API_TOKEN」が設定されていません。');
    return;
  }

  const sheet = SpreadsheetApp.getActive().getSheetByName(SHEET_NAME);
  if (!sheet) {
    ui.alert(`シート「${SHEET_NAME}」が見つかりません。シート名を確認してください。`);
    return;
  }

  const lastRow = sheet.getLastRow();
  if (lastRow < DATA_START_ROW) {
    ui.alert('更新対象のデータがありません。');
    return;
  }

  // 対象件数を確認してから実行(誤操作防止)
  const targetCount = lastRow - DATA_START_ROW + 1;
  const confirm = ui.alert(
    '一括更新の確認',
    `${targetCount} 行のユーザーを更新します。よろしいですか?`,
    ui.ButtonSet.OK_CANCEL
  );
  if (confirm !== ui.Button.OK) return;

  let success = 0;
  let failure = 0;

  for (let row = DATA_START_ROW; row <= lastRow; row++) {
    const uuid  = String(sheet.getRange(row, COL.uuid).getValue()).trim();
    const email = String(sheet.getRange(row, COL.email).getValue()).trim();
    const code  = String(sheet.getRange(row, COL.code).getValue()).trim();

    // UUIDが空の行はスキップ
    if (!uuid) {
      sheet.getRange(row, COL.result).setValue('スキップ(UUID未入力)');
      continue;
    }

    // 入力された列だけをリクエストボディに含める
    const payload = {};
    if (email) payload.email = email;
    if (code)  payload.code  = code;

    if (Object.keys(payload).length === 0) {
      sheet.getRange(row, COL.result).setValue('スキップ(変更項目なし)');
      continue;
    }

    const result = updateUser_(uuid, payload, token);
    sheet.getRange(row, COL.result).setValue(result.message);
    if (result.ok) {
      success++;
    } else {
      failure++;
    }

    SpreadsheetApp.flush();      // 結果を逐次画面に反映
    Utilities.sleep(REQUEST_INTERVAL_MS);
  }

  ui.alert('完了', `成功: ${success} 件 / 失敗: ${failure} 件`, ui.ButtonSet.OK);
}

/**
 * ユーザー1件をPATCHで更新する
 * @param {string} uuid 対象ユーザーのUUID
 * @param {Object} payload 更新するフィールド(email / code 等)
 * @param {string} token Personal Access Token
 * @return {{ok: boolean, message: string}} 実行結果
 */
function updateUser_(uuid, payload, token) {
  const url = `${KICKFLOW_API_BASE}/v1/users/${encodeURIComponent(uuid)}`;
  const options = {
    method: 'patch',
    contentType: 'application/json',
    headers: { Authorization: `Bearer ${token}` },
    payload: JSON.stringify(payload),
    muteHttpExceptions: true,
  };

  try {
    const response = UrlFetchApp.fetch(url, options);
    const status = response.getResponseCode();
    if (status === 200) {
      return { ok: true, message: `OK(${formatTimestamp_()})` };
    }
    const body = response.getContentText();
    return { ok: false, message: `失敗 HTTP${status}: ${truncate_(body, 300)}` };
  } catch (e) {
    return { ok: false, message: `通信エラー: ${e.message}` };
  }
}

/**
 * 現在時刻を YYYY-MM-DD HH:mm:ss 形式で返す
 */
function formatTimestamp_() {
  return Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyy-MM-dd HH:mm:ss');
}

/**
 * 文字列を指定文字数で切り詰める
 */
function truncate_(str, max) {
  return str.length > max ? `${str.slice(0, max)}...` : str;
}
この記事は役に立ちましたか?