ChatGPTを組み込んで低温調理に特化したLINE Botを作ったら軽く想像を超えてきた。

## 低温調理っていいですよね？

こんにちは

我が家には7歳と5歳の男児がいるのですが、とにかく肉が大好き。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3292587/53bd3a49-e78f-d951-e5db-eaa87759cac2.jpeg" alt="ステーキ" width="400" height="10">


休みの日に料理をすることもあるのですが、
「何食べたい？」
と聞くと、高確率で
「ステーキ！」か「ポロイチ！」と返ってきます。

:::note warn
ポロイチ＝サッポロ一番 味噌ラーメン
:::

なので我が家の週末の晩御飯はステーキになる確率が高いのですが、何か特別な記念日でもない限りそんなに高い牛肉は買えません。
（余談ですが、牛肉より魚の方が高くないですか？）

よって、スーパーで安い牛肉を買ってくるのですが、どうせなら美味しく食べたい！
ということで色々と調べて、試行錯誤を繰り返した結果、今は低温調理が一番楽で失敗が少ない方法だと思っております。

<details><summary>より詳細な調理方法はこちら（興味のある人は見て下さい）</summary><div>

・ゲランドの塩を重量の1.5％ぐらい
・低温調理
・高温のフライパンで焼き色を付ける
焼き色を付ける際、メイラード反応を促進するためにグルコースをまぶすとなお良いです。ローストポークの記事を参考にしていますが、肉全般に使えます。

https://engryouri.net/recipe/side-dishes/bake/8569

フライパンではなく、炭を起こして炭火で焼くのもオススメですが、結構手間がかかるので滅多にやりません。

</div></details>

低温調理は、肉の種類（牛肉や鶏肉）や厚みによって適した温度と調理時間が異なりますが、そんなものを覚えているわけもなく、毎回調べるのが面倒です（かつ、結構奥が深く色々な情報が出て来るので調べ始めると沼ります）。

そこで、
**肉の種類**
**大きさ（厚さ）**

を送れば、さっと返答してくれるLINE Botを作ってみました。
どうせならおすすめの付け合わせや味付け、お酒も教えて！

ChatGPT先生、お願いします！


## 指定したプロンプトはこちら

`## あなたは低温調理の専門家です。`
`## userが肉の種類と厚さを送ってくるので、適した温度と時間を教えてあげて下さい。`
`## また、追加でおすすめの付け合わせ、味付け、お酒も教えてあげて下さい。`
`## 更に追加でその肉を使った代表的な低温調理の画像を見つけて送ってください。`

下記コードのこちらの部分でChatGPTに役割を与え、LINEに打ち込んだ内容が質問と認識され、返答が来る。
というような流れになっております。

## コードはこちら

:::note warn
'作成したBotのチャネルシークレット'
'作成したBotのチャネルアクセストークン'
"取得したOrganization ID"
'取得したAPI key'
は書き換えて下さい。
:::

<details><summary>コード</summary><div>


```Node.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 || '作成したBotのチャネルシークレット',
  channelAccessToken: process.env.CHANNEL_ACCESS_TOKEN || '作成したBotのチャネルアクセストークン',
};

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

const gptConfig = new openai.Configuration({
  organization: process.env.OPENAI_ORGANIZATION || "取得したOrganization ID",
  apiKey: process.env.OPENAI_API_KEY || '取得したAPI key',
});

const gpt = new openai.OpenAIApi(gptConfig);

const makeCompletion = async (userMessage) => {
  const prompt = {
      role: "system", 
      content: `## あなたは低温調理の専門家です。
      ## userが肉の種類と厚さを送ってくるので、適した温度と時間を教えてあげて下さい。
      ## また、追加でおすすめの付け合わせ、味付け、お酒も教えてあげて下さい。
      ## 更に追加でその肉を使った代表的な低温調理の画像を見つけて送ってください。` // プロンプトを入力
  };

  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
  }];

  // ChatGPT APIにリクエストを送る
  try {
    const completion = await makeCompletion(userMessage);
    // レスポンスから返答を取得
    const reply = completion.data.choices[0].message.content;
    // ChatGPT APIからの返答を受け取り、テキストメッセージとスタンプを一度に送信
await client.replyMessage(event.replyToken, [
  { type: 'text', text: reply },
  { type: 'sticker', packageId: '789', stickerId: '10865' }
]);
   

    return Promise.resolve(null);
  } catch (error) {
    // エラーが発生した場合はログに出力
    console.error(error);
    return Promise.resolve(null);
  }
}

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>


## 実際の動き

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">LINEBOT作ってみた <a href="https://t.co/ZRaPJ40IPi">pic.twitter.com/ZRaPJ40IPi</a></p>&mdash; 小山浩晃 (@ghbcKTpFr5rvfE4) <a href="https://twitter.com/ghbcKTpFr5rvfE4/status/1663400281814761472?ref_src=twsrc%5Etfw">May 30, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


以下、返答のテキストを貼っておきます。

:::note info
牛肉の場合、レアからウェルダンまで好みが分かれますが、2cm程度の厚さであれば、レアからミディアムレアがおすすめです。

適した温度は、レアであれば50℃〜55℃、ミディアムレアであれば55℃〜60℃です。時間は、厚さによって異なりますが、2cm程度の場合は1時間半〜2時間程度が目安です。

おすすめの付け合わせは、ローストポテトやグリル野菜などが合います。味付けは、塩・胡椒・オリーブオイルでシンプルに調理するのがおすすめです。お酒は、赤ワインが合います。

牛肉の低温調理の代表的な画像を添付します。（エラー）
:::


## どうせなら美味しそうな画像も一緒に送りたい

今回の場合であればこんな感じの美味しそうなステーキの画像も一緒に送られて来て欲しい。

![asparagus-2169305_1280.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3292587/22d18bf6-d144-07a3-9153-73c126ef174f.jpeg)

コード内に
**「その肉を使った代表的な低温調理の画像を見つけて送ってください」**
と指示を入れているのですが、権利の関係やリンク切れで開けない画像ばかりが送られてきてしまいます。
（5回に1回ぐらいは開ける画像が届く感じです）

ここは画像生成AIを活用して、今後実装していきたい部分です。

## 低温調理に特化したつもりだったけど

オススメの付け合わせでローストポテトを提案してくれたので、追加で以下の質問をしてみました。

![potate.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3292587/1842b147-3016-8970-d525-5b88a23d05a7.jpeg)


返答がこちら

![answer.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3292587/6c1a3fe9-4b33-5af1-5445-d68bbcee42b2.jpeg)

万能やん！


## 軽く想像を超えて来るChatGPT

僕が求めている以上の結果をすぐに返してくれるChatGPT
もはやこちらで〇〇に特化、とか制限する必要もないのかもしれません。

一方で、ものすごく便利なものには間違いありませんが、質問の仕方によって得られる回答が結構変わってくるなという事も実感しました。

これからも色々試しながら、いいところをどんどん取り入れていきたいですね！