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トークン。 「レコード追加」の権限が必要。「レコード閲覧」権限は不要です。 |
appToken (例外) | ABCDEFG1234567,HIJKLMN8901234 | 追加するデータに フィールド形式:ルックアップ を含む場合は、ルックアップ先アプリの「レコード閲覧」権限があるAPIトークンが必要です。 APIトークン同士は","で区切ります。 |
更新先アプリ
以下アプリ(例)の任意のレコードを更新します。
フィールド名 | フィールドコード | フィールド形式 | 更新したい値 | |
---|---|---|---|---|
保有資格 | 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 resp = updateRecordByID(1,updateData)
Logger.log(resp)
}
/**
* スクリプトプロパティに設定したアプリのレコードを1件更新
*/
function updateRecordByID(recordID, recordData) {
const subDomain = scriptProperties.getProperty('subdomain')
const appId = Number(scriptProperties.getProperty('appId'))
const appToken = scriptProperties.getProperty('appToken')
if (!Number.isInteger(recordID)) {
throw new TypeError('recordIDは数値で指定してください。');
}
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,
id: recordID,
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',
},
}
},
]
},
}
今回はレコード番号1
の、フィールドコード名qualificationList
の内容を更新するようデータを用意しました。
テーブルの場合は[]
や{}
でのネストが多く、しかもキー名value
もそこそこ使うためややこしく感じますが、階層構造さえしっかりイメージできていれば、あとは慣れの問題にできます。
とは言えテーブル内容を更新するコードは頻繁に書かないため、毎回初めましての気分でコーディングしていますので、フィールド形式のページを毎回確認しています。
実際の利用方法としては、この書き方よりもforeach((item)=>{})
やmap((item)=>{})
でループして内容を生成するのが多いのではないでしょうか。
その方が効率的かつ動的な内容にも対応させやすいです。
スクリプトプロパティから秘匿した設定を取得
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,
id: recordID,
record: recordData,
}),
};
ここも、レコードを追加するときの書き方と大きくは変わりません。
唯一違うのが、payload
の中にid: recordID
が必要なくらいです。
リクエストする
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