Dify でクーポン情報が届くワークフローをつくってみよう

<img width="100%" src="https://storage.googleapis.com/zenn-user-upload/b4058e438346-20250320.png">

Dify には[ワークフロー](https://docs.dify.ai/ja-jp/guides/workflow)という仕組みがあり、作業の自動化に特化したアプリケーションです。
ボタンを押したり、定期的に実行したい場合に利用します。

## 1. LINE にクーポンを通知してくれる Bot 

Dify のワークフローを使って、次の仕組みをつくります。  

:::note info
1. ビックカメラのWebサイトにアクセスしてクーポン情報を取得し、
2. クーポン情報を整理して、
3. LINE に通知を行う
:::

<img width="50%" src="https://storage.googleapis.com/zenn-user-upload/75378bb73e06-20250321.png">

完成系のフローはこちらです。

<img width="100%" src="https://storage.googleapis.com/zenn-user-upload/1a38f1ceb27d-20250320.png">

-----    

## 2. 実装

### 2-1. 準備①
**Dify のワークフローの準備**
- Dify でアカウントを作成しワークフローを準備します 
※アカウント作成方法は割愛します

<img width="60%" src="https://i.gyazo.com/efe618b5bd0ab6d278c74c4046ec1606.png">
  
### 2-2. 準備②
**LINE 公式アカウントの準備**  

<img width="100%" src="https://storage.googleapis.com/zenn-user-upload/64f1eecc6ebd-20250320.png">

LINE Developers から以下を用意します。
※手順は割愛します
- 公式ラインのアカウント 
- ユーザーID
- チャネルアクセストークン

準備ができたら、Dify に戻りノードをつないでいきます。

<img width="60%" src="https://storage.googleapis.com/zenn-user-upload/165a9df6c282-20250320.png">

<details><summary> 環境変数の設定 </summary>

`[ENV]` ブロックから以下の2つの環境変数を設定してください。

:::note
- ユーザーID
    - タイプ：Secret
    - 名前：to
    - 値：2-2で取得したLINEのユーザーIDの値

- アクセストークン
    - タイプ：Secret
    - 名前：line_channel_access_token
    - 値：LINEのチャネルアクセストークンの値
:::
  
<img width="60%" src="https://storage.googleapis.com/zenn-user-upload/069a8e5521f6-20250320.png">

</details>

### 2-3. Scrape ノード
[Firecrawl](https://www.firecrawl.dev/) の登録をし、API key を取得しておきます。
※取得方法は割愛します

<img width="60%" src="https://storage.googleapis.com/zenn-user-upload/3b2f89702ec1-20250320.png">


Dify のマーケットプレイスから `Firecrawl` をインストールし認証します。
<img width="60%" src="https://storage.googleapis.com/zenn-user-upload/657cc6e55ea1-20250320.png">

Dify に戻り、FireCrawlの認証画面に `API key` を入れてください。URLは入れなくてOKです。

<img width="60%" src="https://storage.googleapis.com/zenn-user-upload/14cfafe46305-20250320.png">

`SCRAPEノード`が選択できるようになるので追加します。

<img width="60%" src="https://storage.googleapis.com/zenn-user-upload/56d2efad682b-20250320.png">


<details><summary> Scrapeノードの設定 </summary>

- URL to scrape: データを取得したいサイトのURL 

</details>

::: note warn
スクレイピングは Web サイトの利用規約を確認してから実施しましょう
:::
  
### 2-4. LLM ノードを追加

スクレイピング結果から必要な文字を抽出するために、生成AIを使います！
これを簡単に実装できるのは Dify の魅力です。

`Scrapeノード`、`LLMノード`と繋いでください。

<img width="60%" src="https://storage.googleapis.com/zenn-user-upload/c7286bd79743-20250320.png">

<details><summary> LLM ノードの設定 </summary>

- モデル：`GPT-4o-mini`
- SYSTEM：
  ```
    ビックカメラのクーポン情報の一覧のテキストが送られてきます。
    - タイトル
    - 画像URL
    - 商品リンクURL
    - 有効期限
    を抽出してリストアップしてください。
    
    ## 出力
    - 出力は最初の2件のクーポンだけ出力してください。
    - マークダウン形式にせず、プレーンなテキストで出力してください。
  ```
- USER：`SCRAPE` > `{x}text`
> `USER`は`メッセージの追加`で編集できます

</details>

なお、USER に入れるのは変数で、変数の選択は`/`を押すことで候補が出現します。

### 

### 2-5. コードノードと HTTP リクエストを追加

同様に LLM ノードの後ろに`コードノード`と `HTTP リクエストノード`を追加します。
<img width="60%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/6ff655df-b49d-4844-a65a-d04a3b66b17a.png">

<details><summary> コードノードの設定の設定 </summary>

生成AIがつくったテキストを受け取り、LINE で送れるオブジェクトに整形します。
この部分も LLM ノードのプロンプトで整形してみるのも良いかもしれません。

- 入力変数を追加
    - 変数名：`sendCoupon`
    - 変数を設定：`LLM` > `{x}text`
- JavaScript 
  
  ```Javascript
    function main({to, sendCoupon}) {
        const messageObj = {
            "to": to,
            "messages":[
                {
                    "type":"text",
                    "text": sendCoupon
                }
            ]
        };
    
        return {result: JSON.stringify(messageObj)};
    }

  ```

LLM で生成した内容を `sendCoupon` という名前の変数にして、LINE で送るメッセージとして扱っています。

</details>

<details><summary> HTTP リクエストの設定の設定の設定 </summary>

- API
    - POST
    - `https://api.line.me/v2/bot/message/push`
- ヘッダー
    - キー：`Authorization`、値：Bearer `ENV` > `line_channel_access_token`
    - キー：`Content-Type`、値：`application/json`
- ボディ
    - JSON、{x}result

<img width="60%" src="https://storage.googleapis.com/zenn-user-upload/cf81a89e68bb-20250320.png">

</details>

### 2-6. 全てのノードをつなげる

最後にこれまでのノードをつなげていきます。`LLM ノード`の後ろに`コードノード`、`HTTPリクエスト`と続くようにします。

<img width="60%" src="https://storage.googleapis.com/zenn-user-upload/6994ff12272c-20250320.png">

最後に、`終了`のノードをつけましょう。

### 2-7. 実行

最後に右上の実行を押すと処理がスタートし、 LINE に情報が通知されます。

<img width="60%" src="https://storage.googleapis.com/zenn-user-upload/2224f5c57331-20250321.png">

成功すると通知が送られます。  

<img width="50%" src="https://storage.googleapis.com/zenn-user-upload/75378bb73e06-20250321.png">

-----   

## 3. 自動投稿


API アクセスから API 経由でこのワークフローを実行させることができます。
API はこちらから取得できます。

<img width="60%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/b6ebe3c8-4695-4ae9-aab9-8b73524f40f4.png">

**Dify スケジュールアシスタント**というツールを使うことができます。

https://docs.dify.ai/ja-jp/learn-more/use-cases/dify-schedule

具体的には GitHub Actions 利用します。

https://github.com/leochen-g/dify-schedule

API の使い方については詳しく記載しませんが、このようにAPI 経由で定期実行するため、GAS のようなサービスでも実装可能です。

## 5. まとめ

これができれば、LINE 以外に Slack や Discord などに送ることも簡単です。