【LINE botから画像送信する方法】問いかけると柴犬の画像を返してくれるLINE botを作ってみた

#概要
　LINE botでできることを調べていたら、画像を返すことが可能とのことで試してみました。
ただ画像を返すだけでは面白くないので、柴犬APIで画像を拾ってきて表示することにしました。最後にソースコードの全体を載せています。

　柴犬APIについては[こちら](https://shibe.online/)をご参照ください。実際の動きは次のようになります。

【デモ】
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">LINE botって、画像を返してくれる機能もあるのですね！ということで、問いかけると柴犬の画像を返してくれるLINE botを作ってみました🐶<a href="https://twitter.com/hashtag/protoout?src=hash&amp;ref_src=twsrc%5Etfw">#protoout</a> <a href="https://t.co/iHNFAQvcfR">pic.twitter.com/iHNFAQvcfR</a></p>&mdash; まえぷー@出窓菜園 BWG (@kmaepu) <a href="https://twitter.com/kmaepu/status/1246382355234697219?ref_src=twsrc%5Etfw">April 4, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 

#構成
　主な構成は次の通りです。LINE botからテキストを送ると、ローカルにあるNode.jsサーバにWebhookが投げられ、LINE Messaging APIのフォーマットに従って画像URlが返されます。

![画像送信の構成図.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183282/636649b2-3cb0-42cc-0811-4f64639b97ce.jpeg)

#作ってみる
##開発環境
OS：Windows 10
Node.js：v10.15.3

【ライブラリバージョン】
@line/bot-sdk：6.8.4
express：4.17.1
axios：0.19.2

##プログラム解説
 プログラムの全体は最後に載せるとして、ここでは重要なところのみ解説します。
LINE botのサーバで、画像を返すフォーマットは次の通りです。

```javascript

return client.replyMessage(event.replyToken, {
    type: 'image',
    originalContentUrl: 'オリジナルサイズの画像URL', 
    previewImageUrl: 'LINEアプリのトーク画面にプレビューされるサイズの画像URL'
  });

```

　**画像URL**を指定するため、GoogleドライブやDropboxなどのストレージを使う必要があります。
　また、使用できる画像サイズに限度があるようです。詳しくは[こちら](https://developers.line.biz/ja/reference/messaging-api/#image-message)のLINE Developerサイトを参照してください。

　今回の例では、次のように柴犬APiを利用して得られた画像URLを、固定で入力しています。

```javascript

return client.replyMessage(event.replyToken, {
    type: 'image',
    originalContentUrl: 'https://cdn.shibe.online/shibes/907fed97467e36f3075211872d98f407398126c4.jpg', 
    previewImageUrl: 'https://cdn.shibe.online/shibes/907fed97467e36f3075211872d98f407398126c4.jpg'
  });

```

#余談
　ここまで至るにも苦労しました(;'∀')
なぜか画像が送れないなーと色々悩んでいて、最終的にはDiscordの[ProtoOutStudio](https://protoout.studio/)の技術質問チャンネルに投げかけました。嬉しいことに2期生の方が動作確認して誤り個所を教えていただきました。本当に感謝しています。
　結局は返すフォーマットが間違っていただけなんて....。次からはもっとちゃんと仕様を読んで理解せねば！

　と、いうことで画像を送ることができました。次は自宅で稼働している菜園管理システムとつなげて、画像を一定時間ごとに送れるようにしていこうと思います。

#参考
[LINE Messaging API でできることまとめ【送信編】](https://qiita.com/kakakaori830/items/52e52d969800de61ce28)

#ソースコード

```javascript

'use strict';

const axios = require('axios');         // 追加
const express = require('express');
const line = require('@line/bot-sdk');
const PORT = process.env.PORT || 3000;

const config = {
    channelSecret: 'LINE botのチャンネルシークレット',
    channelAccessToken: 'LINE botのアクセストークン'
};

const app = express();

app.get('/', (req, res) => res.send('Hello LINE BOT!(GET)')); //ブラウザ確認用(無くても問題ない)
app.post('/webhook', line.middleware(config), (req, res) => {
    console.log(req.body.events);

    //ここのif文はdeveloper consoleの"接続確認"用なので後で削除して問題ないです。
    if(req.body.events[0].replyToken === '00000000000000000000000000000000' && req.body.events[1].replyToken === 'ffffffffffffffffffffffffffffffff'){
        res.send('Hello LINE BOT!(POST)');
        console.log('疎通確認用');
        return; 
    }

    Promise
      .all(req.body.events.map(handleEvent))
      .then((result) => res.json(result));
});

const client = new line.Client(config);

function handleEvent(event) {

  if (event.type !== 'message' || event.message.type !== 'text') {
    return Promise.resolve(null);
  }

  return client.replyMessage(event.replyToken, {
    type: 'image',
    originalContentUrl: 'https://cdn.shibe.online/shibes/907fed97467e36f3075211872d98f407398126c4.jpg', 
    previewImageUrl: 'https://cdn.shibe.online/shibes/907fed97467e36f3075211872d98f407398126c4.jpg'
  });
}
app.listen(PORT);
console.log(`Server running at ${PORT}`);

```