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. スプレッドシートにスクリプトを設定する
- Googleスプレッドシートを新規作成します
- シート名を「ユーザー一括更新」に変更します
- スプレッドシート上部の「拡張機能」→「Apps Script」を開きます
- エディタが開いたら、既存のコードをすべて削除し、後述のサンプルコードをすべて貼り付けます
- フロッピーディスクアイコンをクリックしてファイルを保存します
スプレッドシートの編集者は、GASのコードやトークンを閲覧・編集できてしまうため、権限設定にご注意ください。
3. トークンをスクリプトプロパティに登録する
コードにトークンを直接書かず、スクリプトプロパティに登録します。
- Apps Scriptエディタ左メニューの「プロジェクトの設定」をクリックします
- 「スクリプトプロパティ」→「スクリプトプロパティを追加」をクリックします
- 以下を入力して保存します
| プロパティ名 | 値 |
|---|---|
| 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: 実行する
- 上部メニュー「kickflow」→「ユーザーを一括更新」をクリックします
- 「○行のユーザーを更新します。よろしいですか?」という確認ダイアログが表示されるので、内容を確認して「OK」をクリックします
- 処理が進むにつれてD列に結果が表示されます
- 完了すると「成功: ○件 / 失敗: ○件」と表示されます
初回実行時は「このアプリは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;
}