LINEで「商品の売上個数」を聞ける！ノーコードで作る売上応答Bot【Make×Dify】

## あと何パック作ればいいの？
みなさんこんにちは。
北海道の某小売店で朝から働くおじさん（主任）です。

私の仕事内容の中で、**商品を製造する**業務が頻繁に発生します。例えば、お弁当だったり、お肉やお魚のパックだったり……そんな時、
「これあと何パック作ろうかなー？」
なんて、よく考えるし、部下からもよく聞かれます。

そんな時、よく昨年や先週の売上データを参考にして計画するのですが、膨大なデータ量ですし、毎回毎回そんなの覚えていられません。~~おじさんなんで。~~

事務所までデータ確認しに行けばいいのですが、移動するのは面倒ですよね。なんなら現場が1階で、事務所が3階なんてこともあるのです。

だったら、移動しなくてもすぐ確認できるようなアプリを作ってやろうというわけですよ！そこで
「**LINEでJANコードを打ち込むと、その商品の売上実績を返してくれるBot**」
を作りたいと思います。

JANコードとは、商品の識別に使用される13桁または8桁の数字で、商品ラベルにバーコードとして表示されています。下記画像のような感じですね。

<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077785/6673cc83-dfd2-4847-8f6f-a7bdeea9bc6d.png">

カメラを使って撮影した画像からJANコード抽出できるようにすれば楽になりそう。そんな機能も入れてみたいので、頑張っていこー！

## 完成品

![ezgif.com-speed.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077785/cf5151fd-80fd-41db-8f86-82ccc952f2ed.gif)


※商品ラベルに関しては一部記載を隠しています。

## 使用ツール
[LINE Messaging API](https://developers.line.biz/ja/services/messaging-api/)
[Make](https://www.make.com/en)
[Dify](https://dify.ai/jp)
[ChatGPT](https://chatgpt.com/)
Googleスプレッドシート（下図が今回使用したものになります）

![スプレッドシート.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077785/366b45ae-1315-456f-bf8d-cee3bdab38ea.png)


今回はノーコードツールを活用して、アプリを作っていきます。主に使ったツールはMakeと、Difyです。使った理由は、
* Make：LINE連携が非常に楽で、LINE Messaging APIと組み合わせると簡単にLINEBotが作成できる。また、Googleスプレッドシートとの連携も簡単に可能
* Dify：複雑なコーディングなしでAIアプリを作成でき、AIを使った画像認識が可能。また、**作成したワークフローをAPIとして外部アプリと連携することができる**


流れとしては
1. MakeでLINE連携し、画像を貼り付けする
2. MakeとDifyを連携させ、Dify側でAI（ChatGPT）を用いて画像認識を行いJANコードを抽出
3. 抽出したJANコードに該当する売上データをGoogleスプレッドシートから取り出して、LINEで返す

のようになります。

## 作成開始

### Difyワークフロー作成
![dify全体図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077785/62cb8a15-e2bd-48eb-ae51-dec40545624c.png)
↑Difyワークフロー全体図

Difyワークフローから先に作成します。Difyにログインし、最初から作成を押し、「チャットフロー」を選択します。そして、上記のようなフローを作成していきます。

#### 下準備

まず下準備として、Makeと連携するためにAPIキーを取得しておきましょう。上記全体図の左側に**APIアクセス**というリンクがあるので、そちらをクリックすると、

<img width="450" src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077785/ece7d473-934f-485e-a3d7-b8c109dd347a.png">

このような画面になり、右上にAPIキーと書いているところをクリックするとAPIキーを取得できます。あとでMake側で使用するので覚えておきましょう。

次に、今のままでは画像がアップロードできる設定になっていないので、そちらを設定します。先ほどの全体図の右上赤丸の箇所に**機能**と書いてあるのでそこをクリック。すると

<img width="250" src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077785/f6c92776-05b0-439d-baed-62d0ba059dc7.png">

このような画面が出てくるので、ファイルアップロードをONにしてください。これで下準備は完了です。

#### ワークフロー作成
開始ノードは最初から作られており、特に触るところはありません。それ以外のノードを左から順につなげていきます。

パラメータ抽出ノードは、画像から特定のテキストを抽出する役割になります。ここではJANコードを抽出するように設定します。
AIモデルは**gpt-4o-mini**に設定しています。ここは自分の使用用途によって変更可能です。

<img width="250" src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077785/06594184-1064-434b-b9b8-063435c37aa9.png">


このように**入力変数**、**ビジョン変数**、**パラメーターを抽出**（上図右側の+をクリックし、変数と説明を記入します。入力内容は任意ですが、わかりやすい名前にしておきましょう。）、**指示**の欄を上図のように設定します。指示はプロンプトと呼び、AIに具体的な指示を与えることが出来ます。この指示がないと、JANコードを抽出してくれません。ちなみに、「商品名を読み取ってください」とすると、ラベルに書いてある商品名を抽出してくれます。

その隣のLLMノードは、読み取ったJANコードの桁数を減らすためのノードです。
![ラベル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077785/24a48a7e-7889-4ad9-a8d5-a2a1af7c225e.png)
このJANコードは0487276 401876と7桁と6桁の数字に分けられます。実は商品を判別しているのは左側7桁だけで、右側6桁は判別には使用していません。この仕様から、左側7桁のみを抽出する処理を行う必要があります。

<img width="250" src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077785/fa4be584-64d7-4d94-b980-8d25c6cc229c.png">

LLMノード詳細は上図のようになります。コンテキストの欄には、先ほどのパラメータ抽出ノードで設定した変数を指定し、SYSTEMの欄にはAIに指示を出すプロンプトを記載します。「数字だけを返してください」の記載がない場合、

**1111111が左7桁です。**

のように、数字以外の言葉を返してきます。情報としてはJANコードの数字以外は必要ないので、このようなプロンプトになっています。

最後に回答ノードを作り、LLMノードで抽出されるテキスト変数（LLM/{x}text）を指定すれば、Difyワークフローは完成です。画面右上に**公開する**とあるので、アプリを公開します。これでDifyの作成は終了になります。

### Makeシナリオの作成

![make全体図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077785/810fd00d-c88b-4db1-978e-b8bf0a08caf2.png)
Makeシナリオ全体図

Difyの次にMakeシナリオを作成します。主にLINEを活用して画像をDifyに送り、返ってきたJANコードに対応する商品の売上データを返す機能になっています。

①では、まずLINEからメッセージを受け取り、それが画像だった場合は上の処理へ、画像以外なら下へ処理が進みます。下は画像ではなく、直接JANコードを打った場合の処理になります。条件分岐の図は以下の通りです。
<img width="350" src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077785/1d9f8216-0259-462e-a3b5-67c1fdaa0c22.png">
上図のように設定すると、LINEのメッセージが画像かそれ以外かで分岐ができます。

②でHTTPモジュールが2つ繋がっています。両方ともMake a requestモジュールです。左が**画像をDifyに送る処理**、右が**Difyのアプリにリクエストを送る処理**となります。

画像送るHTTPモジュールの詳細は以下のようになります。モジュール詳細が縦長なので、分割して表示します。

![図を送るHTTP1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077785/9c11fcab-f8ff-4ac8-a02f-38af2c48e8bf.png)


Difyのアプリにリクエストを送るHTTPモジュールの詳細は以下のようになります。こちらも縦長なので分割しています。

![テキストを送るHTTP.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077785/7e904090-fa1f-43ae-8d06-23edcc17365b.png)

Request contentにはリクエストを送るJSONを入力します。
```
{
"inputs": {},
"query": "JANコードを読み取ってください。",
"response_mode": "blocking",
"conversation_id": "",
"user": "abc-123",
"files": [
{"type": "image",
"transfer_method": "local_file",
"upload_file_id":"{変数data.id}"
}
]
}

```
`data.id`は変数を指定します。実際にJSONを入力しようとすると、下図の左側ような変数の候補が出てきます。
赤枠で囲っている部分をクリックすると`data.id`を指定できます。これは先ほどのHTTPモジュールでDifyにアップロードした画像を指しています。

<img width="550" src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077785/9102caf9-467d-411c-b39e-c56aa9ca830c.png">


::: note warn
変数が出てこない場合、一度Makeでアプリを実行（Run once）して何らかの画像を送ってみてください。エラーは出ますが、変数が表示されるようになります。
:::

これでリクエストをDifyに送ることができたので、`data.answer`という変数の形で画像認識した結果を取得することができます。

③で、Difyから返ってきたJANコードをGoogleスプレッドシート内を検索し、該当した売上データをLINEで返します。Routerモジュールによる条件分岐は、返ってきたJANコードがGoogleスプレッドシート内にないケースを考慮しています。画質等の問題で画像認識が失敗する可能性があるためです。
Google Sheets Search rowsモジュールの詳細は以下のようになります。

<img width="250" src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077785/6dff1c49-c182-4c81-ad03-5d65389e7fb2.png">

Filterが該当JANコードの行を検索する処理で、A行はGoogleスプレッドシートのJANコードが記載されている行を示しています。`data.answer`（返ってきたJANコード）を含む行を取得します。

<img width="250" src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077785/8b1c7539-649b-487a-bbca-8cd8a04f707b.png">

最後にLINE Send a Reply Messageモジュールで返答させて、処理終了になります。

<img width="250" src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077785/6c74605e-f009-4db0-a2c1-227dba42bec3.png">

品名隠してますが、Googleスプレッドシートの商品E（JANコード2751987）を取得できています。


## まとめ
今回は微妙な移動時間を削減したく、画像から売り上げを返すLINEBotを作ってみました。実際使ってみると気軽に数字を確認できるなーと感じました。移動時間削減というのもありましたが、数字を確認する頻度が増え、その結果製造数の精度が上がり、無駄な製造をしてしまう時間の削減につながりました。そして削減した作業時間は、しっかり事務作業に費やしております。~~早く帰れるとは言ってない。~~

今回ChatGPTを使って画像認識してみましたが、結構精度高いんですね・・・驚きました。画質にもよるとは思いますが、最近のスマートフォンはカメラの画質もいいので、かなり生かせる場面が多いと思いました。ほんとに万能なのね。

しかし、今回のアプリをChatGPTに質問しながらmakeシナリオやDifyのワークフローを作っていたのですが、なかなか正しい情報が返ってこず、色々な記事からやり方を模索したり、有識者に相談してなんとか作りました。AIは確かに万能だとは思いますが、ツールとしての**使い方**が大事だなーと思いました。

今後もAI活用していろいろなデジタルツールを作って、業務改善に取り組んでいきたいと思います。

ここまで見ていただき、ありがとうございました。