見出し画像

【GAS】kintoneのレコードをUPSERTAPIを実行してみる

2025年1月に正式リリースとなるkintoneのAPIでのUPSERTモードをGASから早速使用してみました。

複数のレコードを更新する(UPSERTモードを利用できる)


ライブラリ(コード)

/**
 * アプリからレコードを検索 重複禁止フィールドを元にupsertを実行
 */
function test_callKintoneRecordsUpsertUpdateKey() {


  const uppId = "***"   //※アプリのIDを入力
  const recordId = "***"  //※レコードのIDを入力
  const kintoneRecords = callKintoneRecords()
  const records = kintoneRecords.searchById(uppId, recordId)
  const field = "***"//※フィールドを指定
  console.log(records)

  //レコードをupsert 
  const upsertRecords = records.records.map(record => {

    const field = "***"//※フィールドを指定
    const value = "***"//※値を入力

    return {
      "updateKey": {
        "field": field,
        "value": value
      },
      "record": record
    }
  })

  const response = kintoneRecords.upsert(uppId, upsertRecords,field)
  const upsertResult = JSON.parse(response.getContentText());

  console.log(upsertResult)
}
/**
 * アプリからレコードを検索 レコード番号を元にupsertをします。
 */
function test_callKintoneRecordsUpsertId() {
  //レコードの検索
  const uppId = "***"   //※アプリのIDを入力
  const recordId = "***"  //※レコードのIDを入力
  const kintoneRecords = callKintoneRecords()
  const records = kintoneRecords.searchById(uppId, recordId)
  const field = "レコード番号"
  Logger.log(records)


  //レコードをupsert 
  const upsertRecords = records.records.map(record => {


    return {
      "id": record.$id.value,
      "record": record
    }
  })

  const response = kintoneRecords.upsert(uppId, upsertRecords,field)
  const upsertResult = JSON.parse(response.getContentText());

  Logger.log(upsertResult)
}

function callKintoneRecords() {
  const properties = PropertiesService.getScriptProperties();
  const subdomain = properties.getProperty("CYBOZU_SUBDOMAIN");
  const user = properties.getProperty("CYBOZU_USER");
  const pass = properties.getProperty("CYBOZU_PASSWORD");

  if (!subdomain || !user || !pass) {
    throw new Error("プロパティストアに必要な設定値がありません。");
  }

  const kintoneRecords = new KintoneRecords(subdomain, user, pass);
  return kintoneRecords;
}




class KintoneRecords {
  constructor(subdomain, username, password) {
    this.subdomain = subdomain;
    this.username = username;
    this.password = password;
    this.authorization = Utilities.base64Encode(username + ":" + password);
  }

  searchById(appId, recordId, fields = []) {
    const query = `レコード番号=${recordId}`;
    return this.search(appId, query, fields);
  }

  search(appId, query = '', fields = [], totalCount = false, limit = 500, offset = 0) {
    const q = query;
    const fieldsParam = fields.length > 0 ? fields.map((field, index) => `&fields[${index}]=${encodeURIComponent(field)}`).join('') : '';
    const totalCountParam = totalCount ? "&totalCount=true" : "";
    const url = `${this._getEndpoint()}/records.json?app=${appId}&query=${q} limit ${limit} offset ${offset}${totalCountParam}${fieldsParam}`;
    const response = UrlFetchApp.fetch(encodeURI(url), this._getOption());
    return JSON.parse(response.getContentText());
  }

  /**
   * Note:https://cybozu.dev/ja/kintone/docs/rest-api/records/update-records/
   */
  upsert(appId, records, fieldName, deleteFields = ["レコード番号", "作成者", "更新者", "更新日時", "作成日時",]) {

    records.forEach(record => {

      delete record.record[fieldName]

      deleteFields.forEach(deleteField => {
        delete record.record[deleteField]
      })
    })

    const payload = {
      app: appId,
      upsert: true,
      records: records
    };
    const response = UrlFetchApp.fetch(
      this._getEndpoint() + "/records.json",
      this._putOption(payload)
    );
    return response;
  }
  _getOption() {
    return {
      method: "get",
      headers: this._authorizationHeader(),
      muteHttpExceptions: true
    };
  }

  _putOption(payload) {
    return {
      method: "put",
      contentType: "application/json",
      headers: this._authorizationHeader(),
      muteHttpExceptions: true,
      payload: JSON.stringify(payload)
    };
  }

  _getEndpoint() {
    return `https://${this.subdomain}.cybozu.com/k/v1`;
  }

  _authorizationHeader() {
    return { "X-Cybozu-Authorization": this.authorization };
  }
}


使い方

GASに貼り付けてアプリのIDやレコード番号、認証情報を設定してください。
test_callKintoneRecordsUpsertUpdateKey関数は任意のユニークなフィールドを指定しています。
test_callKintoneRecordsUpsertIdはID(レコード番号)をキーを指定しています。

解説

テストとしてレコードを取得してそのままレコードをそのままアプリに書き込んでいます。
しかし、取得したそのままのレコードではうまくいかずレコード番号フィールドを更新しようとしてしまったためレコード番号フィールドのプロパティを削除しています。

    records.forEach(record => {

      delete record.record[fieldName]

      deleteFields.forEach(deleteField => {
        delete record.record[deleteField]
      })
    })


今回は以上です。
このアップデートで以前は自分でUPSERTの処理を実装しなければならなかったのが相当楽になりました!
うまく使いこなしていきたいですね!

いいなと思ったら応援しよう!