Skip to content

別ドメインの kintone にファイルアップロード(kintone JavaScript API)

はじめに

kintone.proxy.upload() を利用して別ドメインにファイルをアップロードするコードのメモです。

ポイントは次の 2 つです。

  • kintone.proxy.upload() に渡す data.value には Blob 型を指定する
  • ファイルアップロード API は multipart/form-data 形式のみを受け付ける
const downloadFile = async ({ fileKey }) => {
const url = `/k/v1/file.json?fileKey=${fileKey}`;
const headers = { "X-Requested-With": "XMLHttpRequest" };
// ファイルダウンロードは kintone.api() では実行できない
const res = await fetch(url, { headers });
return res.arrayBuffer();
};
const stringToArrayBuffer = (string) => {
const arrayBuffer = new ArrayBuffer(string.length);
const uint8 = new Uint8Array(arrayBuffer);
return uint8.map((_, i) => string.charCodeAt(i)).buffer;
};
const mergeArrayBuffer = (ab1, ab2) => {
const uint8 = new Uint8Array(ab1.byteLength + ab2.byteLength);
uint8.set(new Uint8Array(ab1), 0);
uint8.set(new Uint8Array(ab2), ab1.byteLength);
return uint8.buffer;
};
const getPostData = ({ boundary, body, filename }) => {
let headerString = "";
headerString += `--${boundary}\r\n`;
headerString += `Content-Disposition: form-data; name="file"; filename="${filename}"\r\n`;
headerString += "Content-Type: application/octet-stream\r\n";
headerString += "\r\n";
let footerString = "";
footerString += "\r\n";
footerString += `--${boundary}--`;
const header = stringToArrayBuffer(headerString);
const footer = stringToArrayBuffer(footerString);
return [header, body, footer].reduce((ac, cu) => mergeArrayBuffer(ac, cu));
};
kintone.events.on("app.record.index.show", async (event) => {
// 登録先のドメインとAPIトークン
const domain = "xxx.cybozu.com";
const apiToken = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
// 登録元のファイル情報
const downloadFileKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
const filename = "xxxxx.xxx"; // 例)sample.png
const boundary = "boundary";
const body = await downloadFile({ fileKey: downloadFileKey });
const arrayBuffer = getPostData({ boundary, body, filename });
const url = `https://${domain}/k/v1/file.json`;
const params = {
"X-Cybozu-API-Token": apiToken,
"Content-Type": `multipart/form-data; boundary=${boundary}`,
};
const data = { format: "RAW", value: new Blob([arrayBuffer]) };
try {
const res = await kintone.proxy.upload(url, "POST", params, data);
const { fileKey } = JSON.parse(res[0]);
} catch (error) {
console.error(error);
}
return event;
});