LINE BOTからNode.jsで画像を受け取って保存する


調べてもピンポイントな記事がなかったのでメモ。

普段axiosが多いですが、今回はrequestモジュールを使ってます。

Messaging APIのリファレンスのコンテンツを取得するによると、

GET https://api.line.me/v2/bot/message/{messageId}/contentで取得できます。

  • ユーザー: BOTに画像を送る
  • BOT: ユーザーから投稿された画像が上記のURLに保存されるので、取得しにいく

といった流れです。

コード

記事最後の参考URLでかなり助かったのですが、encoding: nullにしないと保存した画像が壊れてしまってハマりました苦笑

server.js
'use strict';

const fs = require('fs');
const config = require('./config');
const express = require('express');
const bodyParser = require('body-parser');
const Request = require('request');
const accessToken = config.line.accessToken;
const app = express();
const PORT = process.env.PORT || 3000;
app.use(bodyParser.json());

app.post('/webhook', (req, res) => {
    if(req.body.events[0].message.type !== 'image') return;

    const options = {
        url: `https://api.line.me/v2/bot/message/${req.body.events[0].message.id}/content`,
        method: 'get',
        headers: {
            'Authorization': 'Bearer ' + accessToken,
        },
        encoding: null
    };

    Request(options, function(error, response, body) {
        if (!error && response.statusCode == 200) {
            //保存
            fs.writeFileSync(`./image.jpg`, new Buffer(body), 'binary');
            console.log('file saved');
        } else {
            // @todo handle error
        }
    });
});
app.listen(PORT);
console.log(`Server running at ${PORT}`);

ちなみにファイルは全てjpgになる様子なのでファイル名はimage.jpgで固定してます。

調べたい場合はfile-typeモジュールを使うと良さそうでした。

参考