teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

コメントに対する追記

2019/05/22 08:35

投稿

sansaisoba
sansaisoba

スコア241

answer CHANGED
@@ -8,4 +8,37 @@
8
8
 
9
9
  nodeのSDKを使用している場合は、
10
10
  [https://line.github.io/line-bot-sdk-nodejs/api-reference/client.html#methods](https://line.github.io/line-bot-sdk-nodejs/api-reference/client.html#methods)
11
- `client.getMessageContent()`に、`event.message.id`を指定することで`readable stream`が取得できますので、それを元に画像の書き込みを行うと良いでしょう。
11
+ `client.getMessageContent()`に、`event.message.id`を指定することで`readable stream`が取得できますので、それを元に画像の書き込みを行うと良いでしょう。
12
+
13
+ 追記
14
+ ---
15
+
16
+ [getMessageContent()](https://line.github.io/line-bot-sdk-nodejs/api-reference/client.html#methods) のマニュアルにもある通り、
17
+
18
+ > Please beware that what it returns is promise of readable stream. You can pipe the stream into a file, an HTTP response, etc.
19
+
20
+ `getMessageContent()`のcallbackで返ってくるのは[readable stream](https://nodejs.org/dist/latest/docs/api/stream.html#stream_readable_streams)です
21
+
22
+ ある程度の大きさの画像の場合、`stream.on('data')`は、chunkに分けられて複数回呼び出されます。
23
+ ```javascript
24
+ stream.on('data', (chunk) => {
25
+ console.log(`Received ${chunk.length} bytes of data.`);
26
+ });
27
+ ```
28
+ のようにして見れば、何度も呼び出されているのがわかると思います。
29
+
30
+ > コードを変えても0バイトの画像が出力されます。
31
+
32
+ 何度も呼び出されますので、最後に呼び出されたものしか書き込まれていないのでしょう。
33
+ (なので、正確には0バイトではなく数バイトにはなってると思いますが壊れた画像になっているはずです。)
34
+
35
+ [Node.js Stream を使いこなす - Qiita](https://qiita.com/masakura/items/5683e8e3e655bfda6756)
36
+
37
+ こちらを参考に、`fs.writeFile()`を使うのではなく、`fs.createWriteStream()`で作成したWriteable Streamにpipeしてやれば動作するはずです。
38
+
39
+ ```javascript
40
+ const dest = fs.createWriteStream('./out/test.jpg', 'binary');
41
+ client.getMessageContent(event.message.id).then(stream => {
42
+ stream.pipe(dest);
43
+ })
44
+ ```