楽天市場のAPIを使って買えるマスクを提案してくれるLINEBotを作ってみた

### はじめに
こちらの[1時間でLINE BOTを作るハンズオン](https://qiita.com/n0bisuke/items/ceaa09ef8898bee8369d)の記事をベースにLINEBotを作成しました。
最近の新型ウィルスの影響で、ネットショッピングばかりしているのですが、ちょっと楽天市場のトップ画面を見るのに飽きてきたので、マスクなどの必要なものを、（売り切ればかりなので）**買える商品**で、高額になりすぎて買う気がなくなってしまわない（金額の）範囲で、提案してもらえるLINEBotを考えました。
（Amazonは申請が大変そうに見えたのでお見送りしました）

### 概要と作れなかったところ
#### 概要
+ LINEBotにほしいもの、「マスク」と入力したら
    1. 楽天市場のキーワード検索から「マスク」を検索
    2. 絞り込み検索で「購入可能」
    3. 「最安価でソート」
    4. 「最低金額○円以上」
    5. 「最高金額○円以下」
    6. 商品画像付き
    7. を５つくらい返してくれるBot
    
#### 作れなかったところ
+ ほしいもの　「マスク」と入力したら　
    1. ○　→　楽天市場のキーワード検索から「マスク」を検索 
    2. ○　→　絞り込み検索で「購入可能」
    3. ○　→　「最安価でソート」
    4. ○　→　「最低金額○円以上」
    5. ○　→　「最高金額○円以下」
    6. ○　→　商品画像付き
    7. ○　→　を3つくらい返してくれるBot
    

入力したものをエンコードしてAPIのURLに入れて作成するところと、
（APIをベタでかくと動くBotはできたけど）これを複数表示するためにどこでFor文を回せばよいかわからなかった
#### 環境
Node.js v13.7.0
MacBook Pro macOS Mojave
Visual Studio Code v1.43.1

### できたもの
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a href="https://t.co/E50LjkFK3l">https://t.co/E50LjkFK3l</a><a href="https://twitter.com/hashtag/protoout?src=hash&amp;ref_src=twsrc%5Etfw">#protoout</a> <a href="https://t.co/xRjpcWEMYF">pic.twitter.com/xRjpcWEMYF</a></p>&mdash; 3yaka (@3yaka4) <a href="https://twitter.com/3yaka4/status/1243572715698569216?ref_src=twsrc%5Etfw">March 27, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

「マスクある？」と質問することで、楽天市場の中で在庫あり商品、最安価の商品名と商品URLと商品画像のあるマスクを提案してくれます。

#### 呼び出す 楽天のAPIの使い方
パラメーターは＆でつないでね

```
 https://app.rakuten.co.jp/services/api/IchibaItem/Search/20170706? format=json  //楽天のAPIのURLだよjsonで返すよ
 keyword=mask　　　　//検索キーワード　マスク　日本語はエンコードします　　
 genreId=501143　　  //ジャンル　マスク
 availability=1　　　//販売可能は１　不可は０
 sort=%2BitemPrice　//価格が安い順に並べる
 minPrice=1000      //最低価格
 maxPrice=4000　　   //最高価格
 carrier=2          //何用の情報かPC: 0 mobile: 1 smartphone: 2
 hits=3             //３商品取得
 applicationId=***  //自分のapplicationId
```

### コード
```node.js
'use strict';

const express = require('express');
const line = require('@line/bot-sdk');
const axios = require('axios');
const PORT = process.env.PORT || 3000;
const rakutenAPiurl = "***";
const rakutenAppId = '1003940711976508350';
const guidecat = 'https://i.gyazo.com/97840790b257952c89c59e7c176e114c.png';

const config = {
  channelSecret: '***',
  channelAccessToken: '***'
};

const app = express();

app.post('/webhook', line.middleware(config), (req, res) => {
  console.log(req.body.events);
  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);
  }

  let mes = event.message.text;
  if (mes.indexOf('？') > -1) {
    getNodeVer(event.source.userId, mes);
    return client.replyMessage(event.replyToken, [{
      type: 'image',
      originalContentUrl: guidecat,
      previewImageUrl: guidecat
    },
    { type: "text", text: '在庫があって安いのはこれだよ〜' }]);

  } else {
    // mes = event.message.text;

    return client.replyMessage(event.replyToken, [{
      type: 'image',
      originalContentUrl: guidecat,
      previewImageUrl: guidecat
    },
    { type: "text", text: '〇〇ある？って聞いてほしいな' }]);
  }

}

const getNodeVer = async (userId, mes) => {
  //console.log(mes);
  let ownword = mes.split('ある？');
  console.log('mes->' + mes + 'ownword->' + ownword);
  const res = await axios.get(rakutenAPiurl + '&keyword=' + encodeURIComponent(ownword) + '&genreId=501143&availability=1&sort=%2BitemPrice&minPrice=1000&maxPrice=4000&carrier=2&hits=3&applicationId=' + rakutenAppId);
  const items = res.data.Items;
  //console.log(items);
  for (let i = 0, len = items.length; i < len; i++) {
    const item = items[i].Item;
    const msg = `${item.itemName}\n ${item.itemUrl}\n¥${item.itemPrice}`;
    const itemimg = `${item.mediumImageUrls[0].imageUrl}`;

    await client.pushMessage(userId, {
      type: 'text',
      text: msg
    });

    await client.pushMessage(userId, {
      type: 'image',
      originalContentUrl: itemimg,
      previewImageUrl: itemimg
    });
  }
app.listen(PORT);
console.log(`Server running at ${PORT}`);
```

### 参考サイト
+ LINEBotでの画像の出しかた<br>
    + [Node\.jsでLINE BOTの画像送信を試す \- Qiita](https://qiita.com/n0bisuke/items/e2894a6186a9350dc09d)
+ こういうとこまで行きたかった。。。<br>
    + [LINE Messaging APIのテンプレートメッセージでチャットBOTを作る \- Qiita](https://qiita.com/romorimori/items/ac0afcfad226fdb8caa6)
+ [楽天ウェブサービス: API一覧](https://webservice.rakuten.co.jp/document/#ichibaApi) 

### 感想
深いAPIを操るの大変ですが自分好みの条件の商品をサクッと提案してもらえるBotはそれなりに便利そうなでちゃんと完成させねばです。
きっともっといい書き方や２回書かなくてもいいものとかたくさんある気がしますが、【未完】を取れるように早めにやっつけたいです。