LINEWORKS のコンテンツアップロード API を使う

LINEWORKS には色々な API があるのですが、結構使ったことのない API が多いです。
パッと見てわかる API はいいのですが「え、これ、どうやって使うの…？」って思う API もたまにあります。
（私の知識不足のせいかもしれませんが・・・）

今回はトーク Bot の「[コンテンツアップロード API](https://developers.worksmobile.com/jp/document/1005025?lang=ja)」の使い方を勉強しました！

bot が送信する画像ファイルを予めアップロードしておき、発行された `resourceId` を使ってあれやこれやすることができます。
便利ですね！（謎）

それでは、実際のコードをどうぞ！(^^)/

```js:upload.js

const fs = require('fs');
const request = require('request');

const options = {
    method: 'POST',
    url: 'http://storage.worksmobile.com/openapi/message/upload.api',
    headers: {
        'authorization': token,
        'x-works-apiid': apiid,
        'consumerKey': consumerkey,
        'content-type': 'multipart/form-data; boundary=----WebKitFormBoundary1234567890abc'
    },
    formData: {
        resourceName: {
            value: fs.createReadStream("./testPng.png"),
            options: {
                filename: './testPng.png',
                contentType: null
            }
        }
    }
};
request(options, function (error, response, body) {
    if (error) {
        console.log("error start");
        console.log(error); 
        return;
    }
    console.log("resource-id : " + response.headers["x-works-resource-id"]);
});

```

```console:実行結果
resource-id : WAAAQLrbUHwtPzJkJ55S5dg1owx1ms3AdJWzT1XQwjNxPOWUzecUYDzxrEItESuuSrDiobOHfaFizU7bgThBZQT0Ju4=
```

それでは解説をいくつか。

##アップロードするには fs モジュールを使う
`fs` は、Node.js でファイルを操作するための公式モジュールとして提供されています。
node.js が使える環境なら `require('fs')` すればすぐに使えます。
今回は `fs.createReadStream` で読み取り用の stream を値として渡しています。
ちなみに画像は `upload.js` と同じ階層に置いています。
`fs.createReadStream("./testPng.png")`

`createReadStream` については詳しく解説している方がたくさんいらっしゃるのでご参考ください。
※参考にさせていただきました：[Node.js Stream を使いこなす](https://qiita.com/masakura/items/5683e8e3e655bfda6756)

##Content-Type: multipart/form-data
`content-type` は `application/json` ではありません。
`multipart/form-data` です。
`boundary` は「ここからがデータだよ！」っていう目印だそうです。
私も「ふーん、そうなんだー('ω')」ってくらいの理解度です。もっと勉強します。

##resource-id は headers の中に
これ、今回一番苦戦しました。
ドキュメントをよく読めって話なんですが、`resource-id` が `body` じゃなくて `headers` に入ってるんですよ。

```console:headersの中身
{ server: 'FileCloud',
  'content-type': 'application/json;charset=UTF-8',
  etag: '1559634647',
  'x-works-resource-id': 'WAAAQLrbUHwtPzJkJ55S5dg1owwrb6O+C0yXCms9xbKeXluK9PWNiydzSCp0ECOZyQwhZVJMuMl5DDymyDT2xlXJs0A=',
  'content-length': '155' }
```

`x-works-resource-id` ってやつです。
でも、`body` の中には `resourceCid` っていう名前の値があるんですよ。

```console:bodyの中身
{
        "code":0,
        "message":"success",
        "result":{
                "accessKey":"",
                "resourceCid":"1559888966145939007",
                "resourceSize":10084,
                "streamLength":10084
        }
}
```

完全に、トラップ。
これだと思って使ったら、エラーになって返ってくるという恐ろしい罠。

しかも、ドキュメントのどこ読んでも `resourceCid` が何なのかの解説はなし。
`resourceCid` の `C` とはいったい何なのか。謎は深まるばかりです。

まぁ、わからんちんの `C` ちゃんは放っておいて、取得した `resource-id` で Bot からメッセージを送信したり、別の場所に画像をダウンロードしたりしましょう！

#おわりに
ここまでお付き合いいただきありがとうございました。
次はこのお話の続きってことで、コンテンツダウンロード API の解説にしようと思います。

でも、公式ドキュメントの Request Example、色んな言語の Sample code 用意してくれたらいいのにね！
日本語のドキュメントがあるだけで親切なのかもしれませんが。
英語や韓国語、勉強しないとかなぁ。

ではまた！(^^)/

#参考にさせていただきましたm(_ _)m
[LINEWORKS Developers](https://developers.worksmobile.com/jp/document?lang=ja)
[Node.js Stream を使いこなす](https://qiita.com/masakura/items/5683e8e3e655bfda6756)