Difyに待望の「Webhookトリガー」が登場!外部サービスからの連携がより簡単に

はじめに
対象とする読者
本記事は、ノーコードAIアプリ開発ツールで人気のある Dify を構築・運用している方で、特に以下のような方を対象としています。
- Difyを利用して業務効率化や自動化を図っている開発者・非エンジニア
- 外部サービス(SaaS等)からDifyのワークフローを直接呼び出したいと考えている方
- 過去にAPIのリクエスト構造の制約(固定Payload)でDify連携を諦めた経験のある方
また本記事の前提知識として、Webhookに関する基本的な知識、何かしらのワークフローツールの基礎知識があることを想定しています。
記事のゴール
本記事では、以下の点を達成することを目指します。
- 新機能「Webhookトリガー」の基本的な使い方とメリットを理解する。
- 外部サービスから送られる複雑な(ネストされた)JSONデータを、Dify内で適切に処理する具体的な手法(2パターン)を習得する。
DifyにWebhookトリガーが登場
先日はDifyバージョン1.10.1の構築時に遭遇した問題について記事を書きましたが、その後久しぶりにワークフローを作成しようとしたところ、トリガーとしてWebhookが追加されているのに気づきました。(どうも、1ヶ月以上前の v1.10.0-rc1 でプレリリースされていたようです)
以前であれば、外部からDifyのワークフローを呼び出す際は、対象のワークフローでAPIキーを生成し、それを利用してPOSTリクエストを送信するのが一般的でした。しかしこの方式の場合、リクエスト内容は下記のようにDify側で規定した構造にする必要があります。
curl -X POST 'https://api.dify.ai/v1/workflows/run' \
--header 'Authorization: Bearer {api_key}' \
--header 'Content-Type: application/json' \
--data-raw '{
"inputs": {
"query": "Hello!"
},
"response_mode": "streaming",
"user": "abc-123"
}'
そのため、他サービスからDifyのワークフローを呼び出そうとしても、そのサービスが送信できるリクエスト内容が固定されていると、Dify側で規定した構造に合わせることができず、呼び出すことができませんでした。
しかし、このWebhookトリガーの登場によって、その状況が変わったようです。
今回の記事では、実際にこのWebhookトリガーを使って、他サービスからWebhook送信した際にどのように、ワークフローを実行するかを検証していきたいと思います。
検証
使用するPayload
今回の検証では、Zendeskにユーザーを追加した際に送信されるPayloadをサンプルとして利用したいと思います。
内容は次の通りです。
{
"account_id": 12514403,
"detail": {
"created_at": "2022-07-04T05:27:58Z",
"default_group_id": "0",
"email": "test-example@creationline.com",
"external_id": "",
"id": "6596848315901",
"organization_id": "0",
"role": "end-user",
"updated_at": "2022-07-04T05:33:18Z"
},
"event": {},
"id": "6b9bbadf-5725-4e92-bebe-7b71011bf5f1",
"subject": "zen:user:6596848315901",
"time": "2022-07-04T05:33:18Z",
"type": "zen:event-type:user.created",
"zendesk_event_version": "2022-11-06"
}
Webhookトリガーの設定
新規のワークフローを作成し、まず先頭にWebhookトリガーを追加します。

Webhookトリガーを作成すると、エンドポイントとなるURLが自動生成されます。

Webhookトリガーが受け取ったPayloadは、デフォルトだと出力変数の payload._webhook_raw (Object型) にそのまま格納されます。
また、それ以外にも、REQUEST BODY PARAMETERS 部分に以下のようにJSONキー名を設定することで、後続ステップで変数として参照することもできます。

| 変数名 | タイプ |
|---|---|
| account_id | Number |
| detail | Object |
| event | Object |
| id | String |
| subject | String |
| time | String |
| type | String |
| zendesk_event_version | String |
ただしここで1つ注意点があり、Dify の Webhookトリガーの制約として、Payloadがネスト構造になっている場合は第1階層しか取り出すことができません。
ですので、第2階層以降の階層、例えば detail.email の値を参照したい場合は少し工夫が必要になってきます。
方法1. テンプレートノードを利用する
本来テンプレートノードは、構造化されたテンプレートを作成するためのものですが、そこで使用されている Jinja2 の機能を利用して、JSON内のデータを取り出して行きます。
Webhookトリガーの後続にテンプレートノードを追加し、まず入力変数 arg1 に対してWebhookトリガーの出力変数 detail を割り当てます。

arg1 に detail が割り当てられるため、あとはコード内で {{ arg1.email }} と設定することで、結果的に detail.email の値が、テンプレートノードの出力変数 output に格納されます。

ちなみにテンプレートノードでは、出力変数の payload._webhook_raw をそのまま利用することもできます。
先ほどと同様に、入力変数 arg1 に対してWebhookトリガーの出力変数 _webhook_raw を割り当て、コード内で {{ arg1.body.detail.email }} と設定することで、detail.email の値が、テンプレートノードの出力変数 output に格納されます。

この方法だと、Webhookトリガーで REQUEST BODY PARAMETERS 部分にわざわざ変数を設定する必要が無いので、慣れてきたらこちらの方が使いやすいかもしれません。
方法2. コード実行ノードを利用する
せっかくなので完全にノーコードで行きたいところですが、ローコードでも良いのであれば、コード実行ノードを利用する手もあります。
テンプレートノードと同様に、入力変数 arg1 に対してWebhookトリガーの出力変数 _webhook_raw を割り当て、コード内を次のように設定します。(Python3で2つの変数を返す例)

def main(arg1: dict) -> dict:
detail_email = arg1["body"]["detail"]["email"]
detail_role = arg1["body"]["detail"]["role"]
return {
"detail_email": detail_email,
"detail_role" : detail_role
}
さらにコード内の return 部分に記述した detail_email (String型) と detail_role (String型) を出力変数として設定することで、これらの値が後続ステップで参照できるようになります。
少しだけコードを書かなくてはいけないので抵抗がある方も居るかもしれませんが、JSON内のデータを取り出すくらいであれば、このように簡単なコードで済みます。
また、テンプレートノードの場合は、取り出したいデータの数だけノードを作成する必要がありますが、コード実行ノードの場合は1つのブロックで済むというメリットもありますので、コードに抵抗が無い人はこちらの方が実用性が高いでしょう。
LLMなどの後続ステップで利用する
これまでの手順でPayloadの内容を変数化できているので、あとは後続ステップで使うだけです。
例えば、後続に以下のようなLLMノードを定義しておきます。

設定が完了したら、Zendeskでユーザーが追加された場合に、DifyのWebhookトリガーにWebhookが送信されるよう設定します。


そしてZendeskに test-example@creationline.com というメールアドレスのユーザーを追加してみると、無事Difyのワークフローが起動し、以下のような結果が返ってきました。

チャットフローでは利用できない点に注意
ここまでWebhookトリガーの使い方を見てきましたが、公式ドキュメントにも記載のある通り、Webhookトリガーはワークフローでのみ利用できるもので、チャットフローでは利用できませんので、その点は注意してください。
チャットフローはあくまで対話型シナリオを前提とした機能です。
他サービスからの入力に対して処理結果を返すのがワークフローの役割なので、このような仕様になっていると考えられます。
まとめ
学んだことの整理
今回の記事を通じて以下の点を学びました。
- 外部連携のハードルが解消: Webhookトリガーの登場により、Dify側のAPI仕様に合わせる必要がなくなり、送信側(他サービス)のフォーマットのままワークフローを起動できるようになった。
- ネスト構造への対応策: JSONの第1階層のデータは簡単に変数化できるが、第2階層以降を扱うには、Jinja2を利用する「テンプレートノード」か、複数データを一括処理できる「コード実行ノード」の活用が有効である。
- 実用的なワークフロー構築: 各種SaaSイベントをトリガーに、LLMを組み合わせた高度な自動処理が容易に実装できることを確認した。
これまでは「Difyをどう呼び出すか」という橋渡し部分に工夫が必要でしたが、Webhookトリガーの登場によってその壁は取り払われました。本記事で紹介したJSON解析の手法を組み合わせれば、ほぼ全てのSaaSとの連携が可能になるでしょう。
ぜひ、あなたの業務ワークフローにもこの柔軟な外部連携を取り入れてみてください。
次回以降は、Webhookトリガーが利用できない、チャットフローへの連携について探っていきたいと思います。
