🍡
GASでGoogleDrive上のファイルをkintoneにupする
GoogleDrive上のファイルをkintoneにアップロードします👀
アプリの準備
↓の記事のようなアプリを準備します。
必要なフィールドは添付ファイルフィールド!
必要なトークンやらIDやらを集める
fileID
googleDriveのファイルを右クリックして「リンクを取得」
d/
と/view
に挟まれた部分がfileIDです。コピっておきます。
https://drive.google.com/file/d/【ファイルID】/view?usp=sharing
CSRFトークン
↓こちらを参考に
kintoneのポータルなどで開発ツールを開いて
↓のように入力すると表示されます。
kintone.getRequestToken()
APIトークン
↓こちらを参考に取得してね。レコード追加、レコード編集にもチェックを入れておきましょう。
定義しておこう
必要な情報を取り急ぎ定義しておきましょう。
// GoogleDrive にあるファイルを取得
const file = DriveApp.getFileById("【ファイルID】");
// CSRFトークン
const csrfToken = '【CSRFトークン】';
// APIトークン
const apiToken ='【APIトークン】';
// 区切り文字
const boundary = '【とりあえず英数字なら何でも良いとおもう】';
// kintoneのURL
const url = "https://【サブドメイン】.cybozu.com/k/v1/";
// アプリのID
const appId = 485;
ファイルアップロード
アップロード用のfileKeyを取得してから、レコードを追加(または更新)するという2段構えです。
↓これをGASでやります。
アップロード用fileKeyの取得
アップロード用のfileKeyを取得します。
リクエストボディを作るのがとても大変でした。
↓このあたりを行ったり来たりして作りました🙏
- フォームよるファイルアップロードの仕様
- ファイルアップロードで必須となる3つの手順
- multipart/form-dataのファイルをGoogle Apps Scriptから送信する
- Class UrlFetchApp
// ★ファイルをアップロードしてfileKeyを取得する
// GoogleDriveのファイルからBlobを取得
const blob = file.getBlob();
// リクエストボディを作る
const bodyText =
`--${boundary}\r\n
__REQUEST_TOKEN__:"${csrfToken}"\r\n
Content-Disposition: form-data; name="file"; filename="${blob.getName()}"\r\n
Content-Type: ${blob.getContentType()}\r\n\r\n`;
const requestBody = Utilities.newBlob(bodyText).getBytes()
.concat(blob.getBytes())
.concat(Utilities.newBlob('\r\n--' + boundary + '--\r\n').getBytes());
const options_file = {
method: "post",
contentType: "multipart/form-data; boundary="+boundary,
payload: requestBody,
'headers' : {
'X-Cybozu-API-Token' : apiToken,
},
};
// fileKeyをゲットする
const resp_file = UrlFetchApp.fetch(url +'file.json',options_file);
const data_file = JSON.parse(resp_file);
const fileKey = data_file.fileKey;
レコードの追加
fileKeyが取得できたら、レコードを追加(または更新)してアップロード完了となります。
// ★レコードを追加する
const body = {
"app": appId,
"record": {
"添付ファイル": {
"value": [
{
"fileKey": fileKey
}
]
}
}
};
const options_post = {
"method":"post",
"contentType":"application/json",
"headers" : {
'X-Cybozu-API-Token' : apiToken,
},
"payload": JSON.stringify(body),
};
// レコード追加!
const resp_post = UrlFetchApp.fetch(url+'record.json',options_post);
コード全体
シングルクォーテーションとダブルクォーテーションが混在していたり、
スペースが空いていたり空いていなかったり、
キャメルケースだったりスネークケースだったり、
ダラっと書いていたりするので
使いたいときは、キレイに書き直して使ってね👀
function GoogleDrive2kintone(){
// GoogleDrive にあるファイルを取得
const file = DriveApp.getFileById("【ファイルID】");
// CSRFトークン
const csrfToken = '【CSRFトークン】';
// APIトークン
const apiToken ='【APIトークン】';
// 区切り文字
const boundary = '【とりあえず英数字なら何でも良いとおもう】';
// kintoneのURL
const url = "https://【サブドメイン】.cybozu.com/k/v1/";
// アプリのID
const appId = 485;
// ★ファイルをアップロードしてfileKeyを取得する
// GoogleDriveのファイルからBlobを取得
const blob = file.getBlob();
// リクエストボディを作る
const bodyText =
`--${boundary}\r\n
__REQUEST_TOKEN__:"${csrfToken}"\r\n
Content-Disposition: form-data; name="file"; filename="${blob.getName()}"\r\n
Content-Type: ${blob.getContentType()}\r\n\r\n`;
const requestBody = Utilities.newBlob(bodyText).getBytes()
.concat(blob.getBytes())
.concat(Utilities.newBlob('\r\n--' + boundary + '--\r\n').getBytes());
const options_file = {
method: "post",
contentType: "multipart/form-data; boundary="+boundary,
payload: requestBody,
'headers' : {
'X-Cybozu-API-Token' : apiToken,
},
};
// fileKeyをゲットする
const resp_file = UrlFetchApp.fetch(url +'file.json',options_file);
const data_file = JSON.parse(resp_file);
const fileKey = data_file.fileKey;
// ★レコードを追加する
const body = {
"app": appId,
"record": {
"添付ファイル": {
"value": [
{
"fileKey": fileKey
}
]
}
}
};
const options_post = {
"method":"post",
"contentType":"application/json",
"headers" : {
'X-Cybozu-API-Token' : apiToken,
},
"payload": JSON.stringify(body),
};
// レコード追加!
const resp_post = UrlFetchApp.fetch(url+'record.json',options_post);
}
Discussion
記事の執筆ありがとうございます。
2023/11/17時点のkintoneではファイルアップロードに失敗するようです。
おそらく文字列テンプレート内の改行記号とスペースが原因でRFCに準拠しないため、
エラーが帰ってきてしまいます。次のように修正するとファイルアップロードが行えました
少し話は逸れますが、
__REQUEST_TOKEN__
は不要と思われます。タイムリーな情報、助かりました。ありがとうございます。
急にエラーが出始めて困っていました。
大変助かります。
ありがとうございました。
yokotaso さん、ありがとうございます!!!!
読者の皆様!
大変申し訳無いのですが、修正する余裕がないので yokotaso さんのコードでなんとかしてください🙏