LINE WORKS のトーク Bot を使って送信した画像をLINE WORKSのストレージからダウンロードして、 Node.js サーバーにアップロードするサンプルです。
LINE WORKSのストレージからダウンロードした画像はarraybufferの形です。
axiosを利用します。
ダメなコード
import Axios from 'axios';
import FormData from 'form-data';
......
try {
const lwResponse = await Axios.get(
'http://storage.worksmobile.com/openapi/message/download.api',
{
headers: {
consumerKey: consumerKey,
authorization: 'Bearer ' + accessToken,
'x-works-apiid': apiId,
'x-works-resource-id': resourceId,
},
responseType: 'arraybuffer',
}
);
const formdata = new FormData();
formdata.append('file', arraybuffer);
await Axios.post(
toUrl,
formdata,
{
headers: {
'content-Type': 'multipart/form-data',
}
}
)
.then((response) => {
console.log(response.data);
})
.catch((error) => {
throw error;
});
} catch (error) {
console.error(error);
}
form-data の boundary(境界線) エラーと403エラーが出ました。
ヘッダーを出力して見ると、確かにboundaryのデータがありませんでした。
Content-Type: multipart/form-data; boundary=
403エラーの原因は、アップロードしようとするファイルのメタ情報が足りないからです。
Bufferデータを処理しないとアップロードできないと思いましたが関係ありませんでした。
修正後のコード:
import Axios from 'axios';
const FormData = require('form-data');
......
try {
const lwResponse = await Axios.get(
'http://storage.worksmobile.com/openapi/message/download.api',
{
headers: {
consumerKey: consumerKey,
authorization: 'Bearer ' + accessToken,
'x-works-apiid': apiId,
'x-works-resource-id': resourceId,
},
responseType: 'arraybuffer',
}
);
const formdata = new FormData();
formdata.append('file', imageBuffer, {
filename: 'dummy.jpg', //ポイント1:ダミーファイルを設定してメタ情報をつける
});
await Axios.post(
toUrl,
formdata,
{
headers: formdata.getHeaders(), //ポイント2:getHeadersでヘッダーを取得
}
)
.then((response) => {
console.log(response.data);
})
.catch((error) => {
throw error;
});
} catch (error) {
console.error(error);
}
-
ポイント1:ダミーファイルを設定してメタ情報をつける
画像をNode.js サーバにダウンロードして保存先の実際のファイル名で指定する方法もあります。ダウンロードした画像を参照しない場合はダミーファイル名のがおすすめです。 -
ポイント2:FormDataのgetHeadersでヘッダーを取得
通常のcontent-Type: multipart/form-data
だとboundary情報がなくなるようです。