google app script から kintone のレコードを更新(フィールドの値を指定)
kintoneのデータを、クエリを使って1件更新するスクリプトです。
はじめに
以下の環境で動作しています。
- google app script … Chrome V8ランタイム利用
- kintone … クラウド最新版(2025年1月時点)
用意するもの
他のスクリプトと同じく、google app script → プロジェクトの設定 → スクリプトプロパティ に、以下3つのプロパティを作成します。
それぞれ取得元のアプリにあわせてください。
なお更新先のフィールドコードに「ルックアップ」フィールドがあるか否かでappTokenの記載方法が異なります。
プロパティ名 | 値(例) | 備考 |
---|---|---|
subdomain | myDomain | アドレス欄https://domainName.cybozu.comにあるdomainName部分 |
appId | 123 | レコード更新先のアプリID |
appToken | ABCDEFG1234567 | 取得対象アプリで作成したAPIトークン。 「レコード閲覧」「レコード編集」の2つの権限が必要。 |
appToken (例外) | ABCDEFG1234567,HIJKLMN8901234 | 編集するデータに フィールド形式:ルックアップ を含む場合は、ルックアップ先アプリの「レコード閲覧」権限があるAPIトークンが必要です。 APIトークン同士は","で区切ります。 |
更新先アプリ
以下アプリ(例)のレコードを更新します。
フィールド名 | フィールドコード | フィールド形式 | 追加したい値 | |
---|---|---|---|---|
ユーザー名 | userName | 文字列(1行) | - | |
保有資格 | qualificationList | テーブル | 内容は下のテーブルに記載。このフィールド内容だけ更新します。 |
テーブルのフィールドと、更新したい内容
フィールド名 | フィールドコード | フィールド形式 | 更新したい値1 | 更新したい値2 | 更新したい値3 | |
---|---|---|---|---|---|---|
資格名 | qualificationName | 文字列(1行) | ITパスポート | 簿記2級 | 基本情報技術者試験 | |
資格取得日 | qualificationDate | 日付 | 2020/11/22 | 2021/02/28 | 2021/11/21 | |
資格手当 | qualificationAmount | 数値 | 0 | 2000 | 3000 |
更新が完了すると、kintoneの対象サブテーブルが以下のようになるイメージです。
資格名 | 資格取得日 | 資格手当 |
---|---|---|
ITパスポート | 2020/11/22 | 0 |
簿記2級 | 2021/02/28 | 2000 |
基本情報技術者試験 | 2021/11/21 | 3000 |
スクリプト
/**
* サンプルスクリプト
*/
function sampleScript() {
const qualificationDateValue1 = new Date(2020, 11, 22, 0, 0, 0);
const qualificationDateValue2 = new Date(2021, 2, 28, 0, 0, 0);
const qualificationDateValue3 = new Date(2021, 11, 21, 0, 0, 0);
const updateData = {
qualificationList: {
value: [
{
value: {
qualificationName: {
type: 'SINGLE_LINE_TEXT',
value: 'ITパスポート',
},
qualificationDate: {
type: 'DATE',
value: Utilities.formatDate(qualificationDateValue1, 'JST', 'yyyy-MM-dd'),
},
qualificationAmount: {
type: 'NUMBER',
value: '0',
},
}
},
{
value: {
qualificationName: {
type: 'SINGLE_LINE_TEXT',
value: '簿記2級',
},
qualificationDate: {
type: 'DATE',
value: Utilities.formatDate(qualificationDateValue2, 'JST', 'yyyy-MM-dd'),
},
qualificationAmount: {
type: 'NUMBER',
value: '2000',
},
}
},
{
value: {
qualificationName: {
type: 'SINGLE_LINE_TEXT',
value: '基本情報技術者試験',
},
qualificationDate: {
type: 'DATE',
value: Utilities.formatDate(qualificationDateValue3, 'JST', 'yyyy-MM-dd'),
},
qualificationAmount: {
type: 'NUMBER',
value: '3000',
},
}
},
]
},
}
const updateKey = {
field: 'userName',
value: '山田太郎',
}
const resp = updateRecordByUniqueKey(updateKey,updateData)
Logger.log(resp)
}
/**
* スクリプトプロパティに設定したアプリのレコードを1件更新
*/
function updateRecordByUniqueKey(uniqueKey, recordData) {
const subDomain = scriptProperties.getProperty('subdomain')
const appId = Number(scriptProperties.getProperty('appId'))
const appToken = scriptProperties.getProperty('appToken')
const url = `https://${subDomain}.cybozu.com/k/v1/record.json`;
const options = {
method: 'PUT',
headers: {
'X-Cybozu-API-Token': appToken,
'Content-Type': 'application/json',
},
muteHttpExceptions: true,
payload: JSON.stringify({
app: appId,
updateKey: uniqueKey,
record: recordData,
}),
};
try {
const resp = UrlFetchApp.fetch(url, options);
if (resp.getResponseCode()!==200) {
throw new Error(`レコード更新エラー:\n HTTPステータス:${resp.getResponseCode()}\n レスポンス :${resp.toString()}`);
}
return JSON.parse(resp.getContentText());
} catch (error) {
throw new Error(error.message);
}
}
説明
更新するレコードのフィールドデータを準備
const qualificationDateValue1 = new Date(2020, 11, 22, 0, 0, 0);
const qualificationDateValue2 = new Date(2021, 2, 28, 0, 0, 0);
const qualificationDateValue3 = new Date(2021, 11, 21, 0, 0, 0);
const updateData = {
qualificationList: {
value: [
{
value: {
qualificationName: {
type: 'SINGLE_LINE_TEXT',
value: 'ITパスポート',
},
qualificationDate: {
type: 'DATE',
value: Utilities.formatDate(qualificationDateValue1, 'JST', 'yyyy-MM-dd'),
},
qualificationAmount: {
type: 'NUMBER',
value: '0',
},
}
},
{
value: {
qualificationName: {
type: 'SINGLE_LINE_TEXT',
value: '簿記2級',
},
qualificationDate: {
type: 'DATE',
value: Utilities.formatDate(qualificationDateValue2, 'JST', 'yyyy-MM-dd'),
},
qualificationAmount: {
type: 'NUMBER',
value: '2000',
},
}
},
{
value: {
qualificationName: {
type: 'SINGLE_LINE_TEXT',
value: '基本情報技術者試験',
},
qualificationDate: {
type: 'DATE',
value: Utilities.formatDate(qualificationDateValue3, 'JST', 'yyyy-MM-dd'),
},
qualificationAmount: {
type: 'NUMBER',
value: '3000',
},
}
},
]
},
}
const updateKey = {
field: 'userName',
value: '山田太郎',
}
横着して前回と同じ更新データを用意しましたが、つまりは更新したい内容はそのまま流用できる形式って事です!
大事なのはこのパートの一番最後に記載しているupdateKey
の書式です。
getRecords()
で用いたようなuserName = "山田太郎"
というクエリ文字列の形式ではなく、オブジェクト形式で対象フィールドコードと値を指定します。
またこのようにupdateKey
を指定した場合、レコード番号の指定は使用できません。
スクリプトプロパティから秘匿した設定を取得
const subDomain = scriptProperties.getProperty('subdomain')
const appId = Number(scriptProperties.getProperty('appId'))
const appToken = scriptProperties.getProperty('appToken')
ここはいつも通りです。
パラメータ・リクエストヘッダ・リクエストボディの作成
const url = `https://${subDomain}.cybozu.com/k/v1/record.json`;
const options = {
method: 'PUT',
headers: {
'X-Cybozu-API-Token': appToken,
'Content-Type': 'application/json',
},
muteHttpExceptions: true,
payload: JSON.stringify({
app: appId,
updateKey: uniqueKey,
record: recordData,
}),
};
ここも前回とほぼ同じです。payload: {}
の中にあるオブジェクトがid: recordID
からupdateKey: uniqueKey
に変わっているだけです。
たとえば今回のケースで考えると 山田太郎さんと同姓同名の人が複数人いたらどうなるの? という疑問が生じますが、
const url = `https://${subDomain}.cybozu.com/k/v1/record.json`;
この行の最後をみてください。~/record.json
となっています。
~/record.json
を使う場合は、updateKey
で指定できるフィールドは重複不可のフィールドのみになっています。ですので、 同姓同名の人が存在しない 事が保証されているkintoneアプリという事です。
updateKey
を使って複数のレコードをまとめて更新したい!て場合は、別途記事にする~/records.json
を使う手法もあります。
リクエストする
try {
const resp = UrlFetchApp.fetch(url, options);
if (resp.getResponseCode()!==200) {
throw new Error(`レコード更新エラー:\n HTTPステータス:${resp.getResponseCode()}\n レスポンス :${resp.toString()}`);
}
return JSON.parse(resp.getContentText());
} catch (error) {
throw new Error(error.message);
}
上の「パラメータ・リクエストヘッダ・リクエストボディの作成」が肝になるのでここは他記事と同じですが、GASスクリプト標準のHTTPリクエストUrlFetchApp.fetch
を使って外部(kintone)にHTTPリクエストします。
レスポンスコードが200以外はエラーになるので、その場合にはエラーをthrow
するようにしています。
Discussion