AIさかなクンBot 旬魚レシピをギョ提案～ #LINEDC

## 魚は声じゃなく『会話』で売れ!!

　こんにちは。とあるスーパーの元鮮魚担当です。
　働き始めの頃、よくベテラン職人さんに怒られました。

　<font color="Red">**声じゃなく『会話』で売れ! 魚の旬や食べ方をお客さまに提案しろ!**</font>

　とはいえ丸魚のままだとアジとサバの違いもよく分からないし…
　分からないから職人さんに質問したら「自分でしらべろぃ!」って怒られるし…

　今はスマホが普及したとはいえ毎回検索するのは大変なはず。そこで…
　<font color="Red">**パパっと旬魚とレシピ、そして動画を教えてくれるAIBotを開発しました🐟**</font>


<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ぎょぎょぎょ〜🐟<br>旬の魚が検索できて<br>レシピ＆なんと動画も<br>教えてくれるAIBotが完成📷<br>いい感じでギョざいます🎣<a href="https://twitter.com/hashtag/LINEDC?src=hash&amp;ref_src=twsrc%5Etfw">#LINEDC</a> <a href="https://twitter.com/hashtag/ChatGPT?src=hash&amp;ref_src=twsrc%5Etfw">#ChatGPT</a> <a href="https://twitter.com/hashtag/LINE%E3%82%92%E5%AD%A6%E3%81%B6%E5%85%83%E9%AE%AE%E9%AD%9A%E6%8B%85%E5%BD%93?src=hash&amp;ref_src=twsrc%5Etfw">#LINEを学ぶ元鮮魚担当</a> <a href="https://t.co/hALrzcm5Fg">pic.twitter.com/hALrzcm5Fg</a></p>&mdash; おきなかがいこつ💀 (@okinakamasayos1) <a href="https://twitter.com/okinakamasayos1/status/1663530365112442880?ref_src=twsrc%5Etfw">May 30, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


## こだわったところギョ紹介
### ①旬魚サジェストリッチメニュー
春夏秋冬の旬魚をリストからパっと選べるように、リッチメニューを作成。
まず季節を選びそのあと魚種が出るように、`リッチメニュー切り替え` で整理整頓。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1793443/2171b775-89c9-e5dd-9394-5629a04d125b.png)


4季節×4魚種＝16種の旬魚を、見やすく配置させました。

もちろんフリーで魚の名前を打ち込んでもレシピ提案してくれます！

https://qiita.com/okinakamasayoshi/items/4053c491943133fba900

### ②YouTube動画
レシピ動画も欲しいが、ChatGPTは動画を探してこれないので、プロンプトで指示。
`https://www.youtube.com/results?search_query=[提案された料理名]+作り方` 
とURLを生成させました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1793443/768e3b27-b91a-00d3-1918-e7ff08718134.png)

これで、調理イメージもお客さまにお伝え出来ますね。

## コードとプロンプト

 <details><summary>コードとプロンプトはこちら
 <font color="Red">(クリックで表示)</font></summary><div><br><br>

```js

'use strict';

// ########################################
//               初期設定など
// ########################################

// モジュールの読み込み
const line = require('@line/bot-sdk');
const openai = require('openai');
const express = require('express');

const PORT = process.env.PORT || 3000;

// 設定
const config = {
  channelSecret: process.env.CHANNEL_SECRET || '*****',
  channelAccessToken: process.env.CHANNEL_ACCESS_TOKEN || '*****',
};

// クライアントの作成
const client = new line.Client(config);

const gptConfig = new openai.Configuration({
    organization: process.env.OPENAI_ORGANIZATION || "*****",
    apiKey: process.env.OPENAI_API_KEY || '*****',
});

const gpt = new openai.OpenAIApi(gptConfig);

const makeCompletion = async (userMessage) => {
  const prompt = {
      role: "system", 
      content: "# レシピ提案チャットボット" +

      "## 魚の名前を教えてください" +
      "まず魚の名前を教えてください。" +
      
      "### やり取りのフォーマット" +
      "①ユーザー：魚の名前を入力します。" +
      "②チャットボット：入力された魚の名前に基づいて、代表的なレシピを提案します。" +
      
      "### やり取りのフォーマットの詳細" +
      "②のレシピ提案は以下の通り" +
      
      "ぎょぎょぎょ～🐟！[提案された魚名]の人気のレシピをギョ紹介いたします～🐠" +
      
      "レシピ名:" +
       
      "材料:" +
      
      "調理手順:" +
      
      "動画で確認するには、こちらのリンクをギョ覧ください🎣: " +
      
      "[提案された魚名]を美味しく食べてくれて、ありがとうギョざいます～😁" +
      
      "####動画のURLは下記のように生成" +
      
      "https://www.youtube.com/results?search_query=[提案された料理名]+作り方"
  };

  userMessage.unshift(prompt);
  console.log(userMessage);
  return await gpt.createChatCompletion({
      model: "gpt-3.5-turbo",
      messages: userMessage,
      temperature: 0.5,
      n: 1
  });
};

// メッセージイベントの処理
async function handleEvent(event) {
    // テキストメッセージ以外は無視
    if (event.type !== 'message' || event.message.type !== 'text') {
      return Promise.resolve(null);
    }
  
    const userMessage = [{
      role: "user",
      content: event.message.text
    }];
  
    // 「ちょっと待ってギョ…」とプッシュメッセージを送る
    await client.pushMessage(event.source.userId, {
      type: 'text',
      text: 'ちょっと待ってギョ…🎣',
    });
  
    // ChatGPT APIにリクエストを送る
    try {
      const completion = await makeCompletion(userMessage);
      // レスポンスから返答を取得
      const reply = completion.data.choices[0].message.content;
      // 返答をLINEに送る
      return client.replyMessage(event.replyToken, {
        type: 'text',
        text: reply
      });
    } catch (error) {
      // エラーが発生した場合はログに出力
      console.error(error);
      return Promise.resolve(null);
    }
  }

// ここ以降は理解しなくてOKです
const app = express();
app.get('/', (req, res) => res.send('Hello LINE BOT! (HTTP GET)'));
app.post('/webhook', line.middleware(config), (req, res) => {

  if (req.body.events.length === 0) {
    res.send('Hello LINE BOT! (HTTP POST)');
    console.log('検証イベントを受信しました！');
    return;
  } else {
    console.log('受信しました:', req.body.events);
  }

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


app.listen(PORT);
console.log(`ポート${PORT}番でExpressサーバーを実行中です…`);
```
</div></details>

## 妻の反応

 **なんで1種類しか提案レシピないん…押しつけか？選びたいやろ普通！**
 
 …ぎょぎょぎょ

## データベースを用いて提案型Botに挑戦中

 レシピをいくつか提案してもらい、その中から選択できるようにしたい。

 下記の流れをまずChatGPT上のプロンプトで指示。

 ①魚の名前を打ち込む
 ②レシピが5種類サジェストされる
 ③1~5の番号を選ぶ
 ④そのレシピを提案

 ChatGPT上では上手く実行できたが…

 <details><summary>プロンプトはこちら
 <font color="Red">(クリックで表示)</font></summary><div><br><br>

```js
# レシピ提案チャットボット

## 魚の名前を教えてください
まず魚の名前を教えてください。

### やり取りのフォーマット
①ユーザー：魚の名前を入力します。
②チャットボット：入力された魚の名前に基づいて、代表的なレシピ名を5つ提案します。
③ユーザー：提案されたレシピの番号を選択します。
④チャットボット：選ばれたレシピの詳細と作り方動画へのリンクを提供します。
⑤ユーザー：「もどる」と入力すると、再び5つの提案が表示されます。
⑥ユーザー：再び番号を選択することで、別のレシピの詳細と作り方動画を取得できます。
⑦ユーザー：ご質問や追加の提案があれば、それをチャットボットに尋ねることができます。

### やり取りのフォーマットの詳細
#### ②のレシピを紹介する際は下記の通り

ぎょぎょぎょ～🐟
[提案された魚名]美味しいいですよね！[提案された魚名]の代表的なレシピ名を5つ提案いたします！
番号を教えていただければ、レシピの・作り方・動画へのリンクをお伝えするよ！

①
②
③
④
⑤

番号をボタンからクリックしてね🐠
[提案された魚名]を美味しく食べてくれて、ありがとうギョざいます～😁


#### ④の料理提案の際は下記の通り
ぎょえ～！[提案された料理名]、素晴らしい選択でギョざいます🐠

レシピ名:
 
材料:

調理手順:

動画で確認するには、こちらのリンクをギョ覧ください🎣: 
レシピ一覧に戻るには、「もどる」ボタンをクリックしてください🐡

[提案された魚名]を美味しく食べてくれて、ありがとうギョざいます～😁

#####
動画のURLは下記のように生成

https://www.youtube.com/results?search_query=[提案された料理名]+作り方
```
</div></details>

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1793443/713091dd-601c-195a-1e25-f5c4e7749f6b.png)

Botだとデータベースを保持していないため上手くやり取りできない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1793443/0250c3d8-10d8-4309-0163-5f263a15bb49.png)

データベースを活用して、Botを作り切った猛者を発見。

https://protopedia.net/prototype/3803

なかなか難しそう。でも、

## 魚を食べると

 頭が良くなってできるはず。苦戦してますが継続開発頑張ります🐠
最後まで読んでくれてありがとうギョざいます🐠

https://twitter.com/okinakamasayos1/status/1663205229360455680