add docs for trigger (#504)
* draft * draft * draft * refine dev docs * almost * update * remove sys.file and sys.query; add sys.timestamp * update the end node to output * modify the introduction section of variable * fix typo * adjust image size * remove unnecessary list * feedback fix * remove example * feedback fix & add en/ja dev docs * correct description * fix typos * replace UI text * refinements & add zh-ja translation * feedback fixes * fix punctuation * refine heading-reference * typo * adjust casing & remove sys.timestamp from chatflow * Docs tools: 2 succeeded, some failed Rename operation failed: - Lang 'zh': File 'dify-docs/plugin-dev-zh/0211-getting-started-dify-tool.mdx' - Renaming error: Unexpected error: 'str' object has no attribute 'get' - Lang 'zh': File 'dify-docs/plugin-dev-zh/0222-datasource-plugin.mdx' - Skipped (non-compliant): Missing/empty critical frontmatter fields for renaming: dimensions.type.primary, dimensions.type.detail, dimensions.level, standard_title, language (expected for metadata, though not used in filename suffix anymore). - Lang 'zh': File 'dify-docs/plugin-dev-zh/0222-tool-oauth.mdx' - Skipped (non-compliant): Missing/empty critical frontmatter fields for renaming: dimensions.type.primary, dimensions.type.detail, dimensions.level, standard_title, language (expected for metadata, though not used in filename suffix anymore). - Lang 'zh': File 'dify-docs/plugin-dev-zh/0222-trigger-plugin.mdx' - Skipped (non-compliant): Missing/empty critical frontmatter fields for renaming: dimensions.type.primary, dimensions.type.detail, dimensions.level, standard_title, language (expected for metadata, though not used in filename suffix anymore). - Lang 'en': File 'dify-docs/plugin-dev-en/0211-getting-started-dify-tool.mdx' - Renaming error: Unexpected error: 'str' object has no attribute 'get' - Lang 'en': File 'dify-docs/plugin-dev-en/0222-datasource-plugin.mdx' - Skipped (non-compliant): Missing/empty critical frontmatter fields for renaming: dimensions.type.primary, dimensions.type.detail, dimensions.level, standard_title, language (expected for metadata, though not used in filename suffix anymore). - Lang 'en': File 'dify-docs/plugin-dev-en/0222-tool-oauth.mdx' - Skipped (non-compliant): Missing/empty critical frontmatter fields for renaming: dimensions.type.primary, dimensions.type.detail, dimensions.level, standard_title, language (expected for metadata, though not used in filename suffix anymore). - Lang 'en': File 'dify-docs/plugin-dev-en/0222-trigger-plugin.mdx' - Skipped (non-compliant): Missing/empty critical frontmatter fields for renaming: dimensions.type.primary, dimensions.type.detail, dimensions.level, standard_title, language (expected for metadata, though not used in filename suffix anymore). - Lang 'ja': File 'dify-docs/plugin-dev-ja/0211-getting-started-dify-tool.mdx' - Renaming error: Unexpected error: 'str' object has no attribute 'get' - Lang 'ja': File 'dify-docs/plugin-dev-ja/0222-datasource-plugin.mdx' - Skipped (non-compliant): Missing/empty critical frontmatter fields for renaming: dimensions.type.primary, dimensions.type.detail, dimensions.level, standard_title, language (expected for metadata, though not used in filename suffix anymore). - Lang 'ja': File 'dify-docs/plugin-dev-ja/0222-trigger-plugin.mdx' - Skipped (non-compliant): Missing/empty critical frontmatter fields for renaming: dimensions.type.primary, dimensions.type.detail, dimensions.level, standard_title, language (expected for metadata, though not used in filename suffix anymore). --------- Co-authored-by: Riskey <riskey47@dify.ai> Co-authored-by: alterxyz <88554920+alterxyz@users.noreply.github.com>
64
docs.json
@@ -90,9 +90,24 @@
|
||||
"en/guides/workflow/key-concepts",
|
||||
"en/guides/workflow/variables",
|
||||
{
|
||||
"group": "Node Description",
|
||||
"group": "Nodes",
|
||||
"pages": [
|
||||
"en/guides/workflow/node/start",
|
||||
{
|
||||
"group": "Start",
|
||||
"pages": [
|
||||
"en/guides/workflow/node/start",
|
||||
"en/guides/workflow/node/user-input",
|
||||
{
|
||||
"group": "Trigger",
|
||||
"pages": [
|
||||
"en/guides/workflow/node/trigger",
|
||||
"en/guides/workflow/node/schedule-trigger",
|
||||
"en/guides/workflow/node/plugin-trigger",
|
||||
"en/guides/workflow/node/webhook-trigger"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"en/guides/workflow/node/end",
|
||||
"en/guides/workflow/node/answer",
|
||||
"en/guides/workflow/node/llm",
|
||||
@@ -514,7 +529,8 @@
|
||||
"plugin-dev-en/0222-debugging-logs",
|
||||
"plugin-dev-en/0222-tool-plugin",
|
||||
"plugin-dev-en/0222-tool-oauth",
|
||||
"plugin-dev-en/0222-datasource-plugin"
|
||||
"plugin-dev-en/0222-datasource-plugin",
|
||||
"plugin-dev-en/0222-trigger-plugin"
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -730,9 +746,24 @@
|
||||
"zh-hans/guides/workflow/key-concept",
|
||||
"zh-hans/guides/workflow/variables",
|
||||
{
|
||||
"group": "节点说明",
|
||||
"group": "节点",
|
||||
"pages": [
|
||||
"zh-hans/guides/workflow/node/start",
|
||||
{
|
||||
"group": "开始",
|
||||
"pages": [
|
||||
"zh-hans/guides/workflow/node/start",
|
||||
"zh-hans/guides/workflow/node/user-input",
|
||||
{
|
||||
"group": "触发器",
|
||||
"pages": [
|
||||
"zh-hans/guides/workflow/node/trigger",
|
||||
"zh-hans/guides/workflow/node/schedule-trigger",
|
||||
"zh-hans/guides/workflow/node/plugin-trigger",
|
||||
"zh-hans/guides/workflow/node/webhook-trigger"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"zh-hans/guides/workflow/node/llm",
|
||||
"zh-hans/guides/workflow/node/knowledge-retrieval",
|
||||
"zh-hans/guides/workflow/node/question-classifier",
|
||||
@@ -1202,7 +1233,8 @@
|
||||
"plugin-dev-zh/0222-debugging-logs",
|
||||
"plugin-dev-zh/0222-tool-plugin",
|
||||
"plugin-dev-zh/0222-tool-oauth",
|
||||
"plugin-dev-zh/0222-datasource-plugin"
|
||||
"plugin-dev-zh/0222-datasource-plugin",
|
||||
"plugin-dev-zh/0222-trigger-plugin"
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1419,7 +1451,22 @@
|
||||
{
|
||||
"group": "ノードの説明",
|
||||
"pages": [
|
||||
"ja-jp/guides/workflow/node/start",
|
||||
{
|
||||
"group": "開始",
|
||||
"pages": [
|
||||
"ja-jp/guides/workflow/node/start",
|
||||
"ja-jp/guides/workflow/node/user-input",
|
||||
{
|
||||
"group": "トリガー",
|
||||
"pages": [
|
||||
"ja-jp/guides/workflow/node/trigger",
|
||||
"ja-jp/guides/workflow/node/schedule-trigger",
|
||||
"ja-jp/guides/workflow/node/plugin-trigger",
|
||||
"ja-jp/guides/workflow/node/webhook-trigger"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"ja-jp/guides/workflow/node/end",
|
||||
"ja-jp/guides/workflow/node/answer",
|
||||
"ja-jp/guides/workflow/node/llm",
|
||||
@@ -1857,7 +1904,8 @@
|
||||
"plugin-dev-ja/0222-creating-new-model-provider",
|
||||
"plugin-dev-ja/0222-debugging-logs",
|
||||
"plugin-dev-ja/0222-tool-plugin",
|
||||
"plugin-dev-ja/0222-datasource-plugin"
|
||||
"plugin-dev-ja/0222-datasource-plugin",
|
||||
"plugin-dev-ja/0222-trigger-plugin"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,35 +1,20 @@
|
||||
---
|
||||
title: End
|
||||
title: Output
|
||||
---
|
||||
|
||||
|
||||
### 1 Definition
|
||||
|
||||
Define the final output content of a workflow. Every workflow needs at least one end node after complete execution to output the final result.
|
||||
|
||||
The end node is a termination point in the process; no further nodes can be added after it. In a workflow application, results are only output when the end node is reached. If there are conditional branches in the process, multiple end nodes need to be defined.
|
||||
|
||||
The end node must declare one or more output variables, which can reference any upstream node's output variables.
|
||||
## Introduction
|
||||
|
||||
<Info>
|
||||
End nodes are not supported within Chatflow.
|
||||
- The Output node was previously called End. Unlike before, it's now optional in a workflow and is required only when you want to explicitly return data to the end user.
|
||||
|
||||
- This node is available in workflow applications only. Chatflows use [Answer nodes](/en/guides/workflow/node/answer) instead to deliver responses during the conversation flow.
|
||||
</Info>
|
||||
|
||||
***
|
||||
In an Output node, you can define what your workflow returns to the end user, such as an LLM's response.
|
||||
|
||||
### 2 Scenarios
|
||||
At least one output variable must be specified in an Output node; otherwise, nothing will be returned.
|
||||
|
||||
In the following [long story generation workflow](/en/guides/workflow/node/iteration#example-2-long-article-iterative-generation-another-scheduling-method), the variable `Output` declared by the end node is the output of the upstream code node. This means the workflow will end after the Code node completes execution and will output the execution result of Code.
|
||||
|
||||

|
||||
|
||||
**Single Path Execution Example:**
|
||||
|
||||

|
||||
|
||||
**Multi-Path Execution Example:**
|
||||
|
||||

|
||||
When exposed as a backend service API, workflows without an Output node will not return any values to API callers.
|
||||
|
||||
{/*
|
||||
Contributing Section
|
||||
|
||||
191
en/guides/workflow/node/plugin-trigger.mdx
Normal file
@@ -0,0 +1,191 @@
|
||||
---
|
||||
title: Plugin Trigger
|
||||
---
|
||||
|
||||
## Introduction
|
||||
|
||||
<Info>
|
||||
Triggers are available for workflow applications only.
|
||||
</Info>
|
||||
|
||||
A plugin trigger automatically initiates your workflow when a specific event occurs in an external system. All you need to do is subscribe to these events through a trigger plugin and add the corresponding plugin trigger to your workflow.
|
||||
|
||||
For example, suppose you have installed a GitHub trigger plugin. It provides a list of GitHub events you can subscribe to, including `Pull Request`, `Push`, and `Issue`. If you subscribe to the `Pull Request` event and add the `Pull Request` plugin trigger to your workflow, it will automatically run whenever someone opens a pull request in the specified repository.
|
||||
|
||||
## Add and Configure a Plugin Trigger
|
||||
|
||||
1. On the workflow canvas, right-click and select **Add Node** > **Start**, then choose from the available plugin triggers or search for more in [Dify Marketplace](https://marketplace.dify.ai/?language=en-US&category=trigger).
|
||||
|
||||
<Tip>
|
||||
- If there's no suitable trigger plugin for your target external system, you can [request one from the community](https://github.com/langgenius/dify-plugins/issues/new?template=plugin_request.yaml), [develop one yourself](/plugin-dev-en/0222-trigger-plugin), or use a [webhook trigger](/en/guides/workflow/node/webhook-trigger) instead.
|
||||
|
||||
- A workflow can have multiple plugin triggers running in parallel. When the parallel branches contain identical consecutive nodes, you can add a [Variable Aggregator](/en/guides/workflow/node/variable-aggregator) node to merge the branches before the common section, without duplicating the same nodes across each branch.
|
||||
</Tip>
|
||||
|
||||
2. Select an existing subscription or [create a new one](#create-a-new-subscription).
|
||||
|
||||
<Tip>
|
||||
You can view how many workflows is using a specific subscription from the plugin's details panel under **Plugins**.
|
||||
</Tip>
|
||||
|
||||
3. Configure any other required settings.
|
||||
|
||||
<Info>
|
||||
The output variables of a plugin trigger are defined by its trigger plugin and cannot be modified.
|
||||
</Info>
|
||||
|
||||
## Create a New Subscription
|
||||
|
||||
<Note>
|
||||
A subscription cannot be modified once created. To make changes, delete the existing one and create a new subscription.
|
||||
</Note>
|
||||
|
||||
<Info>
|
||||
A trigger plugin supports creating up to 10 subscriptions per workspace.
|
||||
</Info>
|
||||
|
||||
Each subscription is built on a webhook. When you create a subscription, you're essentially setting up a webhook that listens for events from an external system.
|
||||
|
||||
<Accordion title="What is a webhook?">
|
||||
|
||||
A webhook allows one system to automatically send real-time data to another. When a certain event occurs, the source system packages the event details into an HTTP request and sends it to a designated URL provided by the destination system.
|
||||
|
||||
</Accordion>
|
||||
|
||||
Dify supports the following two methods for creating subscriptions (webhooks), but the options available in each plugin depend on how that plugin was designed.
|
||||
|
||||
- **Automatic Creation**: You select the events you want to subscribe to, and Dify automatically creates the corresponding webhook in the external system. This requires prior authorization via **OAuth** or **API keys** so Dify can handle the webhook setup on your behalf.
|
||||
|
||||
- **Manual Creation**: You create the webhook yourself using the webhook callback URL provided by Dify. No authorization is needed.
|
||||
|
||||
<img src="/images/create_subscription_method.png" alt="Ways to Create Subscriptions" width="563" />
|
||||
|
||||
<Tip>
|
||||
It's recommended to select all available events when creating a subscription.
|
||||
|
||||
A plugin trigger works only when its corresponding event is included in the linked subscription. Selecting all available events ensures that any plugin trigger you add to the workflow later can use the same subscription, without creating another one.
|
||||
</Tip>
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Create with OAuth (Automatic)">
|
||||
|
||||
On Dify Cloud, many popular trigger plugins are pre-configured with default OAuth clients so you can authorize Dify with a single click.
|
||||
|
||||
In self-hosted environments, only the custom OAuth client option is available, meaning that you need to create the OAuth application yourself in the external system.
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Default OAuth Client">
|
||||
|
||||
1. Select **Create with OAuth** > **Default** > **Save and Authorize**.
|
||||
|
||||
<Info>
|
||||
**Save** means the selected option is set as the default OAuth method for future subscriptions.
|
||||
|
||||
To switch methods later, click the **OAuth Client Settings** icon.
|
||||
|
||||
<img src="/images/oauth_client_settings_icon.png" alt="OAuth Client Settings Icon" width="300" />
|
||||
|
||||
</Info>
|
||||
|
||||
2. On the external system's authorization page that pops up, click **Next** to grant Dify access.
|
||||
|
||||
3. Specify the subscription name, select the events you want to subscribe to, and configure any other required settings.
|
||||
|
||||
<Tip>
|
||||
We recommend selecting all available events.
|
||||
</Tip>
|
||||
|
||||
4. Click **Create**.
|
||||
|
||||
</Tab>
|
||||
|
||||
<Tab title="Custom OAuth Client">
|
||||
|
||||
1. Select **Create with OAuth** > **Custom**.
|
||||
|
||||
2. In the external system, create an OAuth application using the callback URL provided by Dify.
|
||||
|
||||
3. Back in Dify, enter the client ID and client secret of the newly created OAuth application, then click **Save and Authorize**.
|
||||
|
||||
<Info>
|
||||
Once saved, the same client credentials can be reused for future subscriptions.
|
||||
</Info>
|
||||
|
||||
4. Specify the subscription name, select the events you want to subscribe to, and configure any other required settings.
|
||||
<Tip>
|
||||
We recommend selecting all available events.
|
||||
</Tip>
|
||||
|
||||
5. Click **Create**.
|
||||
|
||||
</Tab>
|
||||
|
||||
</Tabs>
|
||||
|
||||
<Info>
|
||||
The **Callback URL** displayed on the subscription configuration page is used internally by Dify to create the webhook in the external system on your behalf.
|
||||
|
||||
You don't need to take any action with this URL.
|
||||
</Info>
|
||||
</Tab>
|
||||
|
||||
<Tab title="Create with API Key (Automatic)">
|
||||
|
||||
1. Select **Create with API Key**.
|
||||
|
||||
2. Enter the required authentication information, then click **Verify**.
|
||||
|
||||
3. Specify the subscription name, select the events you want to subscribe to, and configure any other required settings.
|
||||
|
||||
<Tip>
|
||||
We recommend selecting all available events.
|
||||
</Tip>
|
||||
|
||||
4. Click **Create**.
|
||||
|
||||
<Info>
|
||||
The **Callback URL** displayed on the subscription configuration page is used internally by Dify when it creates the webhook in the external system on your behalf.
|
||||
|
||||
You don't need to take any action with this URL.
|
||||
</Info>
|
||||
|
||||
</Tab>
|
||||
|
||||
<Tab title="Paste URL to Create a New Subscription (Manual)">
|
||||
|
||||
1. Select **Paste URL to create a new subscription**.
|
||||
|
||||
2. Specify the subscription name and use the provided callback URL to manually create a webhook in the external system.
|
||||
|
||||
3. (Optional) Test the created webhook.
|
||||
|
||||
<Info>
|
||||
Most external systems automatically test a new webhook by sending a ping request to Dify upon creation.
|
||||
</Info>
|
||||
|
||||
1. Trigger a subscribed event so the external system sends an HTTP request to the callback URL.
|
||||
|
||||
2. Return to the **Manual Setup** page and check the **Request Logs** section at the bottom. If the webhook works properly, you'll see the received request and Dify's response.
|
||||
|
||||
<img src="/images/plugin_trigger_manual_setup_request_logs.png" alt="Request Logs" width="563" />
|
||||
|
||||
4. Click **Create**.
|
||||
|
||||
</Tab>
|
||||
|
||||
</Tabs>
|
||||
|
||||
## Test a Plugin Trigger
|
||||
|
||||
To test an unpublished plugin trigger, you must first click **Run this step** or test-run the entire workflow. This puts the trigger into a listening state so that it can monitor external events. Otherwise, the trigger will not capture subscribed events even when they occur.
|
||||
|
||||
{/*
|
||||
Contributing Section
|
||||
DO NOT edit this section!
|
||||
It will be automatically generated by the script.
|
||||
*/}
|
||||
|
||||
---
|
||||
|
||||
[Edit this page](https://github.com/langgenius/dify-docs/edit/main/en/guides/workflow/node/plugin-trigger.mdx) | [Report an issue](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)
|
||||
|
||||
114
en/guides/workflow/node/schedule-trigger.mdx
Normal file
@@ -0,0 +1,114 @@
|
||||
---
|
||||
title: Schedule Trigger
|
||||
---
|
||||
|
||||
## Introduction
|
||||
|
||||
<Info>
|
||||
Triggers are available for workflow applications only.
|
||||
</Info>
|
||||
|
||||
Schedule triggers enable your workflow to run at specified times or intervals. They are ideal for recurring tasks like generating daily reports or sending scheduled notifications.
|
||||
|
||||
## Add a Schedule Trigger
|
||||
|
||||
On the workflow canvas, right-click and select **Add Node** > **Start** > **Schedule Trigger**.
|
||||
|
||||
<Tip>
|
||||
- A workflow can have multiple schedule triggers running in parallel. When the parallel branches contain identical consecutive nodes, you can add a [Variable Aggregator](/en/guides/workflow/node/variable-aggregator) node to merge the branches before the common section, without duplicating the same nodes across each branch.
|
||||
</Tip>
|
||||
|
||||
## Configure a Schedule Trigger
|
||||
|
||||
You can configure the schedule using either the default visual picker or a cron expression.
|
||||
|
||||
After configuration, you can see the next 5 scheduled execution times.
|
||||
|
||||
<Info>
|
||||
Schedule triggers do not produce output variables, but they update the system variable `sys.timestamp` (the start time of each workflow execution) each time they initiate the workflow.
|
||||
</Info>
|
||||
|
||||
### With the Visual Picker
|
||||
|
||||
Use this for simple hourly, daily, weekly, or monthly schedules. For weekly and monthly frequencies, you can select multiple days or dates.
|
||||
|
||||
### With a Cron Expression
|
||||
|
||||
Use this for more complex and precise timing patterns, such as every 15 minutes from 9 AM to 5 PM on weekdays.
|
||||
|
||||
<Tip>
|
||||
You can use LLMs to generate cron expressions.
|
||||
</Tip>
|
||||
|
||||
#### Standard Format
|
||||
|
||||
A cron expression is a string that defines the schedule for executing your workflow. It consists of five fields separated by spaces, each representing a different time unit.
|
||||
|
||||
<Note>
|
||||
Ensure that there is a single space between each field.
|
||||
</Note>
|
||||
|
||||
```
|
||||
* * * * *
|
||||
| | | | |
|
||||
| | | | |── Day of week (0-7 or SUN-SAT, where both 0 and 7 = Sunday)
|
||||
| | | |──── Month (1-12 or JAN-DEC)
|
||||
| | |────── Day of month (1-31)
|
||||
| |──────── Hour (0-23)
|
||||
|────────── Minute (0-59)
|
||||
```
|
||||
|
||||
<Info>
|
||||
When both the **day-of-month** and **day-of-week** fields are specified, the trigger activates on dates that match *either* field.
|
||||
|
||||
For example, `1 2 3 4 4` will trigger your workflow on the 3rd of April *and* every Thursday in April, not just on Thursdays that fall on the 3rd.
|
||||
</Info>
|
||||
|
||||
#### Special Characters
|
||||
|
||||
| Character | Description | Example |
|
||||
|:-----------|:-------------|:---------|
|
||||
| `*` | Means "every". | `*` in the **hour** field means "every hour". |
|
||||
| `,` | Separates multiple values. | `1,3,5` in the **day-of-week** field means "Monday, Wednesday, and Friday". |
|
||||
| `-` | Defines a range of values. | `9-17` in the **hour** field means "from 9 AM to 5 PM". |
|
||||
| `/` | Specifies step values. | `*/15` in the **minute** field means "every 15 minutes". |
|
||||
| `L` | Means "the last". <br /><br />In the **day-of-month** field, means "the last day of the month".<br /><br />In the **day-of-week** field:<ul><li>When used alone, means "the last day of the week".</li><li>When combined with a number, means "the last occurrence of that weekday in the month". </li></ul>| `L` in the **day-of-month** field means "Jan 31, April 30, or Feb 28 in a non-leap year".<br /><br />`L` in the **day-of-week** field means Sunday.<br /><br />`5L` in the **day-of-week** field means "the last Friday of the month". |
|
||||
| `?` | Means "any" or "no specific value".<br /><br />If you specify a value for the **day-of-week** field, you can use `?` for the **day-of-month** field to ignore it, and vice versa.<br /><br />Not required, because `*` works as well. | To run a task every Monday, it's more precise to set the **day-of-month** field to `?` instead of `*`. |
|
||||
|
||||
#### Predefined Expressions
|
||||
|
||||
- `@yearly`: Run once a year at 12 AM on January 1.
|
||||
- `@monthly`: Run once a month at 12 AM on the first day of the month.
|
||||
- `@weekly`: Run once a week at 12 AM on Sunday.
|
||||
- `@daily`: Run once a day at 12 AM.
|
||||
- `@hourly`: Run at the beginning of every hour.
|
||||
|
||||
#### Examples
|
||||
|
||||
| Schedule | Cron Expression |
|
||||
|:----------|:-----------------|
|
||||
| Weekdays at 9 AM | `0 9 * * MON-FRI` or `0 9 * * 1-5` |
|
||||
| Every Wednesday at 2:30 PM | `30 14 * * WED` |
|
||||
| Every Sunday at 12 AM | `0 0 * * 0` |
|
||||
| Every 2 hours on Tuesday | `0 */2 * * 2` |
|
||||
| The first day of every month at 12 AM | `0 0 1 * *` |
|
||||
| At 12 PM on January 1 and June 1 | `0 12 1 JAN,JUN *` |
|
||||
| The last day of every month at 5 PM | `0 17 L * *` |
|
||||
| The last Friday of every month at 10 PM | `0 22 * * 5L` |
|
||||
|
||||
## Test a Schedule Trigger
|
||||
|
||||
When you test a schedule trigger (either via **Run this step** or by selecting it for a workflow test run), the trigger runs immediately, ignoring the configured schedule.
|
||||
|
||||
However, when you test a workflow with multiple triggers using **Test Run** > **Run all triggers**, the schedule trigger will wait for its next scheduled execution time instead of running instantly.
|
||||
|
||||
{/*
|
||||
Contributing Section
|
||||
DO NOT edit this section!
|
||||
It will be automatically generated by the script.
|
||||
*/}
|
||||
|
||||
---
|
||||
|
||||
[Edit this page](https://github.com/langgenius/dify-docs/edit/main/en/guides/workflow/node/schedule-trigger.mdx) | [Report an issue](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)
|
||||
|
||||
@@ -1,155 +1,23 @@
|
||||
---
|
||||
title: Start
|
||||
sidebarTitle: "Overview"
|
||||
---
|
||||
|
||||
### Definition
|
||||
Start nodes serve as the entry points for workflows and chatflows.
|
||||
|
||||
The **“Start”** node is a critical preset node in the Chatflow / Workflow application. It provides essential initial information, such as user input and [uploaded files](/en/guides/workflow/file-upload), to support the normal flow of the application and subsequent workflow nodes.
|
||||
There are two types of Start nodes, each initiating your application in a different way.
|
||||
|
||||
### Configuring the Node
|
||||
- **[User Input](/en/guides/workflow/node/user-input)**: The application is initiated by direct user interaction or API calls.
|
||||
|
||||
On the Start node's settings page, you'll find two sections: **"Input Fields"** and preset **System Variables**.
|
||||
- **[Trigger](/en/guides/workflow/node/trigger)** (for workflows only): The application runs automatically on a schedule or in response to a specific third-party event.
|
||||
|
||||

|
||||
<Note>
|
||||
Only applications that start with a User Input node can be published as standalone web apps or MCP servers, exposed through backend service APIs, or used as tools in other Dify applications.
|
||||
</Note>
|
||||
|
||||
### Input Field
|
||||
|
||||
Input field is configured by application developers to prompt users for additional information.
|
||||
|
||||
For example, in a weekly report application, users might be required to provide background information such as name, work date range, and work details in a specific format. This preliminary information helps the LLM generate higher quality responses.
|
||||
|
||||
Eight types of input variables are supported, all of which can be set as required:
|
||||
|
||||
* **Text:** Short text, filled in by the user, with a maximum length of 256 characters.
|
||||
* **Paragraph:** Long text, allowing users to input longer content.
|
||||
* **Select:** Fixed options set by the developer; users can only select from preset options and cannot input custom content.
|
||||
* **Number:** Only allows numerical input.
|
||||
* **Checkbox:** Boolean input rendered as a checkbox, allowing users to select true/false values.
|
||||
* **Object:** Structured JSON input that allows users to provide complex data objects. Only available in Workflow/Chatflow applications.
|
||||
* **Single File:** Allows users to upload a single file. Supports document types, images, audio, video, and other file types. Users can upload locally or paste a file URL. For detailed usage, refer to File Upload.
|
||||
* **File List:** Allows users to batch upload files. Supports document types, images, audio, video, and other file types. Users can upload locally or paste file URLs. For detailed usage, refer to File Upload.
|
||||
|
||||
<Info>
|
||||
Dify's built-in document extractor node can only process certain document formats. For processing images, audio, or video files, refer to External Data Tools to set up corresponding file processing nodes.
|
||||
</Info>
|
||||
|
||||
Once configured, users will be guided to provide necessary information to the LLM before using the application. More information will help to improve the LLM's question-answering efficiency.
|
||||
|
||||
### System Variables
|
||||
|
||||
System variables are preset system-level parameters in Chatflow / Workflow applications that can be globally accessed by other nodes in the application. They are typically used in advanced development scenarios, such as building multi-turn dialogue applications, collecting application logs and monitoring data, or recording usage behavior across different applications and users.
|
||||
|
||||
**Workflow**
|
||||
|
||||
Workflow application provides the following system variables:
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Variable Name</th>
|
||||
<th>Data Type</th>
|
||||
<th>Description</th>
|
||||
<th>Notes</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>sys.files</code><br />[LEGACY]</td>
|
||||
<td>Array[File]</td>
|
||||
<td>File parameter, stores images uploaded by users when initially using the application</td>
|
||||
<td>Image upload feature needs to be enabled in the "Features" section at the top right of the application orchestration page</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>sys.user_id</code></td>
|
||||
<td>String</td>
|
||||
<td>User ID, a unique identifier automatically assigned to each user when using the workflow application, used to distinguish different conversation users</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>sys.app_id</code></td>
|
||||
<td>String</td>
|
||||
<td>Application ID, a unique identifier assigned to each Workflow application by the system, used to distinguish different applications and record basic information of the current application</td>
|
||||
<td>For users with development capabilities, this parameter can be used to differentiate and locate different Workflow applications</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>sys.workflow_id</code></td>
|
||||
<td>String</td>
|
||||
<td>Workflow ID, used to record all node information contained in the current Workflow application</td>
|
||||
<td>For users with development capabilities, this parameter can be used to track and record node information within the Workflow</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>sys.workflow_run_id</code></td>
|
||||
<td>String</td>
|
||||
<td>Workflow application run ID, used to record the running status of the Workflow application</td>
|
||||
<td>For users with development capabilities, this parameter can be used to track the application's run history</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
**Chatflow**
|
||||
|
||||
Chatflow application provides the following system variables:
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Variable Name</th>
|
||||
<th>Data Type</th>
|
||||
<th>Description</th>
|
||||
<th>Notes</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>sys.query</code></td>
|
||||
<td>String</td>
|
||||
<td>The initial content input by the user in the dialogue box</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>sys.files</code></td>
|
||||
<td>Array[File]</td>
|
||||
<td>Images uploaded by the user in the dialogue box</td>
|
||||
<td>Image upload feature needs to be enabled in the "Features" section at the top right of the application orchestration page</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>sys.dialogue_count</code></td>
|
||||
<td>Number</td>
|
||||
<td>The number of dialogue turns during user interaction with the Chatflow application. Automatically increments by 1 after each turn. Can be used with if-else nodes to create rich branching logic. For example, at the Xth turn of dialogue, review the conversation history and provide analysis</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>sys.conversation_id</code></td>
|
||||
<td>String</td>
|
||||
<td>Unique identifier for the dialogue interaction session, grouping all related messages into the same conversation, ensuring the LLM continues the dialogue on the same topic and context</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>sys.user_id</code></td>
|
||||
<td>String</td>
|
||||
<td>Unique identifier assigned to each application user, used to distinguish different conversation users</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>sys.app_id</code></td>
|
||||
<td>String</td>
|
||||
<td>Application ID, a unique identifier assigned to each Workflow application by the system, used to distinguish different applications and record basic information of the current application</td>
|
||||
<td>For users with development capabilities, this parameter can be used to differentiate and locate different Workflow applications</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>sys.workflow_id</code></td>
|
||||
<td>String</td>
|
||||
<td>Workflow ID, used to record all node information contained in the current Workflow application</td>
|
||||
<td>For users with development capabilities, this parameter can be used to track and record node information within the Workflow</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>sys.workflow_run_id</code></td>
|
||||
<td>String</td>
|
||||
<td>Workflow application run ID, used to record the running status of the Workflow application</td>
|
||||
<td>For users with development capabilities, this parameter can be used to track the application's run history</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<Tip>
|
||||
A single workflow can have both User Input nodes and triggers as parallel start points.
|
||||
</Tip>
|
||||
|
||||
{/*
|
||||
Contributing Section
|
||||
|
||||
81
en/guides/workflow/node/trigger.mdx
Normal file
@@ -0,0 +1,81 @@
|
||||
---
|
||||
title: Trigger
|
||||
sidebarTitle: "Overview"
|
||||
---
|
||||
|
||||
## Introduction
|
||||
|
||||
<Info>
|
||||
Triggers are available for workflow applications only.
|
||||
</Info>
|
||||
|
||||
A trigger is a type of Start node that enables your workflow to run automatically—on a schedule or in response to events from external systems (e.g., GitHub, Gmail, or your own internal systems)—rather than waiting for active initiation from a user or an API call.
|
||||
|
||||
Triggers are ideal for automating repetitive tasks or integrating your workflow with third-party applications to achieve automatic data synchronization and processing.
|
||||
|
||||
A workflow can have multiple triggers running in parallel. You can also build several independent workflows on the same canvas, each starting with its own triggers.
|
||||
|
||||
The trigger source for each workflow execution is displayed in the **Logs** section.
|
||||
|
||||
<img src="/images/trigger.png" alt="Trigger" width="450" />
|
||||
|
||||
## Trigger Types
|
||||
|
||||
- [Schedule Trigger](/en/guides/workflow/node/schedule-trigger)
|
||||
|
||||
- Runs your workflow at specified times or intervals.
|
||||
|
||||
- Example: Automatically generate a daily sales report every morning at 9 AM and email it to your team.
|
||||
|
||||
- [Plugin Trigger](/en/guides/workflow/node/plugin-trigger)
|
||||
|
||||
- Runs your workflow when a specific event occurs in an external system, via an event subscription through a trigger plugin.
|
||||
|
||||
- Example: Automatically analyze and archive new messages in a specific Slack channel via a subscription to the `New Message in Channel` event through a Slack trigger plugin.
|
||||
|
||||
- [Webhook Trigger](/en/guides/workflow/node/webhook-trigger)
|
||||
|
||||
- Runs your workflow when a specific event occurs in an external system via a custom webhook.
|
||||
|
||||
- Example: Automatically process new orders in response to an HTTP request containing the order details from your e-commerce platform.
|
||||
|
||||
<Tip>
|
||||
Both plugin triggers and webhook triggers make your workflow *event-driven*. Here's how to choose:
|
||||
|
||||
1. Use a **plugin trigger** when a trigger plugin is available for your target external system. You can simply subscribe to the supported events.
|
||||
|
||||
2. Use a **webhook trigger** when no corresponding plugin exists or when you need to capture events not supported by existing plugins. In such cases, you'll need to set up custom webhooks in the external system.
|
||||
</Tip>
|
||||
|
||||
## Enable or Disable Triggers
|
||||
|
||||
In the **Quick Settings** side menu, you can enable or disable published triggers. Disabled triggers do not initiate workflow execution.
|
||||
|
||||
<Info>
|
||||
Only published triggers appear in **Quick Settings**. If you don't see an added trigger listed, ensure it has been published first.
|
||||
</Info>
|
||||
|
||||
<img src="/images/enable_disable_added_trigger.png" alt="Enable or Disable Published Triggers" width="500" />
|
||||
|
||||
## Test Multiple Triggers
|
||||
|
||||
When a workflow has multiple triggers, you can click **Test Run** > **Run all triggers** to test them at once. The first trigger that activates will initiate the workflow, and the others will then be ignored.
|
||||
|
||||
After you click **Run all triggers**:
|
||||
|
||||
- Schedule triggers will run at the next scheduled execution time.
|
||||
|
||||
- Plugin triggers will listen for subscribed events.
|
||||
|
||||
- Webhook triggers will listen for external HTTP requests.
|
||||
|
||||
{/*
|
||||
Contributing Section
|
||||
DO NOT edit this section!
|
||||
It will be automatically generated by the script.
|
||||
*/}
|
||||
|
||||
---
|
||||
|
||||
[Edit this page](https://github.com/langgenius/dify-docs/edit/main/en/guides/workflow/node/trigger.mdx) | [Report an issue](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)
|
||||
|
||||
121
en/guides/workflow/node/user-input.mdx
Normal file
@@ -0,0 +1,121 @@
|
||||
---
|
||||
title: User Input
|
||||
---
|
||||
|
||||
## Introduction
|
||||
|
||||
The User Input node is a type of Start node where you can define what information to collect from end users when they run your application.
|
||||
|
||||
Applications that start with this node run *on demand*, initiated by direct user interaction or API calls. You can also publish these applications as standalone web apps or MCP servers, expose them through backend service APIs, or use them as tools in other Dify applications.
|
||||
|
||||
<Info>
|
||||
Each application canvas can contain only one User Input node.
|
||||
</Info>
|
||||
|
||||
## Input Variable
|
||||
|
||||
### Preset
|
||||
|
||||
Preset input variables are system-defined and available by default.
|
||||
|
||||
- `userinput.files`: Files uploaded by end users when they run the application.
|
||||
|
||||
<Note>
|
||||
For workflow applications, this preset variable has been considered *legacy* and maintained only for backward compatibility.
|
||||
|
||||
We recommend using a [custom file input field](#file-input) instead to collect user files.
|
||||
</Note>
|
||||
|
||||
- `userinput.query` (for chatflows only): The text message automatically captured from the user's latest chat turn.
|
||||
|
||||
### Custom
|
||||
|
||||
You can configure custom input fields in a User Input node to collect information from end users. Each field becomes a variable that can be referenced by downstream nodes. For example, if you add an input field with the variable name `user_name`, you can reference it as `{{user_name}}` throughout the workflow.
|
||||
|
||||
There are seven types of input fields you can choose from to handle different kinds of user input.
|
||||
|
||||
<Info>
|
||||
The **Label Name** is displayed to your end users.
|
||||
</Info>
|
||||
|
||||
<Tip>
|
||||
In a chatflow application, you can **Hide** any input variable to make it invisible to the end user while keeping it available for reference within the chatflow.
|
||||
</Tip>
|
||||
|
||||
#### Text Input
|
||||
|
||||
<Tabs>
|
||||
|
||||
<Tab title="Short Text">
|
||||
The short-text field accepts up to 256 characters. Use it for names, email addresses, titles, or any brief text input that fits on a single line.
|
||||
</Tab>
|
||||
|
||||
<Tab title="Paragraph">
|
||||
The paragraph field allows long-form text without length restrictions. It gives users a multi-line text area for detailed responses or descriptions.
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
#### Structured Input
|
||||
|
||||
<Tabs>
|
||||
|
||||
<Tab title="Select">
|
||||
The select field displays a dropdown menu with predefined options. Users can choose only from the listed options, ensuring data consistency and preventing invalid inputs.
|
||||
</Tab>
|
||||
|
||||
<Tab title="Number">
|
||||
The number field restricts input to numerical values only—ideal for quantities, ratings, IDs, or any data requiring mathematical processing.
|
||||
</Tab>
|
||||
|
||||
<Tab title="Checkbox">
|
||||
The checkbox field provides a simple yes/no option. When a user checks the box, the output is `true`; otherwise, it's `false`. Use it for confirmations or any case that requires a binary choice.
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
#### File Input
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Single File">
|
||||
The single-file field allows users to upload one file of any supported type, either from their device or via a file URL. The uploaded file is available as a variable containing file metadata (name, size, type, etc.).
|
||||
</Tab>
|
||||
|
||||
<Tab title="File List">
|
||||
The file-list field works like single-file but supports multiple file uploads at once. It's useful for handling batches of documents, images, or other files together.
|
||||
<Tip>
|
||||
You can use a List Operator node to filter, sort, or extract specific files from the uploaded file list for further processing.
|
||||
</Tip>
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
**File Processing**
|
||||
|
||||
Files uploaded through a User Input node must be processed appropriately by subsequent nodes. The User Input node only collects files; it does not read or parse their content.
|
||||
|
||||
Therefore, you need to connect specific nodes to extract and process the file content. For example:
|
||||
|
||||
- Document files can be routed to a Doc Extractor node for text extraction so that LLMs can understand their content.
|
||||
- Images can be sent to LLM nodes with vision capabilities or specialized image processing tool nodes.
|
||||
- Structured data files such as CSV or JSON can be processed with Code nodes to parse and transform the data.
|
||||
|
||||
<Tip>
|
||||
When users upload multiple files with mixed types (e.g., images and documents), you can use a List Operator node to separate them by file type before routing them to appropriate processing branches.
|
||||
</Tip>
|
||||
|
||||
## What's Next
|
||||
|
||||
After setting up a User Input node, you can connect it to other nodes to process the collected data. Common patterns include:
|
||||
|
||||
- Send the input to an LLM node for processing.
|
||||
- Use a Knowledge Retrieval node to find relevant information based on the input.
|
||||
- Route the execution path to different branches with conditional logic based on the input.
|
||||
|
||||
{/*
|
||||
Contributing Section
|
||||
DO NOT edit this section!
|
||||
It will be automatically generated by the script.
|
||||
*/}
|
||||
|
||||
---
|
||||
|
||||
[Edit this page](https://github.com/langgenius/dify-docs/edit/main/en/guides/workflow/node/user-input.mdx) | [Report an issue](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)
|
||||
|
||||
195
en/guides/workflow/node/webhook-trigger.mdx
Normal file
@@ -0,0 +1,195 @@
|
||||
---
|
||||
title: Webhook Trigger
|
||||
---
|
||||
|
||||
## Introduction
|
||||
|
||||
<Info>
|
||||
Triggers are available for workflow applications only.
|
||||
</Info>
|
||||
|
||||
A webhook allows one system to automatically send real-time data to another. When a certain event occurs, the source system packages the event details into an HTTP request and sends it to a designated URL provided by the destination system.
|
||||
|
||||
Following the same mechanism, webhook triggers enable your workflow to run in response to third-party events. Here's how you work with it:
|
||||
|
||||
1. When you add a webhook trigger to your workflow, a unique webhook URL is generated—a dedicated endpoint that listens for external HTTP requests.
|
||||
|
||||
2. You use this URL to create a webhook subscribing to the events you want to monitor in an external system. Then you configure the webhook trigger to define how it processes incoming requests and extracts request data.
|
||||
|
||||
3. When a subscribed event occurs, the external system sends an HTTP request with the event data to that provided webhook URL. Once the request is received and processed successfully, your workflow is triggered, and the specified event data is extracted into variables that can be referenced by downstream nodes.
|
||||
|
||||
<Note>
|
||||
For testing purposes, always use the test webhook URL to keep test data separate from production data.
|
||||
<img src="/images/test_webhook_url.png" alt="Test Webhook URL" width="563" />
|
||||
</Note>
|
||||
|
||||
<Tip>
|
||||
If there's a ready-made trigger plugin for your target external system, we recommend using the [plugin trigger](/en/guides/workflow/node/plugin-trigger) instead.
|
||||
</Tip>
|
||||
|
||||
## Add a Webhook Trigger
|
||||
|
||||
On the workflow canvas, right-click and select **Add Node** > **Start** > **Webhook Trigger**.
|
||||
|
||||
<Tip>
|
||||
- A workflow can have multiple webhook triggers running in parallel. When the parallel branches contain identical consecutive nodes, you can add a [Variable Aggregator](/en/guides/workflow/node/variable-aggregator) node to merge the branches before the common section, without duplicating the same nodes across each branch.
|
||||
</Tip>
|
||||
|
||||
## Configure a Webhook Trigger
|
||||
|
||||
You can define how a webhook trigger handles incoming HTTP requests, including:
|
||||
|
||||
- The expected HTTP method for the webhook URL
|
||||
|
||||
- The request's content-type
|
||||
|
||||
- The data you wish to extract from the request
|
||||
|
||||
- The response sent back to the external system when your workflow is successfully triggered
|
||||
|
||||
<Note>
|
||||
To test an unpublished webhook trigger, make sure to click **Run this step** or test-run the entire workflow first. This puts the trigger into a listening state so that it can receive external requests. Otherwise, no request will be captured.
|
||||
</Note>
|
||||
|
||||
### HTTP Method
|
||||
|
||||
To ensure the incoming request can be received successfully, you need to specify which HTTP method the webhook URL accepts.
|
||||
|
||||
The method you select here must match the one used by the external system to send requests; otherwise, the requests will be rejected.
|
||||
|
||||
<Tip>
|
||||
You can typically find this information in the external system's webhook documentation or setup interface.
|
||||
</Tip>
|
||||
|
||||
### Content-Type
|
||||
|
||||
To ensure the request body can be properly parsed and the data you need extracted, you need to specify the expected content type of the incoming request.
|
||||
|
||||
The content-type you select here must match the content type of the request sent from the external system; otherwise, the request will be rejected.
|
||||
|
||||
### Query Parameters, Header Parameters, and Request Body Parameters
|
||||
|
||||
You can extract specific data from the query parameters, headers, and body of the incoming request. **Each extracted parameter becomes an output variable that can be used in your workflow.**
|
||||
|
||||
Some external systems provide a delivery log for each request, where you can view all the data included in the request and decide which parameters to extract.
|
||||
|
||||
Alternatively, you can send a test request to the webhook trigger and check the received request data in its last run logs:
|
||||
|
||||
1. Create a webhook in the external system using the provided test webhook URL.
|
||||
|
||||
2. Set the correct HTTP method and content-type in the trigger.
|
||||
|
||||
3. Click the **Run this step** icon. The trigger will start listening for external requests.
|
||||
|
||||
4. Trigger the subscribed event in the external system so it sends an HTTP request to the provided webhook URL.
|
||||
|
||||
5. Go to the trigger's **Last Run** tab and check the received request data in **Input**.
|
||||
|
||||
<Note>
|
||||
The variable name you define in the trigger must match the key name of the corresponding parameter in the request.
|
||||
</Note>
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Query Parameters">
|
||||
|
||||
- Parameters in key-value pairs added to the webhook URL (after `?`) by external systems when sending requests, each pair separated by `&`.
|
||||
|
||||
- Typically simple, non-sensitive identifiers or filter data about the event.
|
||||
|
||||
- Example: From the URL `{webhook url}?userID=u-456&source=email`, you can extract the `userID` (`u-456`) or the `source` (`email`).
|
||||
</Tab>
|
||||
<Tab title="Header Parameters">
|
||||
|
||||
- Request metadata included in the request headers.
|
||||
|
||||
- Technical information needed for processing the request, such as an authentication token or the request body's data format.
|
||||
|
||||
- Example: From headers like `Authorization: Bearer sk-abc... `and `Content-Type: application/json`, you can extract the authorization information (`Bearer sk-abc...`) or the content-type (`application/json`).
|
||||
</Tab>
|
||||
<Tab title="Request Body Parameters">
|
||||
|
||||
- The main payload where the core event data is sent, such as a customer profile, order details, or the content of a Slack message.
|
||||
|
||||
- Example: From the following request body, you can extract the `customerName` (`Alex`), the list of items, or the `isPriority` status (`true`).
|
||||
|
||||
```JSON
|
||||
"customerName": "Alex",
|
||||
"items":
|
||||
[
|
||||
{ "sku": "A42", "quantity": 2 },
|
||||
{ "sku": "B12", "quantity": 1 }
|
||||
],
|
||||
"isPriority": true
|
||||
```
|
||||
|
||||
<Info>
|
||||
The content-type determines which data types can be extracted from the request body.
|
||||
|
||||
| Content-Type | `String` | `Number` | `Boolean` | `Object` | `File` | `Array[String]` | `Array[Number]` | `Array[Boolean]` | `Array[Object]` | `Array[File]` |
|
||||
|:--------------|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|
|
||||
| application/json | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ |
|
||||
| application/x-www-form-urlencoded | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ | ❌ | ❌ |
|
||||
| multipart/form-data | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ |
|
||||
| text/plain | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
||||
</Info>
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
**Parameter Settings**
|
||||
|
||||
For each parameter to be extracted, you can specify the following:
|
||||
|
||||
- **Variable Name**: The key name of the parameter in the incoming request (e.g., `userID` in `userID=u-456`).
|
||||
|
||||
<Note>
|
||||
For header parameters, any hyphen (`-`) in the variable name will be automatically converted to an underscore (`_`) in the output variable.
|
||||
</Note>
|
||||
|
||||
- **Data Type**: The expected data format. Available for query and request body parameters only, as header parameters are always treated as strings.
|
||||
|
||||
- **Required**: Whether the parameter is required for your workflow to execute properly. If any required parameter is missing from an incoming request, your workflow will not be triggered.
|
||||
|
||||
### Response
|
||||
|
||||
By default, when your workflow is successfully triggered by an incoming request, a `200 OK` status code with the following response body is sent back to the external system:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"status":"success","message":"Webhook processed successfully"
|
||||
}
|
||||
```
|
||||
|
||||
If the external system requires a specific response format, you can customize the success response's status code and body. The default response will be overridden.
|
||||
|
||||
- **Status Code**: Supports any status code in the range [200, 399].
|
||||
|
||||
- **Response Body**: Supports JSON or plain text.
|
||||
|
||||
<Note>
|
||||
In the returned response body, non-JSON content will be automatically converted to JSON.
|
||||
|
||||
For example, `OK` will be wrapped as `"message": "OK"`.
|
||||
</Note>
|
||||
|
||||
<Info>
|
||||
The following error responses are system-defined and cannot be customized. Error details can be found in the response body.
|
||||
- 400 Bad Request
|
||||
- 404 Not Found
|
||||
- 413 Payload Too Large
|
||||
- 500 Internal Server Error
|
||||
</Info>
|
||||
|
||||
## Test a Webhook Trigger
|
||||
|
||||
To test an unpublished webhook trigger, you must first click **Run this step** or test-run the entire workflow. This puts the trigger into a listening state so that it can receive external requests. Otherwise, incoming requests will not be captured.
|
||||
|
||||
{/*
|
||||
Contributing Section
|
||||
DO NOT edit this section!
|
||||
It will be automatically generated by the script.
|
||||
*/}
|
||||
|
||||
---
|
||||
|
||||
[Edit this page](https://github.com/langgenius/dify-docs/edit/main/en/guides/workflow/node/webhook-trigger.mdx) | [Report an issue](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)
|
||||
|
||||
@@ -1,86 +1,44 @@
|
||||
---
|
||||
title: Variables
|
||||
description: Last edited by Allen, Dify Technical Writer
|
||||
---
|
||||
|
||||
**Workflow** and **Chatflow** Application are composed of independent nodes. Most nodes have input and output items, but the input and output information for each node is not consistent and dynamic.
|
||||
## Introduction
|
||||
|
||||
**How to use a fixed symbol to refer dynamically changing content?** Variables, as dynamic data containers, can store and transmit unfixed content, being referenced mutually within different nodes, providing flexible information mobility between nodes.
|
||||
A variable is a labeled container that stores information in your workflow or chatflow. Each variable holds a piece of data—whether it's user input, system-generated values, or outputs from previous nodes. When you need to use this information later, you simply reference it by its name.
|
||||
|
||||
When building a workflow or chatflow, you'll work with different types of variables, each serving a specific purpose in your application's data flow.
|
||||
|
||||
## Variable Types
|
||||
|
||||
### System Variables
|
||||
### System Variable
|
||||
|
||||
System variables refer to pre-set system-level parameters within Chatflow / Workflow App that can be globally read by other nodes. All system-level variables begin with `sys.`
|
||||
System variables are pre-set, system-level parameters that are globally available.
|
||||
|
||||
**Workflow**
|
||||
<Tabs>
|
||||
<Tab title="Workflow">
|
||||
|
||||
Workflow type application provides the system variables below:
|
||||
| Variable Name | <div style={{width: '70px'}}>Data Type</div> | Description | Notes |
|
||||
|:----------------|:-----------|:-------------|:--------|
|
||||
| `sys.user_id` | String | User ID: A unique identifier automatically assigned by the system to each user when they use a workflow application. It is used to distinguish different users. | |
|
||||
| `sys.app_id` | String | App ID: A unique identifier automatically assigned by the system to each App. This parameter is used to record the basic information of the current application. | This parameter is used to differentiate and locate distinct Workflow applications for users with development capabilities. |
|
||||
| `sys.workflow_id` | String | Workflow ID: This parameter records information about all nodes information in the current Workflow application. | This parameter can be used by users with development capabilities to track and record information about the nodes contained within a Workflow. |
|
||||
| `sys.workflow_run_id` | String | Workflow Run ID: Used to record the runtime status and execution logs of a Workflow application. | This parameter can be used by users with development capabilities to track the application's historical execution records. |
|
||||
| `sys.timestamp` | String | The start time of each workflow execution. | |
|
||||
|
||||
<table><thead><tr><th>Variables name</th><th>Data Type</th><th width="267">Description</th><th>Remark</th></tr></thead><tbody><tr><td><p><code>sys.files</code></p><p><code>[LEGACY]</code></p></td><td>Array[File]</td><td>File Parameter: Stores images uploaded by users</td><td>The image upload function needs to be enabled in the 'Features' section in the upper right corner of the application orchestration page</td></tr><tr><td><code>sys.user_id</code></td><td>String</td><td>User ID: A unique identifier automatically assigned by the system to each user when they use a workflow application. It is used to distinguish different users</td><td></td></tr><tr><td><code>sys.app_id</code></td><td>String</td><td>App ID: A unique identifier automatically assigned by the system to each App. This parameter is used to record the basic information of the current application. </td><td>This parameter is used to differentiate and locate distinct Workflow applications for users with development capabilities</td></tr><tr><td><code>sys.workflow_id</code></td><td>String</td><td>Workflow ID: This parameter records information about all nodes information in the current Workflow application.</td><td>This parameter can be used by users with development capabilities to track and record information about the nodes contained within a Workflow</td></tr><tr><td><code>sys.workflow_run_id</code></td><td>String</td><td>Workflow Run ID: Used to record the runtime status and execution logs of a Workflow application.</td><td>This parameter can be used by users with development capabilities to track the application's historical execution records</td></tr></tbody></table>
|
||||
</Tab>
|
||||
<Tab title="Chatflow">
|
||||
|
||||
| Variable Name | <div style={{width: '70px'}}>Data Type</div> | Description | Notes |
|
||||
|:----------------|:-----------|:-------------|:--------|
|
||||
| `sys.conversation_id` | String | A unique ID for the chatting box interaction session, grouping all related messages into the same conversation, ensuring that the LLM continues the chatting on the same topic and context. | |
|
||||
| `sys.dialogue_count` | Number | The number of conversations turns during the user's interaction with a Chatflow application. The count automatically increases by one after each chat round and can be combined with if-else nodes to create rich branching logic.<br /><br />For example, LLM will review the conversation history at the X conversation turn and automatically provide an analysis. | |
|
||||
| `sys.user_id` | String | A unique ID is assigned for each application user to distinguish different conversation users. | The Service API does not share conversations created by the WebApp. This means users with the same ID will have separate conversation histories between API and WebApp interfaces. |
|
||||
| `sys.app_id` | String | App ID: A unique identifier automatically assigned by the system to each App. This parameter is used to record the basic information of the current application. | This parameter is used to differentiate and locate distinct Workflow applications for users with development capabilities. |
|
||||
| `sys.workflow_id` | String | Workflow ID: This parameter records information about all nodes information in the current Workflow application. | This parameter can be used by users with development capabilities to track and record information about the nodes contained within a Workflow. |
|
||||
| `sys.workflow_run_id` | String | Workflow Run ID: Used to record the runtime status and execution logs of a Workflow application. | This parameter can be used by users with development capabilities to track the application's historical execution records. |
|
||||
|
||||

|
||||
|
||||
**Chatflow**
|
||||
|
||||
Chatflow type application provides the following system variables:
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Variables name</th>
|
||||
<th>Data Type</th>
|
||||
<th>Description</th>
|
||||
<th>Remark</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>sys.query</code></td>
|
||||
<td>String</td>
|
||||
<td>Content entered by the user in the chatting box.</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>sys.files</code></td>
|
||||
<td>Array[File]</td>
|
||||
<td>File Parameter: Stores images uploaded by users</td>
|
||||
<td>The image upload function needs to be enabled in the 'Features' section in the upper right corner of the application orchestration page</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>sys.dialogue_count</code></td>
|
||||
<td>Number</td>
|
||||
<td>The number of conversations turns during the user's interaction with a Chatflow application. The count automatically increases by one after each chat round and can be combined with if-else nodes to create rich branching logic.<br /><br />For example, LLM will review the conversation history at the X conversation turn and automatically provide an analysis.</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>sys.conversation_id</code></td>
|
||||
<td>String</td>
|
||||
<td>A unique ID for the chatting box interaction session, grouping all related messages into the same conversation, ensuring that the LLM continues the chatting on the same topic and context.</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>sys.user_id</code></td>
|
||||
<td>String</td>
|
||||
<td>A unique ID is assigned for each application user to distinguish different conversation users. <br /><br /><strong>Note</strong>: The Service API does not share conversations created by the WebApp. This means users with the same ID will have separate conversation histories between API and WebApp interfaces.</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>sys.workflow_id</code></td>
|
||||
<td>String</td>
|
||||
<td>Workflow ID: This parameter records information about all nodes information in the current Workflow application.</td>
|
||||
<td>This parameter can be used by users with development capabilities to track and record information about the nodes contained within a Workflow</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>sys.workflow_run_id</code></td>
|
||||
<td>String</td>
|
||||
<td>Workflow Run ID: Used to record the runtime status and execution logs of a Workflow application.</td>
|
||||
<td>This parameter can be used by users with development capabilities to track the application's historical execution records</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||

|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### Environment Variables
|
||||
|
||||
|
||||
BIN
images/create_subscription_method.png
Normal file
|
After Width: | Height: | Size: 93 KiB |
BIN
images/enable_disable_added_trigger.png
Normal file
|
After Width: | Height: | Size: 149 KiB |
BIN
images/oauth_client_settings_icon.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
images/plugin_trigger_manual_setup_request_logs.png
Normal file
|
After Width: | Height: | Size: 62 KiB |
BIN
images/test_webhook_url.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
images/trigger.png
Normal file
|
After Width: | Height: | Size: 76 KiB |
BIN
images/trigger_plugin_intro.PNG
Normal file
|
After Width: | Height: | Size: 236 KiB |
BIN
images/trigger_plugin_manual_webhook_setup.PNG
Normal file
|
After Width: | Height: | Size: 71 KiB |
BIN
images/trigger_plugin_manual_webhook_setup_config.PNG
Normal file
|
After Width: | Height: | Size: 134 KiB |
BIN
images/trigger_plugin_oauth_apikey.png
Normal file
|
After Width: | Height: | Size: 72 KiB |
@@ -1,34 +1,24 @@
|
||||
---
|
||||
title: 終了
|
||||
title: 出力
|
||||
version: '日本語'
|
||||
---
|
||||
|
||||
### 定義
|
||||
## 概要
|
||||
|
||||
ワークフローの最終出力内容を定義します。すべてのワークフローは、完全に実行された後、最終結果を出力するための少なくとも1つの終了ノードを必要とします。
|
||||
<Info>
|
||||
- 出力ノードは以前「終了」と呼ばれていました。以前とは異なり、現在は workflow でオプションであり、エンドユーザーに明示的にデータを返したい場合にのみ必要です。
|
||||
|
||||
終了ノードはプロセスの終了ノードであり、その後に他のノードを追加することはできません。ワークフローアプリケーションでは、終了ノードに到達して初めて実行結果が出力されます。プロセスに条件分岐がある場合、複数の終了ノードを定義する必要があります。
|
||||
- このノードは workflow アプリケーションでのみ利用可能です。Chatflow では、会話フロー中にレスポンスを配信するために[回答ノード](/ja-jp/guides/workflow/node/answer)を使用します。
|
||||
</Info>
|
||||
|
||||
終了ノードは1つ以上の出力変数を宣言する必要があります。この宣言の際、任意の上流ノードの出力変数を参照することができます。
|
||||
出力ノードでは、LLM のレスポンスなど、workflow がエンドユーザーに返すものを定義できます。
|
||||
|
||||
出力ノードには少なくとも 1 つの出力変数を指定する必要があります。指定しない場合、何も返されません。
|
||||
|
||||
バックエンドサービス API として公開される場合、出力ノードのない workflow は API 呼び出し元に値を返しません。
|
||||
|
||||
|
||||
***
|
||||
|
||||
### シナリオ
|
||||
|
||||
以下の[長編ストーリー生成ワークフロー](./iteration#1)では、終了ノードで宣言された変数 `Output` は上流のコードノードの出力です。つまり、このワークフローはCode3ノードが実行された後に終了し、Code3の実行結果を出力します。
|
||||
|
||||

|
||||
|
||||
**単一ルートの実行例:**
|
||||
|
||||

|
||||
|
||||
**複数ルートの実行例:**
|
||||
|
||||

|
||||
|
||||
{/*
|
||||
{/*s
|
||||
Contributing Section
|
||||
DO NOT edit this section!
|
||||
It will be automatically generated by the script.
|
||||
@@ -37,4 +27,3 @@ It will be automatically generated by the script.
|
||||
---
|
||||
|
||||
[このページを編集する](https://github.com/langgenius/dify-docs/edit/main/ja-jp/guides/workflow/node/end.mdx) | [問題を報告する](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)
|
||||
|
||||
|
||||
191
ja-jp/guides/workflow/node/plugin-trigger.mdx
Normal file
@@ -0,0 +1,191 @@
|
||||
---
|
||||
title: プラグイントリガー
|
||||
---
|
||||
|
||||
## 概要
|
||||
|
||||
<Info>
|
||||
トリガーは workflow アプリケーションでのみ利用可能です。
|
||||
</Info>
|
||||
|
||||
プラグイントリガーは、外部システムで特定のイベントが発生したときに自動的に workflow を開始します。必要なのは、トリガープラグインを通じてこれらのイベントをサブスクライブし、対応するプラグイントリガーを workflow に追加することだけです。
|
||||
|
||||
例えば、GitHub トリガープラグインをインストールしたとします。これは、`Pull Request`、`Push`、`Issue` を含む、サブスクライブできる GitHub イベントのリストを提供します。`Pull Request` イベントをサブスクライブし、`Pull Request` プラグイントリガーを workflow に追加すると、指定されたリポジトリで誰かがプルリクエストを開くたびに自動的に実行されます。
|
||||
|
||||
## プラグイントリガーの追加と設定
|
||||
|
||||
workflow キャンバスで右クリックし、**ブロックを追加** > **始める** を選択してから、利用可能なプラグイントリガーの中から選択するか、[Dify Marketplace](https://marketplace.dify.ai/?language=jp-ja&category=trigger) でさらに検索します。
|
||||
|
||||
<Tip>
|
||||
- 対象の外部システムに適切なトリガープラグインがない場合は、[コミュニティにリクエスト](https://github.com/langgenius/dify-plugins/issues/new?template=plugin_request.yaml)したり、[自分で開発](/plugin-dev-ja/0222-trigger-plugin)したり、代わりに [Webhook トリガー](/ja-jp/guides/workflow/node/webhook-trigger)を使用したりできます。
|
||||
|
||||
- 1 つの workflow は、並行して実行される複数のプラグイントリガーで開始できます。並行分岐に同一の連続したノードが含まれている場合、共通セクションの前に[変数集約](/ja-jp/guides/workflow/node/variable-aggregator)ノードを追加して分岐をマージできます。これにより、各分岐で同じノードを個別に重複して追加することを回避できます。
|
||||
</Tip>
|
||||
|
||||
2. 既存のサブスクリプションを選択するか、[新しいサブスクリプションを作成](#新しいサブスクリプションを作成)します。
|
||||
|
||||
<Tip>
|
||||
**プラグイン**配下のプラグイン詳細パネルから、特定のサブスクリプションを使用している workflow の数を確認できます。
|
||||
</Tip>
|
||||
|
||||
3. その他の必要な設定を行います。
|
||||
|
||||
<Info>
|
||||
プラグイントリガーの出力変数は、そのトリガープラグインによって定義されており、変更できません。
|
||||
</Info>
|
||||
|
||||
## 新しいサブスクリプションを作成
|
||||
|
||||
<Note>
|
||||
サブスクリプションは一度作成すると変更できません。変更するには、既存のサブスクリプションを削除して新しいサブスクリプションを作成してください。
|
||||
</Note>
|
||||
|
||||
<Info>
|
||||
トリガープラグインは、ワークスペースごとに最大 10 個のサブスクリプションをサポートします。
|
||||
</Info>
|
||||
|
||||
各サブスクリプションは Webhook 上に構築されています。サブスクリプションを作成する際、実際には外部システムからのイベントをリッスンする Webhook を設定しています。
|
||||
|
||||
<Accordion title="Webhook とは?">
|
||||
|
||||
Webhook を使用すると、あるシステムが別のシステムにリアルタイムでデータを自動的に送信できます。特定のイベントが発生すると、ソースシステムはイベントの詳細を HTTP リクエストにパッケージ化し、宛先システムが提供する指定された URL に送信します。
|
||||
|
||||
</Accordion>
|
||||
|
||||
Dify は以下の 2 つの方法でサブスクリプション(Webhook)を作成することをサポートしていますが、各プラグインで利用可能なオプションは、そのプラグインの設計方法によって異なります。
|
||||
|
||||
- **自動作成**:サブスクライブしたいイベントを選択すると、Dify が外部システムで対応する Webhook を自動的に作成します。これには、Dify が Webhook のセットアップを代行できるように、 **OAuth** または **API キー**による事前の認証が必要です。
|
||||
|
||||
- **手動作成**:Dify が提供する Webhook コールバック URL を使用して、自分で Webhook を作成します。認証は不要です。
|
||||
|
||||
<img src="/images/create_subscription_method.png" alt="Ways to Create Subscriptions" width="563" />
|
||||
|
||||
<Tip>
|
||||
サブスクリプションを作成する際は、利用可能なすべてのイベントを選択することをお勧めします。
|
||||
|
||||
プラグイントリガーは、対応するイベントがリンクされたサブスクリプションに含まれている場合にのみ機能します。利用可能なすべてのイベントを選択すると、後で workflow に追加するプラグイントリガーが同じサブスクリプションを使用でき、別のサブスクリプションを作成する必要がなくなります。
|
||||
</Tip>
|
||||
|
||||
<Tabs>
|
||||
<Tab title="OAuth 経由(自動)">
|
||||
|
||||
Dify Cloud では、多くの人気のあるトリガープラグインにデフォルトの OAuth クライアントが事前設定されているため、ワンクリックで Dify を認証できます。
|
||||
|
||||
セルフホスト環境では、カスタム OAuth クライアントオプションのみが利用可能です。つまり、外部システムで OAuth アプリケーションを自分で作成する必要があります。
|
||||
|
||||
<Tabs>
|
||||
<Tab title="デフォルト OAuth クライアント">
|
||||
|
||||
1. **OAuth 経由** > **デフォルト** > **保存と承認**を選択します。
|
||||
|
||||
<Info>
|
||||
**保存**は、選択したオプションが今後のサブスクリプションのデフォルトの OAuth 方法として設定されることを意味します。
|
||||
|
||||
後で方法を切り替えるには、**OAuth クライアント設定**アイコンをクリックします。
|
||||
|
||||
<img src="/images/oauth_client_settings_icon.png" alt="OAuth Client Settings Icon" width="300" />
|
||||
|
||||
</Info>
|
||||
|
||||
2. ポップアップ表示される外部システムの認証ページで、**次へ**をクリックして Dify にアクセスを許可します。
|
||||
|
||||
3. サブスクリプション名を指定し、サブスクライブするイベントを選択し、その他の必要な設定を行います。
|
||||
|
||||
<Tip>
|
||||
利用可能なすべてのイベントを選択することをお勧めします。
|
||||
</Tip>
|
||||
|
||||
4. **作成**をクリックします。
|
||||
|
||||
</Tab>
|
||||
|
||||
<Tab title="カスタム OAuth クライアント">
|
||||
|
||||
1. **OAuth 経由** > **カスタム**を選択します。
|
||||
|
||||
2. 外部システムで、Dify が提供するコールバック URL を使用して新しい OAuth アプリケーションを作成します。
|
||||
|
||||
3. Dify に戻り、新しく作成した OAuth アプリケーションのクライアント ID とクライアントシークレットを入力してから、**保存と承認**をクリックします。
|
||||
|
||||
<Info>
|
||||
保存後、同じクライアント認証情報を今後のサブスクリプションで再利用できます。
|
||||
</Info>
|
||||
|
||||
4. サブスクリプション名を指定し、サブスクライブするイベントを選択し、その他の必要な設定を行います。
|
||||
<Tip>
|
||||
利用可能なすべてのイベントを選択することをお勧めします。
|
||||
</Tip>
|
||||
|
||||
5. **作成**をクリックします。
|
||||
|
||||
</Tab>
|
||||
|
||||
</Tabs>
|
||||
|
||||
<Info>
|
||||
サブスクリプション設定ページに表示される**コールバック URL** は、Dify が外部システムで Webhook を作成する際に内部的に使用されます。
|
||||
|
||||
この URL に対して何か操作を行う必要はありません。
|
||||
</Info>
|
||||
</Tab>
|
||||
|
||||
<Tab title="API キーで作成(自動)">
|
||||
|
||||
1. **API キーで作成**を選択します。
|
||||
|
||||
2. 必要な認証情報を入力してから、**検証**をクリックします。
|
||||
|
||||
3. サブスクリプション名を指定し、サブスクライブするイベントを選択し、その他の必要な設定を行います。
|
||||
|
||||
<Tip>
|
||||
利用可能なすべてのイベントを選択することをお勧めします。
|
||||
</Tip>
|
||||
|
||||
4. **作成**をクリックします。
|
||||
|
||||
<Info>
|
||||
サブスクリプション設定ページに表示される**コールバック URL** は、Dify が外部システムで Webhook を作成する際に内部的に使用されます。
|
||||
|
||||
この URL に対して何か操作を行う必要はありません。
|
||||
</Info>
|
||||
|
||||
</Tab>
|
||||
|
||||
<Tab title="URL を貼り付けて新しいサブスクリプションを作成(手動)">
|
||||
|
||||
1. **URL を貼り付けて新しいサブスクリプションを作成**を選択します。
|
||||
|
||||
2. サブスクリプション名を指定し、提供されたコールバック URL を使用して外部システムで手動で Webhook を作成します。
|
||||
|
||||
3. (オプション)作成した Webhook をテストします。
|
||||
|
||||
<Info>
|
||||
ほとんどの外部システムは、作成時に Dify に ping リクエストを送信することで、新しい Webhook を自動的にテストします。
|
||||
</Info>
|
||||
|
||||
1. サブスクライブしたイベントをトリガーして、外部システムがコールバック URL に HTTP リクエストを送信するようにします。
|
||||
|
||||
2. **手動設定**ページに戻り、ページ下部の**リクエストログ**セクションを確認します。Webhook が正しく機能している場合、受信したリクエストと Dify のレスポンスが表示されます。
|
||||
|
||||
<img src="/images/plugin_trigger_manual_setup_request_logs.png" alt="Request Logs" width="563" />
|
||||
|
||||
4. **作成**をクリックします。
|
||||
|
||||
</Tab>
|
||||
|
||||
</Tabs>
|
||||
|
||||
## プラグイントリガーをテストする
|
||||
|
||||
未公開のプラグイントリガーをテストするには、まず**このステップ実行**をクリックするか、workflow 全体をテスト実行する必要があります。これによりトリガーがリスニング状態になり、外部イベントを監視できるようになります。そうしないと、イベントが発生してもトリガーはサブスクライブしたイベントをキャプチャしません。
|
||||
|
||||
{/*
|
||||
Contributing Section
|
||||
DO NOT edit this section!
|
||||
It will be automatically generated by the script.
|
||||
*/}
|
||||
|
||||
---
|
||||
|
||||
[このページを編集する](https://github.com/langgenius/dify-docs/edit/main/ja-jp/guides/workflow/node/plugin-trigger.mdx) | [問題を報告する](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)
|
||||
|
||||
115
ja-jp/guides/workflow/node/schedule-trigger.mdx
Normal file
@@ -0,0 +1,115 @@
|
||||
---
|
||||
title: スケジュールトリガー
|
||||
---
|
||||
|
||||
## 概要
|
||||
|
||||
<Info>
|
||||
トリガーは workflow アプリケーションでのみ利用可能です。
|
||||
</Info>
|
||||
|
||||
スケジュールトリガーを使用すると、指定した時刻または間隔で workflow を実行できます。これは、日次レポートの生成やスケジュールされた通知の送信など、繰り返し発生するタスクに最適です。
|
||||
|
||||
## スケジュールトリガーの追加
|
||||
|
||||
workflow キャンバスで右クリックし、**ブロックを追加** > **始める** > **スケジュールトリガー** を選択します。
|
||||
|
||||
<Tip>
|
||||
1 つの workflow は、並行して実行される複数のスケジュールトリガーで開始できます。並行分岐に同一の連続したノードが含まれている場合、共通セクションの前に[変数集約](/ja-jp/guides/workflow/node/variable-aggregator)ノードを追加して分岐をマージできます。これにより、各分岐で同じノードを個別に重複して追加することを回避できます。
|
||||
</Tip>
|
||||
|
||||
## スケジュールトリガーの設定
|
||||
|
||||
トリガーのスケジュールは、デフォルトのビジュアル設定または Cron 式を使用して設定できます。
|
||||
|
||||
設定後、次の 5 回のスケジュール実行時刻を確認できます。
|
||||
|
||||
<Info>
|
||||
スケジュールトリガーは出力変数を生成しませんが、workflow をトリガーするたびにシステム変数 `sys.timestamp`(各 workflow 実行の開始時刻)を更新します。
|
||||
</Info>
|
||||
|
||||
### ビジュアル設定を使用
|
||||
|
||||
単純な毎時、毎日、毎週、または毎月のスケジュールに使用します。毎週および毎月の頻度では、複数の曜日や日付を選択できます。
|
||||
|
||||
### Cron 式を使用
|
||||
|
||||
平日の午前 9 時から午後 5 時まで 15 分ごと、といったより複雑で正確なタイミングパターンに使用します。
|
||||
|
||||
<Tip>
|
||||
LLM を使用して Cron 式を生成できます。
|
||||
</Tip>
|
||||
|
||||
#### 標準フォーマット
|
||||
|
||||
Cron 式は、workflow の実行スケジュールを定義する文字列です。スペースで区切られた 5 つのフィールドで構成され、それぞれが異なる時間単位を表します。
|
||||
|
||||
<Note>
|
||||
各フィールド間に 1 つのスペースがあることを確認してください。
|
||||
</Note>
|
||||
|
||||
```
|
||||
* * * * *
|
||||
| | | | |
|
||||
| | | | |── 曜日 (0-7 または SUN-SAT、0 と 7 は両方とも日曜日)
|
||||
| | | |──── 月 (1-12 または JAN-DEC)
|
||||
| | |────── 日 (1-31)
|
||||
| |──────── 時間 (0-23)
|
||||
|────────── 分 (0-59)
|
||||
```
|
||||
|
||||
<Info>
|
||||
|
||||
**日**と**曜日**の両方のフィールドが指定されている場合、トリガーは*どちらか*のフィールドに一致する日付でアクティブになります。
|
||||
|
||||
例えば、`1 2 3 4 4` は、4 月 3 日*および* 4 月の毎週木曜日に workflow をトリガーします。4 月 3 日が木曜日である場合に限定されません。
|
||||
</Info>
|
||||
|
||||
#### 特殊文字
|
||||
|
||||
| <div style={{width: '50px'}}>文字</div> | 説明 | 例 |
|
||||
|:-----------|:-------------|:---------|
|
||||
| `*` | 「毎」を意味します。 | **時間**フィールドの `*` は「毎時」を意味します。 |
|
||||
| `,` | 複数の値を区切ります。 | **曜日**フィールドの `1,3,5` は「月曜日、水曜日、金曜日」を意味します。 |
|
||||
| `-` | 値の範囲を定義します。 | **時間**フィールドの `9-17` は「午前 9 時から午後 5 時まで」を意味します。 |
|
||||
| `/` | ステップ値を指定します。 | **分**フィールドの `*/15` は「15 分ごと」を意味します。 |
|
||||
| `L` | 「最後」を意味します。<br /><br />**日**フィールドでは、「その月の最終日」を意味します。<br /><br />**曜日**フィールドでは:<ul><li>単独で使用すると、「週の最終日」を意味します。</li><li>数字と組み合わせると、「その月の最後の指定された曜日」を意味します。</li></ul>| **日**フィールドの `L` は「1 月 31 日、4 月 30 日、または閏年でない年の 2 月 28 日」を意味します。<br /><br />**曜日**フィールドの `L` は日曜日を意味します。<br /><br />**曜日**フィールドの `5L` は「その月の最後の金曜日」を意味します。 |
|
||||
| `?` | 「任意」または「特定の値なし」を意味します。<br /><br />**曜日**フィールドに値を指定した場合、**日**フィールドを無視するために `?` を使用できます。逆も同様です。<br /><br />必須ではありません。`*` も同様に機能するためです。 | 毎週月曜日にタスクを実行するには、**日**フィールドを `*` の代わりに `?` に設定する方がより正確です。 |
|
||||
|
||||
#### 定義済み表現
|
||||
|
||||
- `@yearly`:年に一度、1 月 1 日の午前 0 時に実行。
|
||||
- `@monthly`:月に一度、月の初日の午前 0 時に実行。
|
||||
- `@weekly`:週に一度、日曜日の午前 0 時に実行。
|
||||
- `@daily`:日に一度、午前 0 時に実行。
|
||||
- `@hourly`:毎正時に実行。
|
||||
|
||||
#### 例
|
||||
|
||||
| スケジュール | Cron 式 |
|
||||
|:----------|:-----------------|
|
||||
| 平日の午前 9 時 | `0 9 * * MON-FRI` または `0 9 * * 1-5` |
|
||||
| 毎週水曜日の午後 2 時 30 分 | `30 14 * * WED` |
|
||||
| 毎週日曜日の午前 0 時 | `0 0 * * 0` |
|
||||
| 毎週火曜日の 2 時間ごと | `0 */2 * * 2` |
|
||||
| 毎月初日の午前 0 時 | `0 0 1 * *` |
|
||||
| 1 月 1 日と 6 月 1 日の午後 12 時 | `0 12 1 JAN,JUN *` |
|
||||
| 毎月最終日の午後 5 時 | `0 17 L * *` |
|
||||
| 毎月最終金曜日の午後 10 時 | `0 22 * * 5L` |
|
||||
|
||||
## スケジュールトリガーのテスト
|
||||
|
||||
スケジュールトリガーをテストする場合(**このステップ実行**をクリックするか、workflow のテスト実行で選択するかにかかわらず)、トリガーは設定されたスケジュールを無視して即座に実行されます。
|
||||
|
||||
ただし、**テスト実行** > **すべてのトリガーを実行**をクリックして workflow のすべてのトリガーを同時にテストする場合、スケジュールトリガーは即座に実行されるのではなく、次のスケジュールされた実行時刻を待ちます。
|
||||
|
||||
{/*
|
||||
Contributing Section
|
||||
DO NOT edit this section!
|
||||
It will be automatically generated by the script.
|
||||
*/}
|
||||
|
||||
---
|
||||
|
||||
[このページを編集する](https://github.com/langgenius/dify-docs/edit/main/ja-jp/guides/workflow/node/schedule-trigger.mdx) | [問題を報告する](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)
|
||||
|
||||
@@ -1,97 +1,24 @@
|
||||
---
|
||||
title: 開始
|
||||
version: '日本語'
|
||||
sidebarTitle: "概要"
|
||||
---
|
||||
|
||||
## 定義
|
||||
開始ノードは、workflow および chatflow のエントリーポイントとして機能します。
|
||||
|
||||
**“開始”** ノードは、すべてのワークフローアプリ(チャットフロー / ワークフロー)に必須のデフォルトノードであり、後続のワークフローノードやアプリの正常なプロセスに必要な初期情報を提供します。これには、アプリの使用者が入力した内容や、[アップロードされたファイル](/ja-jp/guides/workflow/file-upload)などが含まれます。
|
||||
開始ノードには 2 種類があり、それぞれ異なる方法でアプリケーションを開始します。
|
||||
|
||||
### ノードの設定
|
||||
- **[ユーザー入力](/ja-jp/guides/workflow/node/user-input)**:ユーザーによる直接的な操作や API 呼び出しによって、アプリケーションが開始されます。
|
||||
|
||||
開始ノードの設定ページでは、**“入力フィールド”**とデフォルトの[**システム変数**](/ja-jp/guides/workflow/variables)という二つの設定部分が見られます。
|
||||
|
||||
<Frame caption="チャットフローとワークフロー">
|
||||
<img src="https://assets-docs.dify.ai/dify-enterprise-mintlify/jp/guides/workflow/node/c4a9bb46f636807f0b59710724fddc40.png" alt="" />
|
||||
</Frame>
|
||||
|
||||
### 入力フィールド
|
||||
|
||||
入力フィールドの機能はアプリ開発者によって設定され、通常はアプリの使用者がさらに情報を提供するために使用されます。例えば、週次報告アプリでは、使用者に対して名前、作業期間、作業内容などの背景情報をあらかじめフォーマットに従って提供するよう求めることがあります。これらの前提情報は、LLM(大規模言語モデル)がより質の高い回答を生成するのに役立ちます。
|
||||
|
||||
以下の8種類の入力変数をサポートしており、すべての変数は必須項目として設定可能です:
|
||||
|
||||
* **テキスト**
|
||||
|
||||
短いテキストで、アプリ使用者が自分で内容を入力します。最大文字数は256文字です。
|
||||
* **段落**
|
||||
|
||||
長文で、アプリ使用者が長いテキストを入力することができます。
|
||||
* **ドロップダウンオプション**
|
||||
|
||||
アプリ開発者によって固定された選択肢で、アプリ使用者は設定された選択肢の中からのみ選ぶことができ、自由に内容を入力することはできません。
|
||||
* **数字**
|
||||
|
||||
数字のみの入力を許可します。
|
||||
* **チェックボックス**
|
||||
|
||||
ブール値入力で、チェックボックスとして表示され、ユーザーが真/偽の値を選択できます。
|
||||
* **オブジェクト**
|
||||
|
||||
構造化されたJSON入力で、ユーザーが複雑なデータオブジェクトを提供できます。ワークフロー/チャットフローアプリでのみ使用可能です。
|
||||
* **単一ファイル**
|
||||
|
||||
アプリ使用者が単独でファイルをアップロードできる機能で、サポートされるファイルタイプは文書、画像、音声、動画、その他のファイルです。ローカルからのファイルアップロードやファイルのURLを貼り付けてのアップロードが可能です。詳細な使い方については[ファイルアップロード](/ja-jp/guides/workflow/file-upload)を参照してください。
|
||||
* **ファイルリスト**
|
||||
|
||||
アプリ使用者が複数のファイルを一括でアップロードできる機能で、サポートされるファイルタイプは文書、画像、音声、動画、その他のファイルです。ローカルからのファイルアップロードやファイルのURLを貼り付けてのアップロードが可能です。詳細な使い方については[ファイルアップロード](/ja-jp/guides/workflow/file-upload)を参照してください。
|
||||
- **[トリガー](/ja-jp/guides/workflow/node/trigger)**(workflow のみ):アプリケーションはスケジュールに従って、または特定のサードパーティイベントに応じて自動的に実行されます。
|
||||
|
||||
<Note>
|
||||
Difyに組み込まれているファイル抽出ノードは、特定のフォーマットファイルのみを処理できます。画像、音声、動画ファイルを処理する必要がある場合は、[外部データツール](/ja-jp/guides/extension/code-based-extension/external-data-tool)を参照し、対応するファイル処理ノードを構築してください。
|
||||
ユーザー入力ノードで開始するアプリケーションのみ、単体の Web アプリや MCP サーバーとして公開でき、バックエンドサービス API を通じて外部に公開したり、他の Dify アプリケーション内でツールとして利用したりできます。
|
||||
</Note>
|
||||
|
||||
設定が完了した後、使用者はアプリを使用する前に、入力項目に従ってLLMに必要な情報を提供します。より多くの情報がLLMの質問応答効率を向上させるのに役立ちます。
|
||||
|
||||
<Frame caption="">
|
||||
<img src="https://assets-docs.dify.ai/dify-enterprise-mintlify/jp/guides/workflow/node/2b26dc5f5b088304b65190e14f58423a.png" alt="" />
|
||||
</Frame>
|
||||
|
||||
### システム変数
|
||||
|
||||
システム変数は、チャットフロー / ワークフローアプリ内であらかじめ設定されたシステムレベルのパラメータであり、アプリ内の他のノードからグローバルに読み取ることができます。通常は、高度な開発シナリオで使用され、たとえば多段階対話アプリの構築、アプリのログ収集と監視、異なるアプリや使用者の使用行動の記録などに利用されます。
|
||||
|
||||
**ワークフロー**
|
||||
|
||||
ワークフロータイプのアプリは以下のシステム変数を提供します:
|
||||
|
||||
| 変数名 | データタイプ | 説明 | メモ |
|
||||
| ---------------------- | ------------ | ----------------------------------------------------------------------------------------------------- | ------------------------- |
|
||||
| `sys.files` | Array[File] | ファイルパラメータで、ユーザーがアプリを使用する際にアップロードした画像を保存します。複数の画像をアップロードできます。このパラメータは今後廃止予定であり、「入力フィールド」内のファイル変数の使用を推奨します。 | 画像アップロード機能は、アプリの編成ページの右上にある「機能」で有効にする必要があります。 |
|
||||
| `sys.user_id` | String | ユーザーIDで、各ユーザーがワークフローアプリを使用する際に、システムが自動的に一意の識別子を割り当てて、異なる対話ユーザーを区別します。 | |
|
||||
| `sys.app_id` | String | アプリIDで、システムが各ワークフローアプリに一意の識別子を割り当て、異なるアプリを区別し、このパラメータを通じて現在のアプリの基本情報を記録します。 | 開発能力のあるユーザー向けで、このパラメータを通じて異なるワークフローアプリを区別・特定できます。 |
|
||||
| `sys.workflow_id` | String | ワークフローIDで、現在のワークフローアプリに含まれるすべてのノード情報を記録します。 | 開発能力のあるユーザー向けで、このパラメータを通じてワークフロー内のノード情報を追跡・記録できます。 |
|
||||
| `sys.workflow_run_id` | String | ワークフローアプリの実行IDで、ワークフローアプリの運用状況を記録します。 | 開発能力のあるユーザー向けで、このパラメータを通じてアプリの過去の実行状況を追跡できます。 |
|
||||
|
||||
<Frame caption="ワークフロータイプアプリのシステム変数">
|
||||

|
||||
</Frame>
|
||||
|
||||
**チャットフロー**
|
||||
|
||||
チャットフロータイプのアプリケーションは、以下のシステム変数を提供しています:
|
||||
|
||||
| 変数名 | データ型 | 説明 | メモ |
|
||||
|---------|--------|------|------|
|
||||
| `sys.query` | String | ユーザーが最初に入力した内容 | |
|
||||
| `sys.files` | Array[File] | ユーザーがアップロードした画像 | 画像のアップロード機能は、アプリケーションの編成ページ右上の「機能」で有効化する必要があります |
|
||||
| `sys.dialogue_count` | Number | チャットフロータイプのアプリケーションとの対話中にユーザーが行った対話のラウンド数です。各対話の後に自動的に数が増加し、if-elseノードと組み合わせて複雑な分岐ロジックを構築できます。たとえば、Xラウンド目に達したときに、対話履歴を振り返って分析が可能です | |
|
||||
| `sys.conversation_id` | String | ダイアログの対話セッションの一意の識別子で、関連するすべてのメッセージを同じ対話にグループ化し、LLMが同じトピックとコンテキストで継続的に対話できるようにします | |
|
||||
| `sys.user_id` | String | 各アプリケーションユーザーに割り当てられた一意の識別子で、異なる対話ユーザーを区別するために使用されます | |
|
||||
| `sys.app_id` | String | アプリケーションのIDで、システムは各ワークフローアプリケーションに一意の識別子を割り当て、異なるアプリケーションを識別します。このパラメータを使用して現在のアプリケーションの基本情報を記録します | 開発者向けで、このパラメータを使用して異なるワークフローアプリケーションを区別します |
|
||||
| `sys.workflow_id` | String | ワークフローIDで、現在のワークフローアプリケーションに含まれるすべてのノード情報を記録するために使用されます | 開発者向けで、このパラメータを使用してワークフロー内のノード情報を追跡および記録できます |
|
||||
| `sys.workflow_run_id` | String | ワークフローアプリケーションの実行IDで、アプリケーションの実行状況を記録するために使用されます | 開発者向けで、このパラメータを使用してアプリケーションの過去の実行状況を追跡できます |
|
||||
|
||||

|
||||
<Tip>
|
||||
1 つの workflow において、ユーザー入力ノードとトリガーを並行する開始ポイントとして設定することも可能です。
|
||||
</Tip>
|
||||
|
||||
{/*
|
||||
Contributing Section
|
||||
|
||||
81
ja-jp/guides/workflow/node/trigger.mdx
Normal file
@@ -0,0 +1,81 @@
|
||||
---
|
||||
title: トリガー
|
||||
sidebarTitle: "概要"
|
||||
---
|
||||
|
||||
## 概要
|
||||
|
||||
<Info>
|
||||
トリガーは workflow アプリケーションでのみ利用可能です。
|
||||
</Info>
|
||||
|
||||
トリガーは開始ノードの一種で、ユーザーや API 呼び出しによる能動的な開始を待つのではなく、スケジュールに従って、または外部システム(例:GitHub、Gmail、または独自の内部システム)からのイベントに応じて、workflow を自動的に実行できるようにします。
|
||||
|
||||
トリガーは、反復タスクの自動化や、workflow をサードパーティアプリケーションと統合して自動的なデータ同期と処理を実現するのに最適です。
|
||||
|
||||
1 つの workflow は、並行して実行される複数のトリガーを持つことができます。また、同じキャンバス上に複数の独立した workflow を構築し、それぞれが独自のトリガーで開始することもできます。
|
||||
|
||||
各 workflow 実行のトリガーソースは、**ログ**セクションに表示されます。
|
||||
|
||||
<img src="/images/trigger.png" alt="Trigger" width="450" />
|
||||
|
||||
## トリガータイプ
|
||||
|
||||
- [スケジュールトリガー](/ja-jp/guides/workflow/node/schedule-trigger)
|
||||
|
||||
- 指定された時刻または間隔で workflow を実行します。
|
||||
|
||||
- 例:毎朝 9 時に日次売上レポートを自動生成し、チームにメールで送信します。
|
||||
|
||||
- [プラグイントリガー](/ja-jp/guides/workflow/node/plugin-trigger)
|
||||
|
||||
- トリガープラグインを通じたイベントサブスクリプションにより、外部システムで特定のイベントが発生したときに workflow を実行します。
|
||||
|
||||
- 例:Slack トリガープラグインを通じて`チャンネル内の新規メッセージ`イベントをサブスクライブすることで、特定の Slack チャンネル内の新規メッセージを自動的に分析およびアーカイブします。
|
||||
|
||||
- [Webhook トリガー](/ja-jp/guides/workflow/node/webhook-trigger)
|
||||
|
||||
- カスタム webhook を介して外部システムで特定のイベントが発生したときに workflow を実行します。
|
||||
|
||||
- 例:e コマースプラットフォームから注文詳細を含む HTTP リクエストに応答して、新規注文を自動的に処理します。
|
||||
|
||||
<Tip>
|
||||
プラグイントリガーと webhook トリガーは、どちらも workflow を*イベント駆動型*にします。選択方法は次のとおりです:
|
||||
|
||||
1. 対象の外部システムにトリガープラグインが利用可能な場合は、**プラグイントリガー**を使用してください。サポートされているイベントを簡単にサブスクライブできます。
|
||||
|
||||
2. 対応するプラグインが存在しない場合、または既存のプラグインでサポートされていないイベントをキャプチャする必要がある場合は、**webhook トリガー**を使用します。この場合、外部システムでカスタム webhook を設定する必要があります。
|
||||
</Tip>
|
||||
|
||||
## トリガーの有効化または無効化
|
||||
|
||||
**クイック設定**サイドメニューでは、公開済みのトリガーを有効化または無効化できます。無効化されたトリガーは workflow の実行を開始しません。
|
||||
|
||||
<Info>
|
||||
**クイック設定**には、公開済みのトリガーのみが表示されます。トリガーがリストに表示されない場合は、まず公開されていることを確認してください。
|
||||
</Info>
|
||||
|
||||
<img src="/images/enable_disable_added_trigger.png" alt="Enable or Disable Published Triggers" width="500" />
|
||||
|
||||
## 複数のトリガーをテストする
|
||||
|
||||
workflow に複数のトリガーがある場合、**テスト実行** > **すべてのトリガーを実行**をクリックして一度にテストできます。最初にアクティブ化されたトリガーが workflow を開始し、他のトリガーは無視されます。
|
||||
|
||||
**すべてのトリガーを実行**をクリックすると:
|
||||
|
||||
- スケジュールトリガーは次の予定実行時刻に実行されます。
|
||||
|
||||
- プラグイントリガーはサブスクライブされたイベントをリッスンします。
|
||||
|
||||
- Webhook トリガーは受信 HTTP リクエストをリッスンします。
|
||||
|
||||
{/*
|
||||
Contributing Section
|
||||
DO NOT edit this section!
|
||||
It will be automatically generated by the script.
|
||||
*/}
|
||||
|
||||
---
|
||||
|
||||
[このページを編集する](https://github.com/langgenius/dify-docs/edit/main/ja-jp/guides/workflow/node/trigger.mdx) | [問題を報告する](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)
|
||||
|
||||
121
ja-jp/guides/workflow/node/user-input.mdx
Normal file
@@ -0,0 +1,121 @@
|
||||
---
|
||||
title: ユーザー入力
|
||||
---
|
||||
|
||||
## 概要
|
||||
|
||||
ユーザー入力ノードは開始ノードの一種で、エンドユーザーがアプリケーションを実行する際に収集する情報を定義できます。
|
||||
|
||||
このノードで開始するアプリケーションはオンデマンドで実行され、ユーザーの直接的な操作や API 呼び出しによって開始されます。これらのアプリケーションは、単体の Web アプリや MCP サーバーとして公開したり、バックエンドサービス API を通じて外部に公開したり、他の Dify アプリケーション内でツールとして利用したりできます。
|
||||
|
||||
<Info>
|
||||
各アプリケーションキャンバスには、ユーザー入力ノードを 1 つだけ配置できます。
|
||||
</Info>
|
||||
|
||||
## 入力変数
|
||||
|
||||
### プリセット
|
||||
|
||||
プリセット入力変数はシステムで定義されており、デフォルトで利用可能です。
|
||||
|
||||
- `userinput.files`:エンドユーザーがアプリケーションを実行する際にアップロードしたファイル。
|
||||
|
||||
<Note>
|
||||
workflow アプリケーションの場合、このプリセット変数は*レガシー機能(legacy)*と見なされており、後方互換性のためにのみ維持されています。
|
||||
|
||||
ユーザーファイルを収集する際は、[カスタムファイル型入力フィールド](#ファイル入力)の使用を推奨します。
|
||||
</Note>
|
||||
|
||||
- `userinput.query`(chatflow のみ):ユーザーの最新の会話ターンから自動的にキャプチャされたテキストメッセージ。
|
||||
|
||||
### カスタム
|
||||
|
||||
ユーザー入力ノードでカスタム入力フィールドを設定して、エンドユーザーから情報を収集できます。各フィールドは変数となり、下流のノードから参照できます。例えば、変数名が `user_name` の入力フィールドを追加した場合、workflow 全体で `{{user_name}}` として参照できます。
|
||||
|
||||
さまざまな種類のユーザー入力を処理するために、7 種類の入力フィールドタイプから選択できます。
|
||||
|
||||
<Info>
|
||||
**ラベル名**はエンドユーザーに表示されます。
|
||||
</Info>
|
||||
|
||||
<Tip>
|
||||
chatflow アプリケーションでは、任意の入力変数を**非表示**にして、エンドユーザーには見えないようにしながら、chatflow 内部では参照可能な状態を維持できます。
|
||||
</Tip>
|
||||
|
||||
#### テキスト入力
|
||||
|
||||
<Tabs>
|
||||
|
||||
<Tab title="短文">
|
||||
短文フィールドは最大 256 文字まで受け付けます。名前、メールアドレス、タイトル、または 1 行に収まる短いテキスト入力に適しています。
|
||||
</Tab>
|
||||
|
||||
<Tab title="段落">
|
||||
段落フィールドは長文テキスト入力を許可し、文字数制限はありません。詳細な回答や説明のために、複数行のテキストエリアをユーザーに提供します。
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
#### 構造化入力
|
||||
|
||||
<Tabs>
|
||||
|
||||
<Tab title="選択">
|
||||
選択フィールドは、事前定義されたオプションを含むドロップダウンメニューを表示します。ユーザーはリストされたオプションからのみ選択できるため、データの一貫性が確保され、無効な入力を防ぐことができます。
|
||||
</Tab>
|
||||
|
||||
<Tab title="数値">
|
||||
数値フィールドは数値のみの入力に制限されます。数量、評価、ID、または数学的処理が必要なデータに最適です。
|
||||
</Tab>
|
||||
|
||||
<Tab title="チェックボックス">
|
||||
チェックボックスフィールドは、シンプルなはい/いいえの選択肢を提供します。ユーザーがボックスをチェックすると出力は `true` に、そうでなければ `false` になります。確認や二者択一が必要な場合に使用します。
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
#### ファイル入力
|
||||
|
||||
<Tabs>
|
||||
<Tab title="単一ファイル">
|
||||
単一ファイルフィールドは、サポートされている任意のタイプのファイルを 1 つアップロードできます。デバイスからのアップロードまたはファイル URL 経由でのアップロードが可能です。アップロードされたファイルは、ファイルメタデータ(名前、サイズ、タイプなど)を含む変数として利用できます。
|
||||
</Tab>
|
||||
|
||||
<Tab title="ファイルリスト">
|
||||
ファイルリストフィールドは単一ファイルと同様に機能しますが、一度に複数のファイルをアップロードできます。ドキュメント、画像、その他のファイルをまとめて処理する場合に便利です。
|
||||
<Tip>
|
||||
リスト操作ノードを使用して、アップロードされたファイルリストから特定のファイルをフィルタリング、ソート、または抽出して、さらなる処理を行うことができます。
|
||||
</Tip>
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
**ファイルの処理**
|
||||
|
||||
ユーザー入力ノードを通じてアップロードされたファイルは、後続のノードで適切に処理される必要があります。ユーザー入力ノードはファイルを収集するだけで、その内容を読み取ったり解析したりはしません。
|
||||
|
||||
そのため、ファイルの内容を抽出・処理するために特定のノードを接続する必要があります。例えば:
|
||||
|
||||
- ドキュメントファイルは、LLM が内容を理解できるよう、文書抽出器ノードにルーティングしてテキスト抽出を行えます。
|
||||
- 画像は、ビジョン機能を持つ LLM ノードや専用の画像処理ツールに送信できます。
|
||||
- CSV や JSON などの構造化データファイルは、コードノードを使用してデータを解析・変換できます。
|
||||
|
||||
<Tip>
|
||||
ユーザーが異なるタイプのファイル(画像とドキュメントなど)を複数アップロードした場合、リスト操作ノードを使用してファイルタイプごとに分離し、適切な処理ブランチにルーティングできます。
|
||||
</Tip>
|
||||
|
||||
## 次のステップ
|
||||
|
||||
ユーザー入力ノードを設定した後、他のノードに接続して収集したデータを処理できます。一般的なパターンには次のようなものがあります:
|
||||
|
||||
- 入力を LLM ノードに送信して処理する。
|
||||
- 知識検索ノードを使用して、入力に基づいて関連情報を検索する。
|
||||
- 入力に基づいた条件ロジックで、実行パスを異なるブランチにルーティングする。
|
||||
|
||||
{/*
|
||||
Contributing Section
|
||||
DO NOT edit this section!
|
||||
It will be automatically generated by the script.
|
||||
*/}
|
||||
|
||||
---
|
||||
|
||||
[このページを編集する](https://github.com/langgenius/dify-docs/edit/main/ja-jp/guides/workflow/node/user-input.mdx) | [問題を報告する](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)
|
||||
|
||||
197
ja-jp/guides/workflow/node/webhook-trigger.mdx
Normal file
@@ -0,0 +1,197 @@
|
||||
---
|
||||
title: Webhook トリガー
|
||||
---
|
||||
|
||||
## 概要
|
||||
|
||||
<Info>
|
||||
トリガーは workflow アプリケーションでのみ利用可能です。
|
||||
</Info>
|
||||
|
||||
Webhook を使用すると、あるシステムが別のシステムにリアルタイムでデータを自動的に送信できます。特定のイベントが発生すると、ソースシステムはイベントの詳細を HTTP リクエストにパッケージ化し、宛先システムが提供する指定された URL に送信します。
|
||||
|
||||
同じ仕組みに従い、Webhook トリガーを使用すると、サードパーティのイベントに応答して workflow を実行できます。使用方法は次のとおりです:
|
||||
|
||||
1. workflow に Webhook トリガーを追加すると、一意の Webhook URL が生成されます。これは、外部 HTTP リクエストをリッスンする専用エンドポイントです。
|
||||
|
||||
2. この URL を使用して、外部システムで監視したいイベントをサブスクライブする Webhook を作成します。次に、Webhook トリガーを設定して、受信リクエストの処理方法とリクエストデータの抽出方法を定義します。
|
||||
|
||||
3. サブスクライブしたイベントが発生すると、外部システムはイベントデータを含む HTTP リクエストを提供された Webhook URL に送信します。リクエストが正常に受信および処理されると、workflow がトリガーされ、指定されたイベントデータが変数として抽出され、ダウンストリームノードで参照できるようになります。
|
||||
|
||||
<Note>
|
||||
テスト目的では、常にテスト Webhook URL を使用して、テストデータを本番データから分離してください。
|
||||
<img src="/images/test_webhook_url.png" alt="Test Webhook URL" width="563" />
|
||||
</Note>
|
||||
|
||||
<Tip>
|
||||
対象の外部システムに既製のトリガープラグインがある場合は、代わりに[プラグイントリガー](/ja-jp/guides/workflow/node/plugin-trigger)を使用することをお勧めします。
|
||||
</Tip>
|
||||
|
||||
## Webhook トリガーの追加
|
||||
|
||||
workflow キャンバスで右クリックし、**ブロックを追加** > **始める** > **Webhook トリガー**を選択します。
|
||||
|
||||
<Tip>
|
||||
1 つの workflow は、並行して実行される複数の Webhook トリガーで開始できます。並行分岐に同一の連続したノードが含まれている場合、共通セクションの前に[変数集約](/ja-jp/guides/workflow/node/variable-aggregator)ノードを追加して分岐をマージできます。これにより、各分岐で同じノードを個別に重複して追加することを回避できます。
|
||||
</Tip>
|
||||
|
||||
## Webhook トリガーの設定
|
||||
|
||||
Webhook トリガーが受信 HTTP リクエストを処理する方法を定義できます。以下が含まれます:
|
||||
|
||||
- Webhook URL が期待する HTTP メソッド
|
||||
|
||||
- リクエストのコンテンツタイプ
|
||||
|
||||
- リクエストから抽出したいデータ
|
||||
|
||||
- workflow が正常にトリガーされたときに外部システムに返送されるレスポンス
|
||||
|
||||
<Note>
|
||||
未公開の Webhook トリガーをテストするには、まず**このステップ実行**をクリックするか、workflow 全体をテスト実行する必要があります。これによりトリガーがリスニング状態になり、外部リクエストを受信できるようになります。そうしないと、リクエストはキャプチャされません。
|
||||
</Note>
|
||||
|
||||
### HTTP メソッド
|
||||
|
||||
受信リクエストが正常に受信されるようにするには、Webhook URL が受け入れる HTTP メソッドを指定する必要があります。
|
||||
|
||||
ここで選択するメソッドは、外部システムがリクエストを送信するときに使用するメソッドと一致する必要があります。そうしないと、リクエストは拒否されます。
|
||||
|
||||
<Tip>
|
||||
通常、この情報は外部システムの Webhook ドキュメントまたはセットアップインターフェースで確認できます。
|
||||
</Tip>
|
||||
|
||||
### コンテンツタイプ
|
||||
|
||||
リクエストボディを適切に解析し、必要なデータを抽出できるようにするには、受信リクエストの期待されるコンテンツタイプを指定する必要があります。
|
||||
|
||||
ここで選択するコンテンツタイプは、外部システムから送信されるリクエストのコンテンツタイプと一致する必要があります。そうしないと、リクエストは拒否されます。
|
||||
|
||||
### Query Parameters、Header Parameters、Request Body Parameters
|
||||
|
||||
受信リクエストの Query Parameters、Header Parameters、Request Body Parameters から特定のデータを抽出できます。**抽出された各パラメータは、workflow で使用できる出力変数になります**。
|
||||
|
||||
一部の外部システムは、各リクエストの配信ログを提供しており、リクエストに含まれるすべてのデータを表示し、どのパラメータを抽出するかを決定できます。
|
||||
|
||||
または、Webhook トリガーにテストリクエストを送信し、最後の実行ログで受信したリクエストデータを確認することもできます:
|
||||
|
||||
1. 提供されたテスト Webhook URL を使用して、外部システムで Webhook を作成します。
|
||||
|
||||
2. トリガーで正しい HTTP メソッドとコンテンツタイプを設定します。
|
||||
|
||||
3. **このステップ実行**アイコンをクリックします。トリガーは外部リクエストのリスニングを開始します。
|
||||
|
||||
4. 外部システムでサブスクライブしたイベントをトリガーして、提供された Webhook URL に HTTP リクエストを送信します。
|
||||
|
||||
5. トリガーの**最後の実行**タブに移動し、**入力**で受信したリクエストデータを確認します。
|
||||
|
||||
<Note>
|
||||
トリガーで定義する変数名は、リクエスト内の対応するパラメータのキー名と一致する必要があります。
|
||||
</Note>
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Query Parameters">
|
||||
|
||||
- 外部システムがリクエストを送信する際に Webhook URL(`?` の後)に追加するキーと値のペアのパラメータで、各ペアは `&` で区切られます。
|
||||
|
||||
- 通常、イベントに関する単純で機密性のない識別子またはフィルタデータです。
|
||||
|
||||
- 例:URL `{webhook url}?userID=u-456&source=email` から、`userID`(`u-456`)または `source`(`email`)を抽出できます。
|
||||
|
||||
</Tab>
|
||||
<Tab title="Header Parameters">
|
||||
|
||||
- リクエストヘッダーに含まれるリクエストメタデータ。
|
||||
|
||||
- 認証トークンやリクエストボディのデータ形式など、リクエストを処理するために必要な技術情報。
|
||||
|
||||
- 例:`Authorization: Bearer sk-abc...` や `Content-Type: application/json` などのヘッダーから、認証情報(`Bearer sk-abc...`)またはコンテンツタイプ(`application/json`)を抽出できます。
|
||||
|
||||
</Tab>
|
||||
<Tab title="Request Body Parameters">
|
||||
|
||||
- 顧客プロファイル、注文詳細、Slack メッセージの内容など、コアイベントデータが送信される主なペイロード。
|
||||
|
||||
- 例:次のリクエストボディから、`customerName`(`Alex`)、アイテムのリスト、または `isPriority` ステータス(`true`)を抽出できます。
|
||||
|
||||
```JSON
|
||||
"customerName": "Alex",
|
||||
"items":
|
||||
[
|
||||
{ "sku": "A42", "quantity": 2 },
|
||||
{ "sku": "B12", "quantity": 1 }
|
||||
],
|
||||
"isPriority": true
|
||||
```
|
||||
|
||||
<Info>
|
||||
コンテンツタイプは、リクエストボディから抽出できるデータ型を決定します。
|
||||
|
||||
| <div style={{width: '120px'}}>コンテンツタイプ</div> | `String` | `Number` | `Boolean` | `Object` | `File` | `Array[String]` | `Array[Number]` | `Array[Boolean]` | `Array[Object]` | `Array[File]` |
|
||||
|:--------------|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|
|
||||
| application/json | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ |
|
||||
| application/x-www-form-urlencoded | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ | ❌ | ❌ |
|
||||
| multipart/form-data | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ |
|
||||
| text/plain | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
||||
</Info>
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
**パラメータ設定**
|
||||
|
||||
抽出する各パラメータについて、次を指定できます:
|
||||
|
||||
- **変数名**: リクエスト内のパラメータのキー名(例:`userID=u-456` の `userID`)。
|
||||
|
||||
<Note>
|
||||
Header Parameters の場合、変数名内のハイフン(`-`)は、出力変数でアンダースコア(`_`)に自動的に変換されます。
|
||||
</Note>
|
||||
|
||||
- **タイプ**:期待されるデータ形式。Query Parameters と Request Body Parameters にのみ使用できます。Header Parameters は常に文字列として扱われます。
|
||||
|
||||
- **必須**:workflow が適切に実行されるためにパラメータが必要かどうか。受信リクエストに必須パラメータが欠落している場合、workflow はトリガーされません。
|
||||
|
||||
### レスポンス
|
||||
|
||||
デフォルトでは、受信リクエストによって workflow が正常にトリガーされると、外部システムに `200 OK` ステータスコードと次のレスポンスボディが返送されます:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"status":"success","message":"Webhook processed successfully"
|
||||
}
|
||||
```
|
||||
|
||||
外部システムが特定のレスポンス形式を必要とする場合、成功レスポンスのステータスコードとレスポンスボディをカスタマイズできます。デフォルトのレスポンスは上書きされます。
|
||||
|
||||
- **ステータスコード**:[200, 399] の範囲内の任意のステータスコードをサポートします。
|
||||
|
||||
- **レスポンスボディ**:JSON またはプレーンテキストをサポートします。
|
||||
|
||||
<Note>
|
||||
返されるレスポンスボディでは、非 JSON コンテンツは自動的に JSON に変換されます。
|
||||
|
||||
例えば、`OK` は `"message": "OK"` としてラップされます。
|
||||
</Note>
|
||||
|
||||
<Info>
|
||||
次のエラーレスポンスはシステム定義であり、カスタマイズできません。エラーの詳細はレスポンスボディで確認できます。
|
||||
- 400 Bad Request
|
||||
- 404 Not Found
|
||||
- 413 Payload Too Large
|
||||
- 500 Internal Server Error
|
||||
</Info>
|
||||
|
||||
## Webhook トリガーをテストする
|
||||
|
||||
未公開の Webhook トリガーをテストするには、まず**このステップ実行**をクリックするか、workflow 全体をテスト実行する必要があります。これによりトリガーがリスニング状態になり、外部リクエストを受信できるようになります。そうしないと、受信リクエストはキャプチャされません。
|
||||
|
||||
{/*
|
||||
Contributing Section
|
||||
DO NOT edit this section!
|
||||
It will be automatically generated by the script.
|
||||
*/}
|
||||
|
||||
---
|
||||
|
||||
[このページを編集する](https://github.com/langgenius/dify-docs/edit/main/ja-jp/guides/workflow/node/webhook-trigger.mdx) | [問題を報告する](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)
|
||||
|
||||
@@ -1,136 +1,45 @@
|
||||
---
|
||||
title: 変数
|
||||
---
|
||||
## 概要
|
||||
|
||||
**ワークフロー**や**チャットフロー**は、単独ノードで構成されています。多くのノードは入力と出力のアイテムを持っていますが、各ノードの入力および出力情報は一貫性がなく、ダイナミックに変化します。
|
||||
変数は、workflow または chatflow 内で情報を保存するためのラベル付きコンテナです。
|
||||
各変数は 1 つのデータを保持します。たとえば、ユーザー入力、システムが生成した値、または前のノードからの出力です。
|
||||
後でこの情報を使用する必要がある場合は、変数名を参照するだけで利用できます。
|
||||
|
||||
**固定のシンボルを用いて、ダイナミックなコンテンツをどのように参照するのでしょうか?** 変数はダイナミックなデータコンテナとして、さまざまな内容を格納・送信し、異なるノードの間で相互に参照され、お互いに情報を移動することができます。
|
||||
workflow や chatflow を構築する際には、アプリケーションのデータフロー内で特定の役割を果たす、いくつかの種類の変数を扱います。
|
||||
|
||||
## 変数の型
|
||||
## 変数の種類
|
||||
|
||||
### **システム変数**
|
||||
### システム変数
|
||||
|
||||
システム変数とは、チャットフロー/ワークフロー内でグローバルに使用される事前設定されたシステムレベルのパラメータです。すべてのシステムレベルの変数は`sys.`で始まります。
|
||||
システム変数は、あらかじめ設定されたシステムレベルのパラメーターで、グローバルに利用できます。
|
||||
|
||||
**ワークフロー**
|
||||
<Tabs>
|
||||
<Tab title="Workflow">
|
||||
|
||||
ワークフローは、以下のシステム変数を提供します:
|
||||
| 変数名 | <div style={{width: '90px'}}> データタイプ</div> | 说明 | メモ |
|
||||
|:----------------|:-----------|:-------------|:--------|
|
||||
| `sys.user_id` | String | ユーザーIDです。ワークフローアプリを使用する際、システムが自動的にユーザーに一意の識別子を割り当て、異なるユーザーを区別するために使用します。 | |
|
||||
| `sys.app_id` | String | アプリIDで、システムが各ワークフローアプリに一意の識別子を割り当て、異なるアプリを区別します。このパラメータは現在のアプリの基本情報を記録するために使用されます。 | 開発能力を持つユーザー向けで、このパラメータを使用して異なるワークフローアプリを区別し、特定できます。 |
|
||||
| `sys.workflow_id` | String | ワークフローIDで、現在のワークフローアプリに含まれるすべてのノード情報を記録するために使用されます。 | 開発能力を持つユーザー向けで、このパラメータを使用してワークフロー内のノード情報を追跡および記録できます。 |
|
||||
| `sys.workflow_run_id` | String | ワークフローアプリ実行IDで、ワークフローアプリ内の実行状況を記録するために使用されます。 | 開発能力を持つユーザー向けで、このパラメータを使用してアプリの過去の実行状況を追跡できます。 |
|
||||
| `sys.timestamp` | String | 各 workflow 実行の開始時刻。 | |
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="193">変数名</th>
|
||||
<th width="116">データタイプ</th>
|
||||
<th width="278">说明</th>
|
||||
<th>メモ</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><p><code>sys.files</code></p><p><code>[LEGACY]</code></p></td>
|
||||
<td>Array[File]</td>
|
||||
<td>ファイルパラメータで、ユーザーがアプリを初めて使用する際にアップロードした画像を保存します。</td>
|
||||
<td>画像のアップロード機能は、アプリケーションの編成ページ右上の「機能」から開始する必要があります。</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>sys.user_id</code></td>
|
||||
<td>String</td>
|
||||
<td>ユーザーIDです。ワークフローアプリを使用する際、システムが自動的にユーザーに一意の識別子を割り当て、異なるユーザーを区別するために使用します。</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>sys.app_id</code></td>
|
||||
<td>String</td>
|
||||
<td>アプリIDで、システムが各ワークフローアプリに一意の識別子を割り当て、異なるアプリを区別します。このパラメータは現在のアプリの基本情報を記録するために使用されます。</td>
|
||||
<td>開発能力を持つユーザー向けで、このパラメータを使用して異なるワークフローアプリを区別し、特定できます。</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>sys.workflow_id</code></td>
|
||||
<td>String</td>
|
||||
<td>ワークフローIDで、現在のワークフローアプリに含まれるすべてのノード情報を記録するために使用されます。</td>
|
||||
<td>開発能力を持つユーザー向けで、このパラメータを使用してワークフロー内のノード情報を追跡および記録できます。</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>sys.workflow_run_id</code></td>
|
||||
<td>String</td>
|
||||
<td>ワークフローアプリ実行IDで、ワークフローアプリ内の実行状況を記録するために使用されます。</td>
|
||||
<td>開発能力を持つユーザー向けで、このパラメータを使用してアプリの過去の実行状況を追跡できます。</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</Tab>
|
||||
<Tab title="Chatflow">
|
||||
|
||||
| 変数名 | <div style={{width: '90px'}}> データタイプ</div> | 说明 | メモ |
|
||||
|:----------------|:-----------|:-------------|:--------|
|
||||
| `sys.conversation_id` | String | 対話ボックスのインタラクションセッションの一意の識別子で、すべての関連メッセージを同じ対話にグループ化し、LLMが同じトピックとコンテキストに対して持続的な対話を行うことを確認します。 | |
|
||||
| `sys.dialogue_count` | Number | チャットフロー形式のアプリとの対話中にユーザーが持つ対話のラウンド数。各対話の後、自動的に1つのカウントが増加します。if-elseノードと組み合わせて豊富な分岐ロジックを作成できます。<br /><br />例えば、Xラウンド目に到達したとき、対話履歴を振り返り分析を提供します。| |
|
||||
| `sys.user_id` | String | 各アプリユーザーに割り当てられた一意の識別子で、異なる対話ユーザーを区別するために使用されます。 | Service API は WebApp で作成された対話を共有しません。つまり、同じ ID を持つユーザーでも、API と WebApp インターフェース間では独立した対話履歴を持ちます。 |
|
||||
| `sys.app_id` | String | アプリIDで、システムが各ワークフローアプリに一意の識別子を割り当て、異なるアプリを区別します。このパラメータは現在のアプリの基本情報を記録するために使用されます。 | 開発能力を持つユーザー向けで、このパラメータを使用して異なるワークフローアプリを区別し、特定できます。 |
|
||||
| `sys.workflow_id` | String | ワークフローIDで、現在のワークフローアプリ内に含まれるすべてのノード情報を記録するために使用されます。 | 開発能力を持つユーザー向けで、このパラメータを使用してワークフロー内のすべてのノード情報を追跡および記録できます。|
|
||||
| `sys.workflow_run_id` | String | ワークフローアプリケーションの実行IDで、ワークフローアプリケーション内の実行状況を記録するために使用されます。 | 開発能力を持つユーザー向けで、このパラメータを使用してアプリの過去の実行状況を追跡できます。 |
|
||||
|
||||
<Frame caption="ワークフロー内のシステム変数">
|
||||
<img src="https://assets-docs.dify.ai/dify-enterprise-mintlify/jp/guides/workflow/684db784d35f7b9771ea40bfda64822c.png" alt="" />
|
||||
</Frame>
|
||||
|
||||
**チャットフロー**
|
||||
|
||||
チャットフローは、以下のシステム変数を提供します:
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>変数名</th>
|
||||
<th width="127">データタイプ</th>
|
||||
<th width="283">説明</th>
|
||||
<th>メモ</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>sys.query</code></td>
|
||||
<td>String</td>
|
||||
<td>ユーザーが最初に入力したダイアログボックスの内容</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>sys.files</code></td>
|
||||
<td>Array[File]</td>
|
||||
<td>ユーザーがダイアログボックス内でアップロードした画像</td>
|
||||
<td>画像のアップロード機能は、アプリケーションの構築ページ右上隅の「機能」で有効にする必要があります</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>sys.dialogue_count</code></td>
|
||||
<td>Number</td>
|
||||
<td><p>チャットフロー形式のアプリとの対話中にユーザーが持つ対話のラウンド数。各対話の後、自動的に1つのカウントが増加します。if-elseノードと組み合わせて豊富な分岐ロジックを作成できます。</p><p>例えば、Xラウンド目に到達したとき、対話履歴を振り返り分析を提供します。</p></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>sys.conversation_id</code></td>
|
||||
<td>String</td>
|
||||
<td>対話ボックスのインタラクションセッションの一意の識別子で、すべての関連メッセージを同じ対話にグループ化し、LLMが同じトピックとコンテキストに対して持続的な対話を行うことを確認します。</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>sys.user_id</code></td>
|
||||
<td>String</td>
|
||||
<td>各アプリユーザーに割り当てられた一意の識別子で、異なる対話ユーザーを区別するために使用されます。<br /><br /><strong>注意</strong>:Service API は WebApp で作成された対話を共有しません。つまり、同じ ID を持つユーザーでも、API と WebApp インターフェース間では独立した対話履歴を持ちます。</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>sys.app_id</code></td>
|
||||
<td>String</td>
|
||||
<td>アプリIDで、システムは各ワークフローアプリケーションに一意の識別子を割り当て、異なるアプリを区別し、このパラメータを使用して現在のアプリの基本情報を記録します。</td>
|
||||
<td>開発能力を持つユーザー向けで、このパラメータを使用して異なるワークフローアプリを特定および位置付けることができます。</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>sys.workflow_id</code></td>
|
||||
<td>String</td>
|
||||
<td>ワークフローIDで、現在のワークフローアプリ内に含まれるすべてのノード情報を記録するために使用されます。</td>
|
||||
<td>開発能力を持つユーザー向けで、このパラメータを使用してワークフロー内のすべてのノード情報を追跡および記録できます。</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>sys.workflow_run_id</code></td>
|
||||
<td>String</td>
|
||||
<td>ワークフローアプリケーションの実行IDで、ワークフローアプリケーション内の実行状況を記録するために使用されます。</td>
|
||||
<td>開発能力を持つユーザー向けで、このパラメータを使用してアプリの過去の実行状況を追跡できます。</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<Frame caption="チャットフロー内のシステム変数">
|
||||
<img src="https://assets-docs.dify.ai/dify-enterprise-mintlify/jp/guides/workflow/79340d58bf2c202dd6bd4e93fa03272d.png" alt="chatflow app system variables" />
|
||||
</Frame>
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### 環境変数
|
||||
|
||||
|
||||
664
plugin-dev-en/0222-trigger-plugin.mdx
Normal file
@@ -0,0 +1,664 @@
|
||||
---
|
||||
title: "Trigger Plugin"
|
||||
---
|
||||
|
||||
## What Is a Trigger Plugin?
|
||||
|
||||
Triggers were introduced in Dify v1.10.0 as a new type of start node. Unlike functional nodes such as Code, Tool, or Knowledge Retrieval, the purpose of a trigger is to **convert third-party events into an input format that Dify can recognize and process**.
|
||||
|
||||

|
||||
|
||||
For example, if you configure Dify as the `new email` event receiver in Gmail, every time you receive a new email, Gmail automatically sends an event to Dify that can be used to trigger a workflow. However:
|
||||
|
||||
- Gmail's original event format is not compatible with Dify's input format.
|
||||
|
||||
- There are thousands of platforms worldwide, each with its own unique event format.
|
||||
|
||||
Therefore, we need trigger plugins to define and parse these events from different platforms and in various formats, and to unify them into an input format that Dify can accept.
|
||||
|
||||
## Technical Overview
|
||||
|
||||
Dify triggers are implemented based on webhooks, a widely adopted mechanism across the web. Many mainstream SaaS platforms (like GitHub, Slack, and Linear) support webhooks with comprehensive developer documentation.
|
||||
|
||||
A webhook can be understood as an HTTP-based event dispatcher. **Once an event-receiving address is configured, these SaaS platforms automatically push event data to the target server whenever a subscribed event occurs.**
|
||||
|
||||
To handle webhook events from different platforms in a unified way, Dify defines two core concepts: **Subscription** and **Event**.
|
||||
|
||||
- **Subscription**: Webhook-based event dispatch requires **registering Dify's network address on a third-party platform's developer console as the target server. In Dify, this configuration process is called a *Subscription*.**
|
||||
|
||||
- **Event**: A platform may send multiple types of events—such as *email received*, *email deleted*, or *email marked as read*—all of which are pushed to the registered address. A trigger plugin can handle multiple event types, with each event corresponding to a plugin trigger node in a Dify workflow.
|
||||
|
||||
## Plugin Development
|
||||
|
||||
The development process for a trigger plugin is consistent with that of other plugin types (Tool, Data Source, Model, etc.).
|
||||
|
||||
You can create a development template using the `dify plugin init` command. The generated file structure follows the standard plugin format specification.
|
||||
|
||||
```
|
||||
├── _assets
|
||||
│ └── icon.svg
|
||||
├── events
|
||||
│ └── star
|
||||
│ ├── star_created.py
|
||||
│ └── star_created.yaml
|
||||
├── main.py
|
||||
├── manifest.yaml
|
||||
├── provider
|
||||
│ ├── github.py
|
||||
│ └── github.yaml
|
||||
├── README.md
|
||||
├── PRIVACY.md
|
||||
└── requirements.txt
|
||||
```
|
||||
|
||||
- `manifest.yaml`: Describes the plugin's basic metadata.
|
||||
|
||||
- `provider` directory: Contains the provider's metadata, the code for creating subscriptions, and the code for classifying events after receiving webhook requests.
|
||||
|
||||
- **`events` directory: Contains the code for event handling and filtering, which supports local event filtering at the node level. You can create subdirectories to group related events.**
|
||||
|
||||
<Note>
|
||||
For trigger plugins, the minimum required Dify version must be set to `1.10.0`, and the SDK version must be `>= 0.6.0`.
|
||||
</Note>
|
||||
|
||||
Next, we'll use GitHub as an example to illustrate the development process of a trigger plugin.
|
||||
|
||||
### Subscription Creation
|
||||
|
||||
Webhook configuration methods vary significantly across mainstream SaaS platforms:
|
||||
|
||||
- Some platforms (such as GitHub) support API-based webhook configuration. For these platforms, once OAuth authentication is completed, Dify can automatically set up the webhook.
|
||||
|
||||
- Other platforms (such as Notion) do not provide a webhook configuration API and may require users to perform manual authentication.
|
||||
|
||||
To accommodate these differences, we divide the subscription process into two parts: the **Subscription Constructor** and the **Subscription** itself.
|
||||
|
||||
For platforms like Notion, creating a subscription requires the user to manually copy the callback URL provided by Dify and paste it into their Notion workspace to complete the webhook setup. This process corresponds to the **Paste URL to create a new subscription** option in the Dify interface.
|
||||
|
||||
<img src="/images/trigger_plugin_manual_webhook_setup.PNG" alt="Paste URL to Create a New Subscription" width="563" />
|
||||
|
||||
To implement subscription creation via manual URL pasting, you need to modify two files: `github.yaml` and `github.py`.
|
||||
|
||||
<Tabs>
|
||||
<Tab title="github.yaml">
|
||||
Since GitHub webhooks use an encryption mechanism, a secret key is required to decrypt and validate incoming requests. Therefore, you need to declare `webhook_secret` in `github.yaml`.
|
||||
|
||||
```YAML
|
||||
subscription_schema:
|
||||
- name: "webhook_secret"
|
||||
type: "secret-input"
|
||||
required: false
|
||||
label:
|
||||
zh_Hans: "Webhook Secret"
|
||||
en_US: "Webhook Secret"
|
||||
ja_JP: "Webhookシークレット"
|
||||
help:
|
||||
en_US: "Optional webhook secret for validating GitHub webhook requests"
|
||||
ja_JP: "GitHub Webhookリクエストの検証用のオプションのWebhookシークレット"
|
||||
zh_Hans: "可选的用于验证 GitHub webhook 请求的 webhook 密钥"
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="github.py">
|
||||
|
||||
First, we need to implement the `dispatch_event` interface. All requests sent to the callback URL are processed by this interface, and the processed events will be displayed in the **Request Logs** section for debugging and verification.
|
||||
|
||||
<img src="/images/trigger_plugin_manual_webhook_setup_config.PNG" alt="Manual Setup" width="500" />
|
||||
|
||||
In the code, you can retrieve the `webhook_secret` declared in `github.yaml` via `subscription.properties`.
|
||||
|
||||
The `dispatch_event` method needs to determine the event type based on the request content. In the example below, this event extraction is handled by the `_dispatch_trigger_event` method.
|
||||
|
||||
<Tip>
|
||||
For the complete code sample, see [Dify's GitHub trigger plugin](https://github.com/langgenius/dify-plugin-sdks/tree/feat/trigger/python/examples/github_trigger).
|
||||
</Tip>
|
||||
|
||||
```Python
|
||||
class GithubTrigger(Trigger):
|
||||
"""Handle GitHub webhook event dispatch."""
|
||||
|
||||
def _dispatch_event(self, subscription: Subscription, request: Request) -> EventDispatch:
|
||||
webhook_secret = subscription.properties.get("webhook_secret")
|
||||
if webhook_secret:
|
||||
self._validate_signature(request=request, webhook_secret=webhook_secret)
|
||||
|
||||
event_type: str | None = request.headers.get("X-GitHub-Event")
|
||||
if not event_type:
|
||||
raise TriggerDispatchError("Missing GitHub event type header")
|
||||
|
||||
payload: Mapping[str, Any] = self._validate_payload(request)
|
||||
response = Response(response='{"status": "ok"}', status=200, mimetype="application/json")
|
||||
event: str = self._dispatch_trigger_event(event_type=event_type, payload=payload)
|
||||
return EventDispatch(events=[event] if event else [], response=response)
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### Event Handling
|
||||
|
||||
Once an event is extracted, the corresponding implementation must filter the original HTTP request and transform it into an input format that Dify workflows can accept.
|
||||
|
||||
Taking the Issue event as an example, you can define the event and its implementation through `events/issues/issues.yaml` and `events/issues/issues.py`, respectively. The event's output can be defined in the `output_schema` section of `issues.yaml`, which follows the same JSON Schema specification as tool plugins.
|
||||
|
||||
<Tabs>
|
||||
<Tab title="issues.yaml">
|
||||
```YAML
|
||||
identity:
|
||||
name: issues
|
||||
author: langgenius
|
||||
label:
|
||||
en_US: Issues
|
||||
zh_Hans: 议题
|
||||
ja_JP: イシュー
|
||||
description:
|
||||
en_US: Unified issues event with actions filter
|
||||
zh_Hans: 带 actions 过滤的统一 issues 事件
|
||||
ja_JP: アクションフィルタ付きの統合イシューイベント
|
||||
output_schema:
|
||||
type: object
|
||||
properties:
|
||||
action:
|
||||
type: string
|
||||
issue:
|
||||
type: object
|
||||
description: The issue itself
|
||||
extra:
|
||||
python:
|
||||
source: events/issues/issues.py
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="issues.py">
|
||||
```Python
|
||||
from collections.abc import Mapping
|
||||
from typing import Any
|
||||
|
||||
from werkzeug import Request
|
||||
|
||||
from dify_plugin.entities.trigger import Variables
|
||||
from dify_plugin.errors.trigger import EventIgnoreError
|
||||
from dify_plugin.interfaces.trigger import Event
|
||||
|
||||
class IssuesUnifiedEvent(Event):
|
||||
"""Unified Issues event. Filters by actions and common issue attributes."""
|
||||
|
||||
def _on_event(self, request: Request, parameters: Mapping[str, Any], payload: Mapping[str, Any]) -> Variables:
|
||||
payload = request.get_json()
|
||||
if not payload:
|
||||
raise ValueError("No payload received")
|
||||
|
||||
allowed_actions = parameters.get("actions") or []
|
||||
action = payload.get("action")
|
||||
if allowed_actions and action not in allowed_actions:
|
||||
raise EventIgnoreError()
|
||||
|
||||
issue = payload.get("issue")
|
||||
if not isinstance(issue, Mapping):
|
||||
raise ValueError("No issue in payload")
|
||||
|
||||
return Variables(variables={**payload})
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### Event Filtering
|
||||
|
||||
To filter out certain events—for example, to focus only on Issue events with a specific label—you can add `parameters` to the event definition in `issues.yaml`. Then, in the `_on_event` method, you can throw an `EventIgnoreError` exception to filter out events that do not meet the configured criteria.
|
||||
|
||||
<Tabs>
|
||||
<Tab title="issues.yaml">
|
||||
```YAML
|
||||
parameters:
|
||||
- name: added_label
|
||||
label:
|
||||
en_US: Added Label
|
||||
zh_Hans: 添加的标签
|
||||
ja_JP: 追加されたラベル
|
||||
type: string
|
||||
required: false
|
||||
description:
|
||||
en_US: "Only trigger if these specific labels were added (e.g., critical, priority-high, security, comma-separated). Leave empty to trigger for any label addition."
|
||||
zh_Hans: "仅当添加了这些特定标签时触发(例如:critical, priority-high, security,逗号分隔)。留空则对任何标签添加触发。"
|
||||
ja_JP: "これらの特定のラベルが追加された場合のみトリガー(例: critical, priority-high, security,カンマ区切り)。空の場合は任意のラベル追加でトリガー。"
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="issues.py">
|
||||
```Python
|
||||
def _check_added_label(self, payload: Mapping[str, Any], added_label_param: str | None) -> None:
|
||||
"""Check if the added label matches the allowed labels"""
|
||||
if not added_label_param:
|
||||
return
|
||||
|
||||
allowed_labels = [label.strip() for label in added_label_param.split(",") if label.strip()]
|
||||
if not allowed_labels:
|
||||
return
|
||||
|
||||
# The payload contains the label that was added
|
||||
label = payload.get("label", {})
|
||||
label_name = label.get("name", "")
|
||||
|
||||
if label_name not in allowed_labels:
|
||||
raise EventIgnoreError()
|
||||
|
||||
def _on_event(self, request: Request, parameters: Mapping[str, Any], payload: Mapping[str, Any]) -> Variables:
|
||||
# ...
|
||||
# Apply all filters
|
||||
self._check_added_label(payload, parameters.get("added_label"))
|
||||
|
||||
return Variables(variables={**payload})
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### Subscription Creation via OAuth or API Key
|
||||
|
||||
To enable automatic subscription creation via OAuth or API key, you need to modify the `github.yaml` and `github.py` files.
|
||||
|
||||
<Tabs>
|
||||
<Tab title="github.yaml">
|
||||
In `github.yaml`, add the following fields.
|
||||
|
||||
```YAML
|
||||
subscription_constructor:
|
||||
parameters:
|
||||
- name: "repository"
|
||||
label:
|
||||
en_US: "Repository"
|
||||
zh_Hans: "仓库"
|
||||
ja_JP: "リポジトリ"
|
||||
type: "dynamic-select"
|
||||
required: true
|
||||
placeholder:
|
||||
en_US: "owner/repo"
|
||||
zh_Hans: "owner/repo"
|
||||
ja_JP: "owner/repo"
|
||||
help:
|
||||
en_US: "GitHub repository in format owner/repo (e.g., microsoft/vscode)"
|
||||
zh_Hans: "GitHub 仓库,格式为 owner/repo(例如:microsoft/vscode)"
|
||||
ja_JP: "GitHubリポジトリは owner/repo 形式で入力してください(例: microsoft/vscode)"
|
||||
credentials_schema:
|
||||
access_tokens:
|
||||
help:
|
||||
en_US: Get your Access Tokens from GitHub
|
||||
ja_JP: GitHub からアクセストークンを取得してください
|
||||
zh_Hans: 从 GitHub 获取您的 Access Tokens
|
||||
label:
|
||||
en_US: Access Tokens
|
||||
ja_JP: アクセストークン
|
||||
zh_Hans: Access Tokens
|
||||
placeholder:
|
||||
en_US: Please input your GitHub Access Tokens
|
||||
ja_JP: GitHub のアクセストークンを入力してください
|
||||
zh_Hans: 请输入你的 GitHub Access Tokens
|
||||
required: true
|
||||
type: secret-input
|
||||
url: https://github.com/settings/tokens?type=beta
|
||||
extra:
|
||||
python:
|
||||
source: provider/github.py
|
||||
```
|
||||
|
||||
`subscription_constructor` is a concept abstracted by Dify to define how a subscription is constructed. It includes the following fields:
|
||||
|
||||
- `parameters` (optional): Defines the parameters required to create a subscription, such as the event types to subscribe to or the target GitHub repository
|
||||
|
||||
- `credentials_schema` (optional): Declares the required credentials for creating a subscription with an API key or access token, such as `access_tokens` for GitHub.
|
||||
|
||||
- `oauth_schema` (optional): Required for implementing subscription creation via OAuth. For details on how to define it, see [Add OAuth Support to Your Tool Plugin](/plugin-dev-en/0222-tool-oauth).
|
||||
</Tab>
|
||||
<Tab title="github.py">
|
||||
In `github.py`, create a `Constructor` class to implement the automatic subscription logic.
|
||||
|
||||
```Python
|
||||
class GithubSubscriptionConstructor(TriggerSubscriptionConstructor):
|
||||
"""Manage GitHub trigger subscriptions."""
|
||||
def _validate_api_key(self, credentials: Mapping[str, Any]) -> None:
|
||||
# ...
|
||||
|
||||
def _create_subscription(
|
||||
self,
|
||||
endpoint: str,
|
||||
parameters: Mapping[str, Any],
|
||||
credentials: Mapping[str, Any],
|
||||
credential_type: CredentialType,
|
||||
) -> Subscription:
|
||||
repository = parameters.get("repository")
|
||||
if not repository:
|
||||
raise ValueError("repository is required (format: owner/repo)")
|
||||
|
||||
try:
|
||||
owner, repo = repository.split("/")
|
||||
except ValueError:
|
||||
raise ValueError("repository must be in format 'owner/repo'") from None
|
||||
|
||||
events: list[str] = parameters.get("events", [])
|
||||
webhook_secret = uuid.uuid4().hex
|
||||
url = f"https://api.github.com/repos/{owner}/{repo}/hooks"
|
||||
headers = {
|
||||
"Authorization": f"Bearer {credentials.get('access_tokens')}",
|
||||
"Accept": "application/vnd.github+json",
|
||||
}
|
||||
|
||||
webhook_data = {
|
||||
"name": "web",
|
||||
"active": True,
|
||||
"events": events,
|
||||
"config": {"url": endpoint, "content_type": "json", "insecure_ssl": "0", "secret": webhook_secret},
|
||||
}
|
||||
|
||||
try:
|
||||
response = requests.post(url, json=webhook_data, headers=headers, timeout=10)
|
||||
except requests.RequestException as exc:
|
||||
raise SubscriptionError(f"Network error while creating webhook: {exc}", error_code="NETWORK_ERROR") from exc
|
||||
|
||||
if response.status_code == 201:
|
||||
webhook = response.json()
|
||||
return Subscription(
|
||||
expires_at=int(time.time()) + self._WEBHOOK_TTL,
|
||||
endpoint=endpoint,
|
||||
parameters=parameters,
|
||||
properties={
|
||||
"external_id": str(webhook["id"]),
|
||||
"repository": repository,
|
||||
"events": events,
|
||||
"webhook_secret": webhook_secret,
|
||||
"active": webhook.get("active", True),
|
||||
},
|
||||
)
|
||||
|
||||
response_data: dict[str, Any] = response.json() if response.content else {}
|
||||
error_msg = response_data.get("message", "Unknown error")
|
||||
error_details = response_data.get("errors", [])
|
||||
detailed_error = f"Failed to create GitHub webhook: {error_msg}"
|
||||
if error_details:
|
||||
detailed_error += f" Details: {error_details}"
|
||||
|
||||
raise SubscriptionError(
|
||||
detailed_error,
|
||||
error_code="WEBHOOK_CREATION_FAILED",
|
||||
external_response=response_data,
|
||||
)
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
---
|
||||
|
||||
Once you have modified these two files, you'll see the **Create with API Key** option in the Dify interface.
|
||||
|
||||
Automatic subscription creation via OAuth can also be implemented in the same `Constructor` class: by adding an `oauth_schema` field under `subscription_constructor`, you can enable OAuth authentication.
|
||||
|
||||
<img src="/images/trigger_plugin_oauth_apikey.png" alt="OAuth & API Key Options" width="563" />
|
||||
|
||||
## Explore More
|
||||
|
||||
The interface definitions and implementation methods of core classes in trigger plugin development are as follows.
|
||||
|
||||
### Trigger
|
||||
|
||||
```Python
|
||||
class Trigger(ABC):
|
||||
@abstractmethod
|
||||
def _dispatch_event(self, subscription: Subscription, request: Request) -> EventDispatch:
|
||||
"""
|
||||
Internal method to implement event dispatch logic.
|
||||
|
||||
Subclasses must override this method to handle incoming webhook events.
|
||||
|
||||
Implementation checklist:
|
||||
1. Validate the webhook request:
|
||||
- Check signature/HMAC using properties when you create the subscription from subscription.properties
|
||||
- Verify request is from expected source
|
||||
2. Extract event information:
|
||||
- Parse event type from headers or body
|
||||
- Extract relevant payload data
|
||||
3. Return EventDispatch with:
|
||||
- events: List of Event names to invoke (can be single or multiple)
|
||||
- response: Appropriate HTTP response for the webhook
|
||||
|
||||
Args:
|
||||
subscription: The Subscription object with endpoint and properties fields
|
||||
request: Incoming webhook HTTP request
|
||||
|
||||
Returns:
|
||||
EventDispatch: Event dispatch routing information
|
||||
|
||||
Raises:
|
||||
TriggerValidationError: For security validation failures
|
||||
TriggerDispatchError: For parsing or routing errors
|
||||
"""
|
||||
raise NotImplementedError("This plugin should implement `_dispatch_event` method to enable event dispatch")
|
||||
|
||||
```
|
||||
|
||||
### TriggerSubscriptionConstructor
|
||||
|
||||
```Python
|
||||
class TriggerSubscriptionConstructor(ABC, OAuthProviderProtocol):
|
||||
# OPTIONAL
|
||||
def _validate_api_key(self, credentials: Mapping[str, Any]) -> None:
|
||||
raise NotImplementedError(
|
||||
"This plugin should implement `_validate_api_key` method to enable credentials validation"
|
||||
)
|
||||
|
||||
# OPTIONAL
|
||||
def _oauth_get_authorization_url(self, redirect_uri: str, system_credentials: Mapping[str, Any]) -> str:
|
||||
raise NotImplementedError(
|
||||
"The trigger you are using does not support OAuth, please implement `_oauth_get_authorization_url` method"
|
||||
)
|
||||
|
||||
# OPTIONAL
|
||||
def _oauth_get_credentials(
|
||||
self, redirect_uri: str, system_credentials: Mapping[str, Any], request: Request
|
||||
) -> TriggerOAuthCredentials:
|
||||
raise NotImplementedError(
|
||||
"The trigger you are using does not support OAuth, please implement `_oauth_get_credentials` method"
|
||||
)
|
||||
|
||||
# OPTIONAL
|
||||
def _oauth_refresh_credentials(
|
||||
self, redirect_uri: str, system_credentials: Mapping[str, Any], credentials: Mapping[str, Any]
|
||||
) -> OAuthCredentials:
|
||||
raise NotImplementedError(
|
||||
"The trigger you are using does not support OAuth, please implement `_oauth_refresh_credentials` method"
|
||||
)
|
||||
|
||||
@abstractmethod
|
||||
def _create_subscription(
|
||||
self,
|
||||
endpoint: str,
|
||||
parameters: Mapping[str, Any],
|
||||
credentials: Mapping[str, Any],
|
||||
credential_type: CredentialType,
|
||||
) -> Subscription:
|
||||
"""
|
||||
Internal method to implement subscription logic.
|
||||
|
||||
Subclasses must override this method to handle subscription creation.
|
||||
|
||||
Implementation checklist:
|
||||
1. Use the endpoint parameter provided by Dify
|
||||
2. Register webhook with external service using their API
|
||||
3. Store all necessary information in Subscription.properties for future operations(e.g., dispatch_event)
|
||||
4. Return Subscription with:
|
||||
- expires_at: Set appropriate expiration time
|
||||
- endpoint: The webhook endpoint URL allocated by Dify for receiving events, same with the endpoint parameter
|
||||
- parameters: The parameters of the subscription
|
||||
- properties: All configuration and external IDs
|
||||
|
||||
Args:
|
||||
endpoint: The webhook endpoint URL allocated by Dify for receiving events
|
||||
parameters: Subscription creation parameters
|
||||
credentials: Authentication credentials
|
||||
credential_type: The type of the credentials, e.g., "api-key", "oauth2", "unauthorized"
|
||||
|
||||
Returns:
|
||||
Subscription: Subscription details with metadata for future operations
|
||||
|
||||
Raises:
|
||||
SubscriptionError: For operational failures (API errors, invalid credentials)
|
||||
ValueError: For programming errors (missing required params)
|
||||
"""
|
||||
raise NotImplementedError(
|
||||
"This plugin should implement `_create_subscription` method to enable event subscription"
|
||||
)
|
||||
|
||||
@abstractmethod
|
||||
def _delete_subscription(
|
||||
self, subscription: Subscription, credentials: Mapping[str, Any], credential_type: CredentialType
|
||||
) -> UnsubscribeResult:
|
||||
"""
|
||||
Internal method to implement unsubscription logic.
|
||||
|
||||
Subclasses must override this method to handle subscription removal.
|
||||
|
||||
Implementation guidelines:
|
||||
1. Extract necessary IDs from subscription.properties (e.g., external_id)
|
||||
2. Use credentials and credential_type to call external service API to delete the webhook
|
||||
3. Handle common errors (not found, unauthorized, etc.)
|
||||
4. Always return UnsubscribeResult with detailed status
|
||||
5. Never raise exceptions for operational failures - use UnsubscribeResult.success=False
|
||||
|
||||
Args:
|
||||
subscription: The Subscription object with endpoint and properties fields
|
||||
|
||||
Returns:
|
||||
UnsubscribeResult: Always returns result, never raises for operational failures
|
||||
"""
|
||||
raise NotImplementedError(
|
||||
"This plugin should implement `_delete_subscription` method to enable event unsubscription"
|
||||
)
|
||||
|
||||
@abstractmethod
|
||||
def _refresh_subscription(
|
||||
self, subscription: Subscription, credentials: Mapping[str, Any], credential_type: CredentialType
|
||||
) -> Subscription:
|
||||
"""
|
||||
Internal method to implement subscription refresh logic.
|
||||
|
||||
Subclasses must override this method to handle simple expiration extension.
|
||||
|
||||
Implementation patterns:
|
||||
1. For webhooks without expiration (e.g., GitHub):
|
||||
- Update the Subscription.expires_at=-1 then Dify will never call this method again
|
||||
|
||||
2. For lease-based subscriptions (e.g., Microsoft Graph):
|
||||
- Use the information in Subscription.properties to call service's lease renewal API if available
|
||||
- Handle renewal limits (some services limit renewal count)
|
||||
- Update the Subscription.properties and Subscription.expires_at for next time renewal if needed
|
||||
|
||||
Args:
|
||||
subscription: Current subscription with properties
|
||||
credential_type: The type of the credentials, e.g., "api-key", "oauth2", "unauthorized"
|
||||
credentials: Current authentication credentials from credentials_schema.
|
||||
For API key auth, according to `credentials_schema` defined in the YAML.
|
||||
For OAuth auth, according to `oauth_schema.credentials_schema` defined in the YAML.
|
||||
For unauthorized auth, there is no credentials.
|
||||
|
||||
Returns:
|
||||
Subscription: Same subscription with extended expiration
|
||||
or new properties and expires_at for next time renewal
|
||||
|
||||
Raises:
|
||||
SubscriptionError: For operational failures (API errors, invalid credentials)
|
||||
"""
|
||||
raise NotImplementedError("This plugin should implement `_refresh` method to enable subscription refresh")
|
||||
|
||||
# OPTIONAL
|
||||
def _fetch_parameter_options(
|
||||
self, parameter: str, credentials: Mapping[str, Any], credential_type: CredentialType
|
||||
) -> list[ParameterOption]:
|
||||
"""
|
||||
Fetch the parameter options of the trigger.
|
||||
|
||||
Implementation guidelines:
|
||||
When you need to fetch parameter options from an external service, use the credentials
|
||||
and credential_type to call the external service API, then return the options to Dify
|
||||
for user selection.
|
||||
|
||||
Args:
|
||||
parameter: The parameter name for which to fetch options
|
||||
credentials: Authentication credentials for the external service
|
||||
credential_type: The type of credentials (e.g., "api-key", "oauth2", "unauthorized")
|
||||
|
||||
Returns:
|
||||
list[ParameterOption]: A list of available options for the parameter
|
||||
|
||||
Examples:
|
||||
GitHub Repositories:
|
||||
>>> result = provider.fetch_parameter_options(parameter="repository")
|
||||
>>> print(result) # [ParameterOption(label="owner/repo", value="owner/repo")]
|
||||
|
||||
Slack Channels:
|
||||
>>> result = provider.fetch_parameter_options(parameter="channel")
|
||||
>>> print(result)
|
||||
```
|
||||
|
||||
### Event
|
||||
|
||||
```Python
|
||||
class Event(ABC):
|
||||
@abstractmethod
|
||||
def _on_event(self, request: Request, parameters: Mapping[str, Any], payload: Mapping[str, Any]) -> Variables:
|
||||
"""
|
||||
Transform the incoming webhook request into structured Variables.
|
||||
|
||||
This method should:
|
||||
1. Parse the webhook payload from the request
|
||||
2. Apply filtering logic based on parameters
|
||||
3. Extract relevant data matching the output_schema
|
||||
4. Return a structured Variables object
|
||||
|
||||
Args:
|
||||
request: The incoming webhook HTTP request containing the raw payload.
|
||||
Use request.get_json() to parse JSON body.
|
||||
parameters: User-configured parameters for filtering and transformation
|
||||
(e.g., label filters, regex patterns, threshold values).
|
||||
These come from the subscription configuration.
|
||||
payload: The decoded payload from previous step `Trigger.dispatch_event`.
|
||||
It will be delivered into `_on_event` method.
|
||||
Returns:
|
||||
Variables: Structured variables matching the output_schema
|
||||
defined in the event's YAML configuration.
|
||||
|
||||
Raises:
|
||||
EventIgnoreError: When the event should be filtered out based on parameters
|
||||
ValueError: When the payload is invalid or missing required fields
|
||||
|
||||
Example:
|
||||
>>> def _on_event(self, request, parameters):
|
||||
... payload = request.get_json()
|
||||
...
|
||||
... # Apply filters
|
||||
... if not self._matches_filters(payload, parameters):
|
||||
... raise EventIgnoreError()
|
||||
...
|
||||
... # Transform data
|
||||
... return Variables(variables={
|
||||
... "title": payload["issue"]["title"],
|
||||
... "author": payload["issue"]["user"]["login"],
|
||||
... "url": payload["issue"]["html_url"],
|
||||
... })
|
||||
"""
|
||||
|
||||
def _fetch_parameter_options(self, parameter: str) -> list[ParameterOption]:
|
||||
"""
|
||||
Fetch the parameter options of the trigger.
|
||||
|
||||
To be implemented by subclasses.
|
||||
|
||||
Also, it's optional to implement, that's why it's not an abstract method.
|
||||
"""
|
||||
raise NotImplementedError(
|
||||
"This plugin should implement `_fetch_parameter_options` method to enable dynamic select parameter"
|
||||
)
|
||||
```
|
||||
|
||||
{/*
|
||||
Contributing Section
|
||||
DO NOT edit this section!
|
||||
It will be automatically generated by the script.
|
||||
*/}
|
||||
|
||||
---
|
||||
|
||||
[Edit this page](https://github.com/langgenius/dify-docs/edit/main/plugin-dev-en/0222-trigger-plugin.mdx) | [Report an issue](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)
|
||||
|
||||
666
plugin-dev-ja/0222-trigger-plugin.mdx
Normal file
@@ -0,0 +1,666 @@
|
||||
---
|
||||
title: "トリガープラグイン"
|
||||
---
|
||||
|
||||
## トリガープラグインとは?
|
||||
|
||||
トリガー(Trigger) は、Dify v1.10.0で導入された新しいタイプの開始ノードです。Code、Tool、Knowledge Retrievalなどの機能的なノードとは異なり、トリガーの目的は、**サードパーティのイベントをDifyが認識・処理できる入力形式に変換する**ことです。
|
||||
|
||||

|
||||
|
||||
例えば、Gmailの`new email`イベントの受信先としてDifyを設定すると、新しいメールを受信するたびに、Gmailはワークフローを起動するためのイベントをDifyに自動的に送信します。しかし、これには課題があります。
|
||||
|
||||
- Gmailの元のイベント形式は、Difyの入力形式と互換性がありません。
|
||||
|
||||
- 世界中には何千ものプラットフォームが存在し、それぞれが独自のイベント形式を持っています。
|
||||
|
||||
そのため、さまざまなプラットフォームや形式から送られてくるこれらのイベントを定義・解析し、Difyが受け入れられる統一された入力形式に変換するために、トリガープラグインが必要となります。
|
||||
|
||||
## 技術概要
|
||||
|
||||
Difyのトリガーは、Webで広く採用されているメカニズムである**Webhook**に基づいて実装されています。多くの主流SaaSプラットフォーム(GitHub、Slack、Linearなど)は、包括的な開発者向けドキュメントと共にWebhookをサポートしています。
|
||||
|
||||
Webhookは、HTTPベースのイベントディスパッチャと理解することができます。**イベント受信アドレスを設定すると、これらのSaaSプラットフォームは、登録したイベントが発生するたびに、ターゲットサーバーにイベントデータを自動的にプッシュします。**
|
||||
|
||||
異なるプラットフォームからのWebhookイベントを統一的に処理するために、Difyは**サブスクリプション (Subscription)** と **イベント (Event)** という2つのコアコンセプトを定義しています。
|
||||
|
||||
- **サブスクリプション**: Webhookベースのイベントディスパッチでは、**サードパーティプラットフォームの開発者コンソールでDifyのネットワークアドレスをターゲットサーバーとして登録する必要があります。Difyでは、この設定プロセスをサブスクリプションと呼びます。**
|
||||
|
||||
- **イベント**: プラットフォームは、*メール受信*、*メール削除*、*メール既読*など、複数のタイプのイベントを送信することがあり、これらはすべて登録されたアドレスにプッシュされます。トリガープラグインは複数のイベントタイプを処理でき、各イベントがDifyワークフロー内のプラグイントリガーノードに対応します。
|
||||
|
||||
## プラグイン開発
|
||||
|
||||
トリガープラグインの開発プロセスは、他のプラグインタイプ(Tool、Data Source、Modelなど)と一貫しています。
|
||||
|
||||
`dify plugin init`コマンドを使用して開発テンプレートを作成できます。生成されるファイル構造は、標準のプラグイン形式仕様に準拠しています。
|
||||
|
||||
```
|
||||
├── _assets
|
||||
│ └── icon.svg
|
||||
├── events
|
||||
│ └── star
|
||||
│ ├── star_created.py
|
||||
│ └── star_created.yaml
|
||||
├── main.py
|
||||
├── manifest.yaml
|
||||
├── provider
|
||||
│ ├── github.py
|
||||
│ └── github.yaml
|
||||
├── README.md
|
||||
├── PRIVACY.md
|
||||
└── requirements.txt
|
||||
```
|
||||
|
||||
- `manifest.yaml`: プラグインの基本的なメタデータを記述します。
|
||||
|
||||
- `provider` ディレクトリ: プロバイダーのメタデータ、購読を作成するためのコード、Webhookリクエスト受信後にイベントを分類するためのコードが含まれます。
|
||||
|
||||
- **`events` ディレクトリ: イベント処理とフィルタリングのコードが含まれ、ノードレベルでのローカルイベントフィルタリングをサポートします。関連するイベントをグループ化するためにサブディレクトリを作成できます。**
|
||||
|
||||
<Note>
|
||||
トリガープラグインの場合、要求されるDifyの最小バージョンは`1.10.0`、SDKバージョンは`>= 0.6.0`に設定する必要があります。
|
||||
</Note>
|
||||
|
||||
次に、GitHubを例として、トリガープラグインの開発プロセスを説明します。
|
||||
|
||||
### Subscription(購読)の作成
|
||||
|
||||
Webhookの設定方法は、主流のSaaSプラットフォーム間で大きく異なります。
|
||||
|
||||
- 一部のプラットフォーム(GitHubなど)は、APIベースのWebhook設定をサポートしています。これらのプラットフォームでは、OAuth認証が完了すると、Difyが自動的にWebhookをセットアップできます。
|
||||
|
||||
- 他のプラットフォーム(Notionなど)は、Webhook設定APIを提供しておらず、ユーザーによる手動認証が必要な場合があります。
|
||||
|
||||
これらの違いに対応するため、サブスクリプションのプロセスを**サブスクリプションコンストラクタ (Subscription Constructor)** と **サブスクリプション (Subscription)** 自体の2つの部分に分けます。
|
||||
|
||||
Notionのようなプラットフォームでは、サブスクリプションを作成するために、ユーザーがDifyから提供されたコールバックURLを手動でコピーし、Notionワークスペースに貼り付けてWebhook設定を完了させる必要があります。このプロセスは、Difyインターフェースの**URLを貼り付けて新しいサブスクリプションを作成**オプションに対応します。
|
||||
|
||||
<img src="/images/trigger_plugin_manual_webhook_setup.PNG" alt="URLを貼り付けて新しいサブスクリプションを作成" width="563" />
|
||||
|
||||
手動でのURL貼り付けによるサブスクリプション作成を実装するには、`github.yaml`と`github.py`の2つのファイルを変更する必要があります。
|
||||
|
||||
<Tabs>
|
||||
<Tab title="github.yaml">
|
||||
|
||||
GitHubのWebhookは暗号化メカニズムを使用しているため、受信リクエストを復号化して検証するにはシークレットキーが必要です。そのため、`github.yaml`で`webhook_secret`を宣言する必要があります。
|
||||
|
||||
```YAML
|
||||
subscription_schema:
|
||||
- name: "webhook_secret"
|
||||
type: "secret-input"
|
||||
required: false
|
||||
label:
|
||||
zh_Hans: "Webhook Secret"
|
||||
en_US: "Webhook Secret"
|
||||
ja_JP: "Webhookシークレット"
|
||||
help:
|
||||
en_US: "Optional webhook secret for validating GitHub webhook requests"
|
||||
ja_JP: "GitHub Webhookリクエストの検証用のオプションのWebhookシークレット"
|
||||
zh_Hans: "可选的用于验证 GitHub webhook 请求的 webhook 密钥"
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="github.py">
|
||||
|
||||
まず、`dispatch_event`インターフェースを実装する必要があります。コールバックURLに送信されるすべてのリクエストはこのインターフェースによって処理され、処理されたイベントはデバッグと検証のために**リクエストログ**セクションに表示されます。
|
||||
|
||||
<img src="/images/trigger_plugin_manual_webhook_setup_config.PNG" alt="手動セットアップ" width="500" />
|
||||
|
||||
コード内では、`github.yaml`で宣言された`webhook_secret`を`subscription.properties`経由で取得できます。
|
||||
|
||||
`dispatch_event`メソッドは、リクエストの内容に基づいてイベントタイプを決定する必要があります。以下の例では、このイベント抽出は`_dispatch_trigger_event`メソッドによって処理されます。
|
||||
|
||||
<Tip>
|
||||
完全なコードサンプルについては、[DifyのGitHubトリガープラグイン](https://github.com/langgenius/dify-plugin-sdks/tree/feat/trigger/python/examples/github_trigger)を参照してください。
|
||||
</Tip>
|
||||
|
||||
```Python
|
||||
class GithubTrigger(Trigger):
|
||||
"""Handle GitHub webhook event dispatch."""
|
||||
|
||||
def _dispatch_event(self, subscription: Subscription, request: Request) -> EventDispatch:
|
||||
webhook_secret = subscription.properties.get("webhook_secret")
|
||||
if webhook_secret:
|
||||
self._validate_signature(request=request, webhook_secret=webhook_secret)
|
||||
|
||||
event_type: str | None = request.headers.get("X-GitHub-Event")
|
||||
if not event_type:
|
||||
raise TriggerDispatchError("Missing GitHub event type header")
|
||||
|
||||
payload: Mapping[str, Any] = self._validate_payload(request)
|
||||
response = Response(response='{"status": "ok"}', status=200, mimetype="application/json")
|
||||
event: str = self._dispatch_trigger_event(event_type=event_type, payload=payload)
|
||||
return EventDispatch(events=[event] if event else [], response=response)
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### イベント処理
|
||||
|
||||
イベントが抽出されると、対応する実装は元のHTTPリクエストをフィルタリングし、Difyワークフローが受け入れ可能な入力形式に変換する必要があります。
|
||||
|
||||
Issueイベントを例にとると、`events/issues/issues.yaml`と`events/issues/issues.py`を通じてイベントとその実装を定義できます。イベントの出力は`issues.yaml`の`output_schema`セクションで定義でき、これはツールプラグインと同じくJSON Schema仕様に従います。
|
||||
|
||||
<Tabs>
|
||||
<Tab title="issues.yaml">
|
||||
```YAML
|
||||
identity:
|
||||
name: issues
|
||||
author: langgenius
|
||||
label:
|
||||
en_US: Issues
|
||||
zh_Hans: 议题
|
||||
ja_JP: イシュー
|
||||
description:
|
||||
en_US: Unified issues event with actions filter
|
||||
zh_Hans: 带 actions 过滤的统一 issues 事件
|
||||
ja_JP: アクションフィルタ付きの統合イシューイベント
|
||||
output_schema:
|
||||
type: object
|
||||
properties:
|
||||
action:
|
||||
type: string
|
||||
issue:
|
||||
type: object
|
||||
description: The issue itself
|
||||
extra:
|
||||
python:
|
||||
source: events/issues/issues.py
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="issues.py">
|
||||
```Python
|
||||
from collections.abc import Mapping
|
||||
from typing import Any
|
||||
|
||||
from werkzeug import Request
|
||||
|
||||
from dify_plugin.entities.trigger import Variables
|
||||
from dify_plugin.errors.trigger import EventIgnoreError
|
||||
from dify_plugin.interfaces.trigger import Event
|
||||
|
||||
class IssuesUnifiedEvent(Event):
|
||||
"""Unified Issues event. Filters by actions and common issue attributes."""
|
||||
|
||||
def _on_event(self, request: Request, parameters: Mapping[str, Any], payload: Mapping[str, Any]) -> Variables:
|
||||
payload = request.get_json()
|
||||
if not payload:
|
||||
raise ValueError("No payload received")
|
||||
|
||||
allowed_actions = parameters.get("actions") or []
|
||||
action = payload.get("action")
|
||||
if allowed_actions and action not in allowed_actions:
|
||||
raise EventIgnoreError()
|
||||
|
||||
issue = payload.get("issue")
|
||||
if not isinstance(issue, Mapping):
|
||||
raise ValueError("No issue in payload")
|
||||
|
||||
return Variables(variables={**payload})
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### イベントフィルタリング
|
||||
|
||||
特定のイベント(例えば、特定のラベルを持つIssueイベントのみ)をフィルタリングするには、`issues.yaml`のイベント定義に`parameters`を追加します。その後、`_on_event`メソッド内で`EventIgnoreError`例外をスローすることで、設定された基準を満たさないイベントを除外できます。
|
||||
|
||||
<Tabs>
|
||||
<Tab title="issues.yaml">
|
||||
```YAML
|
||||
parameters:
|
||||
- name: added_label
|
||||
label:
|
||||
en_US: Added Label
|
||||
zh_Hans: 添加的标签
|
||||
ja_JP: 追加されたラベル
|
||||
type: string
|
||||
required: false
|
||||
description:
|
||||
en_US: "Only trigger if these specific labels were added (e.g., critical, priority-high, security, comma-separated). Leave empty to trigger for any label addition."
|
||||
zh_Hans: "仅当添加了这些特定标签时触发(例如:critical, priority-high, security,逗号分隔)。留空则对任何标签添加触发。"
|
||||
ja_JP: "これらの特定のラベルが追加された場合のみトリガー(例: critical, priority-high, security,カンマ区切り)。空の場合は任意のラベル追加でトリガー。"
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="issues.py">
|
||||
```Python
|
||||
def _check_added_label(self, payload: Mapping[str, Any], added_label_param: str | None) -> None:
|
||||
"""Check if the added label matches the allowed labels"""
|
||||
if not added_label_param:
|
||||
return
|
||||
|
||||
allowed_labels = [label.strip() for label in added_label_param.split(",") if label.strip()]
|
||||
if not allowed_labels:
|
||||
return
|
||||
|
||||
# The payload contains the label that was added
|
||||
label = payload.get("label", {})
|
||||
label_name = label.get("name", "")
|
||||
|
||||
if label_name not in allowed_labels:
|
||||
raise EventIgnoreError()
|
||||
|
||||
def _on_event(self, request: Request, parameters: Mapping[str, Any], payload: Mapping[str, Any]) -> Variables:
|
||||
# ...
|
||||
# Apply all filters
|
||||
self._check_added_label(payload, parameters.get("added_label"))
|
||||
|
||||
return Variables(variables={**payload})
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### OAuthまたはAPIキーによるサブスクリプションの作成
|
||||
|
||||
OAuthまたはAPIキーを介した自動的なサブスクリプション作成を有効にするには、`github.yaml`と`github.py`ファイルを変更する必要があります。
|
||||
|
||||
<Tabs>
|
||||
<Tab title="github.yaml">
|
||||
`github.yaml`に以下のフィールドを追加します。
|
||||
|
||||
```YAML
|
||||
subscription_constructor:
|
||||
parameters:
|
||||
- name: "repository"
|
||||
label:
|
||||
en_US: "Repository"
|
||||
zh_Hans: "仓库"
|
||||
ja_JP: "リポジトリ"
|
||||
type: "dynamic-select"
|
||||
required: true
|
||||
placeholder:
|
||||
en_US: "owner/repo"
|
||||
zh_Hans: "owner/repo"
|
||||
ja_JP: "owner/repo"
|
||||
help:
|
||||
en_US: "GitHub repository in format owner/repo (e.g., microsoft/vscode)"
|
||||
zh_Hans: "GitHub 仓库,格式为 owner/repo(例如:microsoft/vscode)"
|
||||
ja_JP: "GitHubリポジトリは owner/repo 形式で入力してください(例: microsoft/vscode)"
|
||||
credentials_schema:
|
||||
access_tokens:
|
||||
help:
|
||||
en_US: Get your Access Tokens from GitHub
|
||||
ja_JP: GitHub からアクセストークンを取得してください
|
||||
zh_Hans: 从 GitHub 获取您的 Access Tokens
|
||||
label:
|
||||
en_US: Access Tokens
|
||||
ja_JP: アクセストークン
|
||||
zh_Hans: Access Tokens
|
||||
placeholder:
|
||||
en_US: Please input your GitHub Access Tokens
|
||||
ja_JP: GitHub のアクセストークンを入力してください
|
||||
zh_Hans: 请输入你的 GitHub Access Tokens
|
||||
required: true
|
||||
type: secret-input
|
||||
url: https://github.com/settings/tokens?type=beta
|
||||
extra:
|
||||
python:
|
||||
source: provider/github.py
|
||||
```
|
||||
|
||||
`subscription_constructor`は、サブスクリプションがどのように構築されるかを定義するためにDifyによって抽象化された概念です。以下のフィールドが含まれます。
|
||||
|
||||
- `parameters` (任意): 購読するイベントタイプやターゲットのGitHubリポジトリなど、サブスクリプション作成に必要なパラメータを定義します。
|
||||
|
||||
- `credentials_schema` (任意): APIキーでサブスクリプションを作成する際に必要な認証情報(例: GitHubの`access_tokens`)を宣言します。
|
||||
|
||||
- `oauth_schema` (任意): OAuth経由でのサブスクリプション作成を実装する場合に必要です。定義方法の詳細は、[ツールプラグインにOAuthサポートを追加する](/plugin-dev-en/0222-tool-oauth)を参照してください。
|
||||
</Tab>
|
||||
<Tab title="github.py">
|
||||
`github.py`に`Constructor`クラスを作成し、自動サブスクリプションロジックを実装します。
|
||||
|
||||
```Python
|
||||
class GithubSubscriptionConstructor(TriggerSubscriptionConstructor):
|
||||
"""Manage GitHub trigger subscriptions."""
|
||||
def _validate_api_key(self, credentials: Mapping[str, Any]) -> None:
|
||||
# ...
|
||||
|
||||
def _create_subscription(
|
||||
self,
|
||||
endpoint: str,
|
||||
parameters: Mapping[str, Any],
|
||||
credentials: Mapping[str, Any],
|
||||
credential_type: CredentialType,
|
||||
) -> Subscription:
|
||||
repository = parameters.get("repository")
|
||||
if not repository:
|
||||
raise ValueError("repository is required (format: owner/repo)")
|
||||
|
||||
try:
|
||||
owner, repo = repository.split("/")
|
||||
except ValueError:
|
||||
raise ValueError("repository must be in format 'owner/repo'") from None
|
||||
|
||||
events: list[str] = parameters.get("events", [])
|
||||
webhook_secret = uuid.uuid4().hex
|
||||
url = f"https://api.github.com/repos/{owner}/{repo}/hooks"
|
||||
headers = {
|
||||
"Authorization": f"Bearer {credentials.get('access_tokens')}",
|
||||
"Accept": "application/vnd.github+json",
|
||||
}
|
||||
|
||||
webhook_data = {
|
||||
"name": "web",
|
||||
"active": True,
|
||||
"events": events,
|
||||
"config": {"url": endpoint, "content_type": "json", "insecure_ssl": "0", "secret": webhook_secret},
|
||||
}
|
||||
|
||||
try:
|
||||
response = requests.post(url, json=webhook_data, headers=headers, timeout=10)
|
||||
except requests.RequestException as exc:
|
||||
raise SubscriptionError(f"Network error while creating webhook: {exc}", error_code="NETWORK_ERROR") from exc
|
||||
|
||||
if response.status_code == 201:
|
||||
webhook = response.json()
|
||||
return Subscription(
|
||||
expires_at=int(time.time()) + self._WEBHOOK_TTL,
|
||||
endpoint=endpoint,
|
||||
parameters=parameters,
|
||||
properties={
|
||||
"external_id": str(webhook["id"]),
|
||||
"repository": repository,
|
||||
"events": events,
|
||||
"webhook_secret": webhook_secret,
|
||||
"active": webhook.get("active", True),
|
||||
},
|
||||
)
|
||||
|
||||
response_data: dict[str, Any] = response.json() if response.content else {}
|
||||
error_msg = response_data.get("message", "Unknown error")
|
||||
error_details = response_data.get("errors", [])
|
||||
detailed_error = f"Failed to create GitHub webhook: {error_msg}"
|
||||
if error_details:
|
||||
detailed_error += f" Details: {error_details}"
|
||||
|
||||
raise SubscriptionError(
|
||||
detailed_error,
|
||||
error_code="WEBHOOK_CREATION_FAILED",
|
||||
external_response=response_data,
|
||||
)
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
---
|
||||
|
||||
|
||||
これら2つのファイルを変更すると、Difyインターフェースに**APIキーで作成**オプションが表示されます。
|
||||
|
||||
OAuth経由の自動サブスクリプション作成も同じ`Constructor`クラスで実装できます。`subscription_constructor`の下に`oauth_schema`フィールドを追加することで、OAuth認証を有効にできます。
|
||||
|
||||
<img src="/images/trigger_plugin_oauth_apikey.png" alt="OAuthとAPIキーのオプション" width="563" />
|
||||
|
||||
## さらに詳しく
|
||||
|
||||
トリガープラグイン開発における核心クラスのインターフェース定義と実装方法は以下の通りです。
|
||||
|
||||
### Trigger
|
||||
|
||||
```Python
|
||||
class Trigger(ABC):
|
||||
@abstractmethod
|
||||
def _dispatch_event(self, subscription: Subscription, request: Request) -> EventDispatch:
|
||||
"""
|
||||
Internal method to implement event dispatch logic.
|
||||
|
||||
Subclasses must override this method to handle incoming webhook events.
|
||||
|
||||
Implementation checklist:
|
||||
1. Validate the webhook request:
|
||||
- Check signature/HMAC using properties when you create the subscription from subscription.properties
|
||||
- Verify request is from expected source
|
||||
2. Extract event information:
|
||||
- Parse event type from headers or body
|
||||
- Extract relevant payload data
|
||||
3. Return EventDispatch with:
|
||||
- events: List of Event names to invoke (can be single or multiple)
|
||||
- response: Appropriate HTTP response for the webhook
|
||||
|
||||
Args:
|
||||
subscription: The Subscription object with endpoint and properties fields
|
||||
request: Incoming webhook HTTP request
|
||||
|
||||
Returns:
|
||||
EventDispatch: Event dispatch routing information
|
||||
|
||||
Raises:
|
||||
TriggerValidationError: For security validation failures
|
||||
TriggerDispatchError: For parsing or routing errors
|
||||
"""
|
||||
raise NotImplementedError("This plugin should implement `_dispatch_event` method to enable event dispatch")
|
||||
|
||||
```
|
||||
|
||||
### TriggerSubscriptionConstructor
|
||||
|
||||
```Python
|
||||
class TriggerSubscriptionConstructor(ABC, OAuthProviderProtocol):
|
||||
# OPTIONAL
|
||||
def _validate_api_key(self, credentials: Mapping[str, Any]) -> None:
|
||||
raise NotImplementedError(
|
||||
"This plugin should implement `_validate_api_key` method to enable credentials validation"
|
||||
)
|
||||
|
||||
# OPTIONAL
|
||||
def _oauth_get_authorization_url(self, redirect_uri: str, system_credentials: Mapping[str, Any]) -> str:
|
||||
raise NotImplementedError(
|
||||
"The trigger you are using does not support OAuth, please implement `_oauth_get_authorization_url` method"
|
||||
)
|
||||
|
||||
# OPTIONAL
|
||||
def _oauth_get_credentials(
|
||||
self, redirect_uri: str, system_credentials: Mapping[str, Any], request: Request
|
||||
) -> TriggerOAuthCredentials:
|
||||
raise NotImplementedError(
|
||||
"The trigger you are using does not support OAuth, please implement `_oauth_get_credentials` method"
|
||||
)
|
||||
|
||||
# OPTIONAL
|
||||
def _oauth_refresh_credentials(
|
||||
self, redirect_uri: str, system_credentials: Mapping[str, Any], credentials: Mapping[str, Any]
|
||||
) -> OAuthCredentials:
|
||||
raise NotImplementedError(
|
||||
"The trigger you are using does not support OAuth, please implement `_oauth_refresh_credentials` method"
|
||||
)
|
||||
|
||||
@abstractmethod
|
||||
def _create_subscription(
|
||||
self,
|
||||
endpoint: str,
|
||||
parameters: Mapping[str, Any],
|
||||
credentials: Mapping[str, Any],
|
||||
credential_type: CredentialType,
|
||||
) -> Subscription:
|
||||
"""
|
||||
Internal method to implement subscription logic.
|
||||
|
||||
Subclasses must override this method to handle subscription creation.
|
||||
|
||||
Implementation checklist:
|
||||
1. Use the endpoint parameter provided by Dify
|
||||
2. Register webhook with external service using their API
|
||||
3. Store all necessary information in Subscription.properties for future operations(e.g., dispatch_event)
|
||||
4. Return Subscription with:
|
||||
- expires_at: Set appropriate expiration time
|
||||
- endpoint: The webhook endpoint URL allocated by Dify for receiving events, same with the endpoint parameter
|
||||
- parameters: The parameters of the subscription
|
||||
- properties: All configuration and external IDs
|
||||
|
||||
Args:
|
||||
endpoint: The webhook endpoint URL allocated by Dify for receiving events
|
||||
parameters: Subscription creation parameters
|
||||
credentials: Authentication credentials
|
||||
credential_type: The type of the credentials, e.g., "api-key", "oauth2", "unauthorized"
|
||||
|
||||
Returns:
|
||||
Subscription: Subscription details with metadata for future operations
|
||||
|
||||
Raises:
|
||||
SubscriptionError: For operational failures (API errors, invalid credentials)
|
||||
ValueError: For programming errors (missing required params)
|
||||
"""
|
||||
raise NotImplementedError(
|
||||
"This plugin should implement `_create_subscription` method to enable event subscription"
|
||||
)
|
||||
|
||||
@abstractmethod
|
||||
def _delete_subscription(
|
||||
self, subscription: Subscription, credentials: Mapping[str, Any], credential_type: CredentialType
|
||||
) -> UnsubscribeResult:
|
||||
"""
|
||||
Internal method to implement unsubscription logic.
|
||||
|
||||
Subclasses must override this method to handle subscription removal.
|
||||
|
||||
Implementation guidelines:
|
||||
1. Extract necessary IDs from subscription.properties (e.g., external_id)
|
||||
2. Use credentials and credential_type to call external service API to delete the webhook
|
||||
3. Handle common errors (not found, unauthorized, etc.)
|
||||
4. Always return UnsubscribeResult with detailed status
|
||||
5. Never raise exceptions for operational failures - use UnsubscribeResult.success=False
|
||||
|
||||
Args:
|
||||
subscription: The Subscription object with endpoint and properties fields
|
||||
|
||||
Returns:
|
||||
UnsubscribeResult: Always returns result, never raises for operational failures
|
||||
"""
|
||||
raise NotImplementedError(
|
||||
"This plugin should implement `_delete_subscription` method to enable event unsubscription"
|
||||
)
|
||||
|
||||
@abstractmethod
|
||||
def _refresh_subscription(
|
||||
self, subscription: Subscription, credentials: Mapping[str, Any], credential_type: CredentialType
|
||||
) -> Subscription:
|
||||
"""
|
||||
Internal method to implement subscription refresh logic.
|
||||
|
||||
Subclasses must override this method to handle simple expiration extension.
|
||||
|
||||
Implementation patterns:
|
||||
1. For webhooks without expiration (e.g., GitHub):
|
||||
- Update the Subscription.expires_at=-1 then Dify will never call this method again
|
||||
|
||||
2. For lease-based subscriptions (e.g., Microsoft Graph):
|
||||
- Use the information in Subscription.properties to call service's lease renewal API if available
|
||||
- Handle renewal limits (some services limit renewal count)
|
||||
- Update the Subscription.properties and Subscription.expires_at for next time renewal if needed
|
||||
|
||||
Args:
|
||||
subscription: Current subscription with properties
|
||||
credential_type: The type of the credentials, e.g., "api-key", "oauth2", "unauthorized"
|
||||
credentials: Current authentication credentials from credentials_schema.
|
||||
For API key auth, according to `credentials_schema` defined in the YAML.
|
||||
For OAuth auth, according to `oauth_schema.credentials_schema` defined in the YAML.
|
||||
For unauthorized auth, there is no credentials.
|
||||
|
||||
Returns:
|
||||
Subscription: Same subscription with extended expiration
|
||||
or new properties and expires_at for next time renewal
|
||||
|
||||
Raises:
|
||||
SubscriptionError: For operational failures (API errors, invalid credentials)
|
||||
"""
|
||||
raise NotImplementedError("This plugin should implement `_refresh` method to enable subscription refresh")
|
||||
|
||||
# OPTIONAL
|
||||
def _fetch_parameter_options(
|
||||
self, parameter: str, credentials: Mapping[str, Any], credential_type: CredentialType
|
||||
) -> list[ParameterOption]:
|
||||
"""
|
||||
Fetch the parameter options of the trigger.
|
||||
|
||||
Implementation guidelines:
|
||||
When you need to fetch parameter options from an external service, use the credentials
|
||||
and credential_type to call the external service API, then return the options to Dify
|
||||
for user selection.
|
||||
|
||||
Args:
|
||||
parameter: The parameter name for which to fetch options
|
||||
credentials: Authentication credentials for the external service
|
||||
credential_type: The type of credentials (e.g., "api-key", "oauth2", "unauthorized")
|
||||
|
||||
Returns:
|
||||
list[ParameterOption]: A list of available options for the parameter
|
||||
|
||||
Examples:
|
||||
GitHub Repositories:
|
||||
>>> result = provider.fetch_parameter_options(parameter="repository")
|
||||
>>> print(result) # [ParameterOption(label="owner/repo", value="owner/repo")]
|
||||
|
||||
Slack Channels:
|
||||
>>> result = provider.fetch_parameter_options(parameter="channel")
|
||||
>>> print(result)
|
||||
```
|
||||
|
||||
### Event
|
||||
|
||||
```Python
|
||||
class Event(ABC):
|
||||
@abstractmethod
|
||||
def _on_event(self, request: Request, parameters: Mapping[str, Any], payload: Mapping[str, Any]) -> Variables:
|
||||
"""
|
||||
Transform the incoming webhook request into structured Variables.
|
||||
|
||||
This method should:
|
||||
1. Parse the webhook payload from the request
|
||||
2. Apply filtering logic based on parameters
|
||||
3. Extract relevant data matching the output_schema
|
||||
4. Return a structured Variables object
|
||||
|
||||
Args:
|
||||
request: The incoming webhook HTTP request containing the raw payload.
|
||||
Use request.get_json() to parse JSON body.
|
||||
parameters: User-configured parameters for filtering and transformation
|
||||
(e.g., label filters, regex patterns, threshold values).
|
||||
These come from the subscription configuration.
|
||||
payload: The decoded payload from previous step `Trigger.dispatch_event`.
|
||||
It will be delivered into `_on_event` method.
|
||||
Returns:
|
||||
Variables: Structured variables matching the output_schema
|
||||
defined in the event's YAML configuration.
|
||||
|
||||
Raises:
|
||||
EventIgnoreError: When the event should be filtered out based on parameters
|
||||
ValueError: When the payload is invalid or missing required fields
|
||||
|
||||
Example:
|
||||
>>> def _on_event(self, request, parameters):
|
||||
... payload = request.get_json()
|
||||
...
|
||||
... # Apply filters
|
||||
... if not self._matches_filters(payload, parameters):
|
||||
... raise EventIgnoreError()
|
||||
...
|
||||
... # Transform data
|
||||
... return Variables(variables={
|
||||
... "title": payload["issue"]["title"],
|
||||
... "author": payload["issue"]["user"]["login"],
|
||||
... "url": payload["issue"]["html_url"],
|
||||
... })
|
||||
"""
|
||||
|
||||
def _fetch_parameter_options(self, parameter: str) -> list[ParameterOption]:
|
||||
"""
|
||||
Fetch the parameter options of the trigger.
|
||||
|
||||
To be implemented by subclasses.
|
||||
|
||||
Also, it's optional to implement, that's why it's not an abstract method.
|
||||
"""
|
||||
raise NotImplementedError(
|
||||
"This plugin should implement `_fetch_parameter_options` method to enable dynamic select parameter"
|
||||
)
|
||||
```
|
||||
|
||||
{/*
|
||||
Contributing Section
|
||||
DO NOT edit this section!
|
||||
It will be automatically generated by the script.
|
||||
*/}
|
||||
|
||||
---
|
||||
|
||||
[このページを編集する](https://github.com/langgenius/dify-docs/edit/main/plugin-dev-ja/0222-trigger-plugin.mdx) | [問題を報告する](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)
|
||||
|
||||
660
plugin-dev-zh/0222-trigger-plugin.mdx
Normal file
@@ -0,0 +1,660 @@
|
||||
---
|
||||
title: "触发器插件"
|
||||
---
|
||||
|
||||
## 触发器插件是什么?
|
||||
|
||||
Dify v1.10.0 引入了触发器(Trigger)类型的开始节点。区别于代码(Code)、工具(Tool)、知识检索(Knowledge Retrieval)等功能性节点,触发器的作用是**将第三方事件转化为 Dify 能接受的入参格式**。
|
||||
|
||||

|
||||
|
||||
例如,在 Gmail 中将事件的接收方配置为 Dify 后,每当你收到一封新邮件,Gmail 就会向 Dify 发送一个事件,可用于触发工作流。然而:
|
||||
|
||||
- Gmail 的原始请求格式不是 Dify 可接受的格式;
|
||||
|
||||
- 全世界有成千上万的平台,每个平台的格式都不尽相同。
|
||||
|
||||
因此,我们需要触发器插件来定义和解析这些来自不同平台、不同格式的事件,并将它们统一为 Dify 可接受的标准入参格式。
|
||||
|
||||
## 技术原理
|
||||
|
||||
Dify 触发器基于 Webhook 实现。Webhook 是互联网中广泛应用的机制,主流 SaaS 平台(如 Github、Slack、Linear 等)均支持 Webhook 并配有详细的开发文档。
|
||||
|
||||
Webhook 可理解为基于 HTTP 协议的事件派发中心。**当配置好事件接收地址后,这些 SaaS 平台会在指定事件发生时自动将其推送至目标服务器。**
|
||||
|
||||
为了统一处理来自不同平台的 Webhook 事件,Dify 抽象出两个核心概念:订阅(Subscription) 和事件(Event)。
|
||||
|
||||
- **订阅**:如前所述,基于 Webhook 的事件派发有一个前提条件——**需要将 Dify 的网络地址作为目标服务器,配置在第三方平台的开发者后台中。这个配置过程在 Dify 中称为「订阅」。**
|
||||
|
||||
- **事件**:一个平台可能会发送多种类型的事件,例如 *新邮件*、*邮件删除*、*邮件已读* 等,这些事件均会被推送至预先配置的地址。一个触发器插件可配置多个事件,一个事件对应 Dify 工作流中的一个触发器节点。
|
||||
|
||||
## 插件开发
|
||||
|
||||
触发器插件的开发方式与工具(Tool)、数据源(Data Source)、模型(Model)等插件类型一致,均可通过 `dify plugin init` 命令创建开发模板,其文件结构遵循统一的插件格式规范:
|
||||
|
||||
```
|
||||
├── _assets
|
||||
│ └── icon.svg
|
||||
├── events
|
||||
│ └── star
|
||||
│ ├── star_created.py
|
||||
│ └── star_created.yaml
|
||||
├── main.py
|
||||
├── manifest.yaml
|
||||
├── provider
|
||||
│ ├── github.py
|
||||
│ └── github.yaml
|
||||
├── README.md
|
||||
├── PRIVACY.md
|
||||
└── requirements.txt
|
||||
```
|
||||
- `manifest.yaml`:描述插件的基本信息。
|
||||
|
||||
- `provider` 目录:包含插件供应商的描述信息、创建订阅的代码,以及接收 Webhook 请求后对事件进行分类的代码。
|
||||
|
||||
- **`events` 目录:包含事件处理和筛选功能的代码,支持在节点端对事件进行本地筛选;每个目录下可创建二级目录,以便对事件进行分组。**
|
||||
|
||||
<Note>
|
||||
在触发器插件中,最低 Dify 版本需设置为 `1.10.0`,SDK 版本需设置为大于等于 `0.6.0`。
|
||||
</Note>
|
||||
|
||||
下面以 GitHub 为例,介绍触发器插件的具体开发方法。
|
||||
|
||||
### 订阅创建
|
||||
|
||||
在主流 SaaS 平台中,Webhook 的配置方式差异较大:
|
||||
|
||||
- 部分平台(如 GitHub)支持通过 API 配置 Webhook。此类平台在 Dify 中完成 OAuth 鉴权后,Dify 即可自动完成 Webhook 配置。
|
||||
|
||||
- 另一类平台(如 Notion)不仅不提供 Webhook API 配置功能,还要求用户手动完成部分校验工作。
|
||||
|
||||
因此,我们将订阅过程分为两个部分:Subscription Constructor 和 Subscription。
|
||||
|
||||
对于 Notion 这类平台,订阅的创建需要用户手动将 Dify 提供的回调地址(Callback URL)复制粘贴到 Notion 后台中,以完成 Webhook 配置。此流程对应 Dify 界面中的 **粘贴 URL 以创建新订阅** 选项。
|
||||
|
||||
<img src="/images/trigger_plugin_manual_webhook_setup.PNG" alt="Paste URL to Create a New Subscription" width="563" />
|
||||
|
||||
若要实现通过手动复制 Callback URL 的方式创建订阅,需要修改 `github.yaml` 和 `github.py` 两个文件。
|
||||
|
||||
<Tabs>
|
||||
<Tab title="github.yaml">
|
||||
由于 Github Webhook 存在加密机制,解密和校验请求需要使用密钥,因此需在 `github.yaml` 中声明 `webhook_secret`。
|
||||
|
||||
```YAML
|
||||
subscription_schema:
|
||||
- name: "webhook_secret"
|
||||
type: "secret-input"
|
||||
required: false
|
||||
label:
|
||||
zh_Hans: "Webhook Secret"
|
||||
en_US: "Webhook Secret"
|
||||
ja_JP: "Webhookシークレット"
|
||||
help:
|
||||
en_US: "Optional webhook secret for validating GitHub webhook requests"
|
||||
ja_JP: "GitHub Webhookリクエストの検証用のオプションのWebhookシークレット"
|
||||
zh_Hans: "可选的用于验证 GitHub webhook 请求的 webhook 密钥"
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="github.py">
|
||||
|
||||
首先,我们需要编写 `dispatch_event` 接口。所有发送到 Callback URL 的请求都会先经过该接口处理,处理后的事件将显示在界面上的 **请求日志** 中,便于调试与验证。
|
||||
|
||||
<img src="/images/trigger_plugin_manual_webhook_setup_config.PNG" alt="Manual Setup" width="500" />
|
||||
|
||||
在代码中,可通过 `subscription.properties` 获取在 `github.yaml` 中声明的 `webhook_secret`。
|
||||
|
||||
`dispatch_event` 方法需要根据请求内容判断该请求对应的事件类型。在以下示例中,事件提取由 `_dispatch_trigger_event` 方法完成。
|
||||
|
||||
<Tip>
|
||||
完整代码示例,请参考 [Dify GitHub 插件代码](https://github.com/langgenius/dify-plugin-sdks/tree/feat/trigger/python/examples/github_trigger)。
|
||||
</Tip>
|
||||
|
||||
```Python
|
||||
class GithubTrigger(Trigger):
|
||||
"""Handle GitHub webhook event dispatch."""
|
||||
|
||||
def _dispatch_event(self, subscription: Subscription, request: Request) -> EventDispatch:
|
||||
webhook_secret = subscription.properties.get("webhook_secret")
|
||||
if webhook_secret:
|
||||
self._validate_signature(request=request, webhook_secret=webhook_secret)
|
||||
|
||||
event_type: str | None = request.headers.get("X-GitHub-Event")
|
||||
if not event_type:
|
||||
raise TriggerDispatchError("Missing GitHub event type header")
|
||||
|
||||
payload: Mapping[str, Any] = self._validate_payload(request)
|
||||
response = Response(response='{"status": "ok"}', status=200, mimetype="application/json")
|
||||
event: str = self._dispatch_trigger_event(event_type=event_type, payload=payload)
|
||||
return EventDispatch(events=[event] if event else [], response=response)
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### 事件处理
|
||||
|
||||
提取出事件后,需要由相应的事件实现对原始 HTTP 请求进行过滤,并将其转换为 Dify 工作流可接受的入参。
|
||||
|
||||
以 Issue 事件为例,可分别通过 `events/issues/issues.yaml` 和 `events/issues/issues.py` 来定义事件与实现事件。事件的输出可在 `issues.yaml` 的 `output_schema` 中定义,与工具类型插件相同,遵循 JSON Schema 规范。
|
||||
|
||||
<Tabs>
|
||||
<Tab title="issues.yaml">
|
||||
```YAML
|
||||
identity:
|
||||
name: issues
|
||||
author: langgenius
|
||||
label:
|
||||
en_US: Issues
|
||||
zh_Hans: 议题
|
||||
ja_JP: イシュー
|
||||
description:
|
||||
en_US: Unified issues event with actions filter
|
||||
zh_Hans: 带 actions 过滤的统一 issues 事件
|
||||
ja_JP: アクションフィルタ付きの統合イシューイベント
|
||||
output_schema:
|
||||
type: object
|
||||
properties:
|
||||
action:
|
||||
type: string
|
||||
issue:
|
||||
type: object
|
||||
description: The issue itself
|
||||
extra:
|
||||
python:
|
||||
source: events/issues/issues.py
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="issues.py">
|
||||
```Python
|
||||
from collections.abc import Mapping
|
||||
from typing import Any
|
||||
|
||||
from werkzeug import Request
|
||||
|
||||
from dify_plugin.entities.trigger import Variables
|
||||
from dify_plugin.errors.trigger import EventIgnoreError
|
||||
from dify_plugin.interfaces.trigger import Event
|
||||
|
||||
class IssuesUnifiedEvent(Event):
|
||||
"""Unified Issues event. Filters by actions and common issue attributes."""
|
||||
|
||||
def _on_event(self, request: Request, parameters: Mapping[str, Any], payload: Mapping[str, Any]) -> Variables:
|
||||
payload = request.get_json()
|
||||
if not payload:
|
||||
raise ValueError("No payload received")
|
||||
|
||||
allowed_actions = parameters.get("actions") or []
|
||||
action = payload.get("action")
|
||||
if allowed_actions and action not in allowed_actions:
|
||||
raise EventIgnoreError()
|
||||
|
||||
issue = payload.get("issue")
|
||||
if not isinstance(issue, Mapping):
|
||||
raise ValueError("No issue in payload")
|
||||
|
||||
return Variables(variables={**payload})
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### 事件过滤
|
||||
|
||||
若希望插件能够筛选掉部分事件,例如只关注具有某个特定标签的 Issue 事件,可在事件定义中为 Issue 事件添加 `parameters`。在 `_on_event` 方法中,通过抛出 `EventIgnoreError` 异常,即可在实际运行中根据配置的参数过滤掉不符合条件的事件。
|
||||
|
||||
<Tabs>
|
||||
<Tab title="issues.yaml">
|
||||
```YAML
|
||||
parameters:
|
||||
- name: added_label
|
||||
label:
|
||||
en_US: Added Label
|
||||
zh_Hans: 添加的标签
|
||||
ja_JP: 追加されたラベル
|
||||
type: string
|
||||
required: false
|
||||
description:
|
||||
en_US: "Only trigger if these specific labels were added (e.g., critical, priority-high, security, comma-separated). Leave empty to trigger for any label addition."
|
||||
zh_Hans: "仅当添加了这些特定标签时触发(例如:critical, priority-high, security,逗号分隔)。留空则对任何标签添加触发。"
|
||||
ja_JP: "これらの特定のラベルが追加された場合のみトリガー(例: critical, priority-high, security,カンマ区切り)。空の場合は任意のラベル追加でトリガー。"
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="issues.py">
|
||||
```Python
|
||||
def _check_added_label(self, payload: Mapping[str, Any], added_label_param: str | None) -> None:
|
||||
"""Check if the added label matches the allowed labels"""
|
||||
if not added_label_param:
|
||||
return
|
||||
|
||||
allowed_labels = [label.strip() for label in added_label_param.split(",") if label.strip()]
|
||||
if not allowed_labels:
|
||||
return
|
||||
|
||||
# The payload contains the label that was added
|
||||
label = payload.get("label", {})
|
||||
label_name = label.get("name", "")
|
||||
|
||||
if label_name not in allowed_labels:
|
||||
raise EventIgnoreError()
|
||||
|
||||
def _on_event(self, request: Request, parameters: Mapping[str, Any], payload: Mapping[str, Any]) -> Variables:
|
||||
# ...
|
||||
# Apply all filters
|
||||
self._check_added_label(payload, parameters.get("added_label"))
|
||||
|
||||
return Variables(variables={**payload})
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### 通过 OAuth 或 API key 创建订阅
|
||||
|
||||
若要实现通过 OAuth 或 API key 自动创建订阅,同样需要修改 `github.yaml` 和 `github.py` 两个文件。
|
||||
|
||||
<Tabs>
|
||||
<Tab title="github.yaml">
|
||||
在 `github.yaml` 中,添加如下字段。
|
||||
|
||||
```YAML
|
||||
subscription_constructor:
|
||||
parameters:
|
||||
- name: "repository"
|
||||
label:
|
||||
en_US: "Repository"
|
||||
zh_Hans: "仓库"
|
||||
ja_JP: "リポジトリ"
|
||||
type: "dynamic-select"
|
||||
required: true
|
||||
placeholder:
|
||||
en_US: "owner/repo"
|
||||
zh_Hans: "owner/repo"
|
||||
ja_JP: "owner/repo"
|
||||
help:
|
||||
en_US: "GitHub repository in format owner/repo (e.g., microsoft/vscode)"
|
||||
zh_Hans: "GitHub 仓库,格式为 owner/repo(例如:microsoft/vscode)"
|
||||
ja_JP: "GitHubリポジトリは owner/repo 形式で入力してください(例: microsoft/vscode)"
|
||||
credentials_schema:
|
||||
access_tokens:
|
||||
help:
|
||||
en_US: Get your Access Tokens from GitHub
|
||||
ja_JP: GitHub からアクセストークンを取得してください
|
||||
zh_Hans: 从 GitHub 获取您的 Access Tokens
|
||||
label:
|
||||
en_US: Access Tokens
|
||||
ja_JP: アクセストークン
|
||||
zh_Hans: Access Tokens
|
||||
placeholder:
|
||||
en_US: Please input your GitHub Access Tokens
|
||||
ja_JP: GitHub のアクセストークンを入力してください
|
||||
zh_Hans: 请输入你的 GitHub Access Tokens
|
||||
required: true
|
||||
type: secret-input
|
||||
url: https://github.com/settings/tokens?type=beta
|
||||
extra:
|
||||
python:
|
||||
source: provider/github.py
|
||||
```
|
||||
`subscription_constructor` 是 Dify 抽象出的一个概念,用于定义如何构建订阅,包含以下字段:
|
||||
|
||||
- `parameters`(可选):用于定义创建订阅时所需的参数,例如想要订阅的事件类型或目标 GitHub 仓库等。
|
||||
|
||||
- `credentials_schema`(可选):通过 API key 创建订阅时,必须填写该字段以声明所需的密钥,例如在 GitHub 中定义 `access_tokens`。
|
||||
|
||||
- `oauth_schema`(可选):通过 OAuth 创建订阅时,必须填写该字段以启用 OAuth 鉴权。具体定义方式,可参考 [为插件添加 OAuth 支持](/plugin-dev-zh/0222-tool-oauth)。
|
||||
</Tab>
|
||||
<Tab title="github.py">
|
||||
在 `github.py` 中创建一个 `Constructor` 类,以实现自动化订阅逻辑。
|
||||
|
||||
```Python
|
||||
class GithubSubscriptionConstructor(TriggerSubscriptionConstructor):
|
||||
"""Manage GitHub trigger subscriptions."""
|
||||
def _validate_api_key(self, credentials: Mapping[str, Any]) -> None:
|
||||
# ...
|
||||
|
||||
def _create_subscription(
|
||||
self,
|
||||
endpoint: str,
|
||||
parameters: Mapping[str, Any],
|
||||
credentials: Mapping[str, Any],
|
||||
credential_type: CredentialType,
|
||||
) -> Subscription:
|
||||
repository = parameters.get("repository")
|
||||
if not repository:
|
||||
raise ValueError("repository is required (format: owner/repo)")
|
||||
|
||||
try:
|
||||
owner, repo = repository.split("/")
|
||||
except ValueError:
|
||||
raise ValueError("repository must be in format 'owner/repo'") from None
|
||||
|
||||
events: list[str] = parameters.get("events", [])
|
||||
webhook_secret = uuid.uuid4().hex
|
||||
url = f"https://api.github.com/repos/{owner}/{repo}/hooks"
|
||||
headers = {
|
||||
"Authorization": f"Bearer {credentials.get('access_tokens')}",
|
||||
"Accept": "application/vnd.github+json",
|
||||
}
|
||||
|
||||
webhook_data = {
|
||||
"name": "web",
|
||||
"active": True,
|
||||
"events": events,
|
||||
"config": {"url": endpoint, "content_type": "json", "insecure_ssl": "0", "secret": webhook_secret},
|
||||
}
|
||||
|
||||
try:
|
||||
response = requests.post(url, json=webhook_data, headers=headers, timeout=10)
|
||||
except requests.RequestException as exc:
|
||||
raise SubscriptionError(f"Network error while creating webhook: {exc}", error_code="NETWORK_ERROR") from exc
|
||||
|
||||
if response.status_code == 201:
|
||||
webhook = response.json()
|
||||
return Subscription(
|
||||
expires_at=int(time.time()) + self._WEBHOOK_TTL,
|
||||
endpoint=endpoint,
|
||||
parameters=parameters,
|
||||
properties={
|
||||
"external_id": str(webhook["id"]),
|
||||
"repository": repository,
|
||||
"events": events,
|
||||
"webhook_secret": webhook_secret,
|
||||
"active": webhook.get("active", True),
|
||||
},
|
||||
)
|
||||
|
||||
response_data: dict[str, Any] = response.json() if response.content else {}
|
||||
error_msg = response_data.get("message", "Unknown error")
|
||||
error_details = response_data.get("errors", [])
|
||||
detailed_error = f"Failed to create GitHub webhook: {error_msg}"
|
||||
if error_details:
|
||||
detailed_error += f" Details: {error_details}"
|
||||
|
||||
raise SubscriptionError(
|
||||
detailed_error,
|
||||
error_code="WEBHOOK_CREATION_FAILED",
|
||||
external_response=response_data,
|
||||
)
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
---
|
||||
|
||||
完成以上两个文件的配置后,你将在 Dify 界面中看到 **通过 API Key 创建** 选项。
|
||||
|
||||
通过 OAuth 的订阅自动创建也可以在 `Constructor` 中实现:在 `subscription_constructor` 中添加 `oauth_schema` 字段,即可启用 OAuth 认证方式。
|
||||
|
||||

|
||||
|
||||
## 探索更多
|
||||
|
||||
触发器插件开发中核心类的接口定义和实现方法如下。
|
||||
|
||||
### Trigger
|
||||
|
||||
```Python
|
||||
class Trigger(ABC):
|
||||
@abstractmethod
|
||||
def _dispatch_event(self, subscription: Subscription, request: Request) -> EventDispatch:
|
||||
"""
|
||||
Internal method to implement event dispatch logic.
|
||||
|
||||
Subclasses must override this method to handle incoming webhook events.
|
||||
|
||||
Implementation checklist:
|
||||
1. Validate the webhook request:
|
||||
- Check signature/HMAC using properties when you create the subscription from subscription.properties
|
||||
- Verify request is from expected source
|
||||
2. Extract event information:
|
||||
- Parse event type from headers or body
|
||||
- Extract relevant payload data
|
||||
3. Return EventDispatch with:
|
||||
- events: List of Event names to invoke (can be single or multiple)
|
||||
- response: Appropriate HTTP response for the webhook
|
||||
|
||||
Args:
|
||||
subscription: The Subscription object with endpoint and properties fields
|
||||
request: Incoming webhook HTTP request
|
||||
|
||||
Returns:
|
||||
EventDispatch: Event dispatch routing information
|
||||
|
||||
Raises:
|
||||
TriggerValidationError: For security validation failures
|
||||
TriggerDispatchError: For parsing or routing errors
|
||||
"""
|
||||
raise NotImplementedError("This plugin should implement `_dispatch_event` method to enable event dispatch")
|
||||
|
||||
```
|
||||
|
||||
### TriggerSubscriptionConstructor
|
||||
|
||||
```Python
|
||||
class TriggerSubscriptionConstructor(ABC, OAuthProviderProtocol):
|
||||
# OPTIONAL
|
||||
def _validate_api_key(self, credentials: Mapping[str, Any]) -> None:
|
||||
raise NotImplementedError(
|
||||
"This plugin should implement `_validate_api_key` method to enable credentials validation"
|
||||
)
|
||||
|
||||
# OPTIONAL
|
||||
def _oauth_get_authorization_url(self, redirect_uri: str, system_credentials: Mapping[str, Any]) -> str:
|
||||
raise NotImplementedError(
|
||||
"The trigger you are using does not support OAuth, please implement `_oauth_get_authorization_url` method"
|
||||
)
|
||||
|
||||
# OPTIONAL
|
||||
def _oauth_get_credentials(
|
||||
self, redirect_uri: str, system_credentials: Mapping[str, Any], request: Request
|
||||
) -> TriggerOAuthCredentials:
|
||||
raise NotImplementedError(
|
||||
"The trigger you are using does not support OAuth, please implement `_oauth_get_credentials` method"
|
||||
)
|
||||
|
||||
# OPTIONAL
|
||||
def _oauth_refresh_credentials(
|
||||
self, redirect_uri: str, system_credentials: Mapping[str, Any], credentials: Mapping[str, Any]
|
||||
) -> OAuthCredentials:
|
||||
raise NotImplementedError(
|
||||
"The trigger you are using does not support OAuth, please implement `_oauth_refresh_credentials` method"
|
||||
)
|
||||
|
||||
@abstractmethod
|
||||
def _create_subscription(
|
||||
self,
|
||||
endpoint: str,
|
||||
parameters: Mapping[str, Any],
|
||||
credentials: Mapping[str, Any],
|
||||
credential_type: CredentialType,
|
||||
) -> Subscription:
|
||||
"""
|
||||
Internal method to implement subscription logic.
|
||||
|
||||
Subclasses must override this method to handle subscription creation.
|
||||
|
||||
Implementation checklist:
|
||||
1. Use the endpoint parameter provided by Dify
|
||||
2. Register webhook with external service using their API
|
||||
3. Store all necessary information in Subscription.properties for future operations(e.g., dispatch_event)
|
||||
4. Return Subscription with:
|
||||
- expires_at: Set appropriate expiration time
|
||||
- endpoint: The webhook endpoint URL allocated by Dify for receiving events, same with the endpoint parameter
|
||||
- parameters: The parameters of the subscription
|
||||
- properties: All configuration and external IDs
|
||||
|
||||
Args:
|
||||
endpoint: The webhook endpoint URL allocated by Dify for receiving events
|
||||
parameters: Subscription creation parameters
|
||||
credentials: Authentication credentials
|
||||
credential_type: The type of the credentials, e.g., "api-key", "oauth2", "unauthorized"
|
||||
|
||||
Returns:
|
||||
Subscription: Subscription details with metadata for future operations
|
||||
|
||||
Raises:
|
||||
SubscriptionError: For operational failures (API errors, invalid credentials)
|
||||
ValueError: For programming errors (missing required params)
|
||||
"""
|
||||
raise NotImplementedError(
|
||||
"This plugin should implement `_create_subscription` method to enable event subscription"
|
||||
)
|
||||
|
||||
@abstractmethod
|
||||
def _delete_subscription(
|
||||
self, subscription: Subscription, credentials: Mapping[str, Any], credential_type: CredentialType
|
||||
) -> UnsubscribeResult:
|
||||
"""
|
||||
Internal method to implement unsubscription logic.
|
||||
|
||||
Subclasses must override this method to handle subscription removal.
|
||||
|
||||
Implementation guidelines:
|
||||
1. Extract necessary IDs from subscription.properties (e.g., external_id)
|
||||
2. Use credentials and credential_type to call external service API to delete the webhook
|
||||
3. Handle common errors (not found, unauthorized, etc.)
|
||||
4. Always return UnsubscribeResult with detailed status
|
||||
5. Never raise exceptions for operational failures - use UnsubscribeResult.success=False
|
||||
|
||||
Args:
|
||||
subscription: The Subscription object with endpoint and properties fields
|
||||
|
||||
Returns:
|
||||
UnsubscribeResult: Always returns result, never raises for operational failures
|
||||
"""
|
||||
raise NotImplementedError(
|
||||
"This plugin should implement `_delete_subscription` method to enable event unsubscription"
|
||||
)
|
||||
|
||||
@abstractmethod
|
||||
def _refresh_subscription(
|
||||
self, subscription: Subscription, credentials: Mapping[str, Any], credential_type: CredentialType
|
||||
) -> Subscription:
|
||||
"""
|
||||
Internal method to implement subscription refresh logic.
|
||||
|
||||
Subclasses must override this method to handle simple expiration extension.
|
||||
|
||||
Implementation patterns:
|
||||
1. For webhooks without expiration (e.g., GitHub):
|
||||
- Update the Subscription.expires_at=-1 then Dify will never call this method again
|
||||
|
||||
2. For lease-based subscriptions (e.g., Microsoft Graph):
|
||||
- Use the information in Subscription.properties to call service's lease renewal API if available
|
||||
- Handle renewal limits (some services limit renewal count)
|
||||
- Update the Subscription.properties and Subscription.expires_at for next time renewal if needed
|
||||
|
||||
Args:
|
||||
subscription: Current subscription with properties
|
||||
credential_type: The type of the credentials, e.g., "api-key", "oauth2", "unauthorized"
|
||||
credentials: Current authentication credentials from credentials_schema.
|
||||
For API key auth, according to `credentials_schema` defined in the YAML.
|
||||
For OAuth auth, according to `oauth_schema.credentials_schema` defined in the YAML.
|
||||
For unauthorized auth, there is no credentials.
|
||||
|
||||
Returns:
|
||||
Subscription: Same subscription with extended expiration
|
||||
or new properties and expires_at for next time renewal
|
||||
|
||||
Raises:
|
||||
SubscriptionError: For operational failures (API errors, invalid credentials)
|
||||
"""
|
||||
raise NotImplementedError("This plugin should implement `_refresh` method to enable subscription refresh")
|
||||
|
||||
# OPTIONAL
|
||||
def _fetch_parameter_options(
|
||||
self, parameter: str, credentials: Mapping[str, Any], credential_type: CredentialType
|
||||
) -> list[ParameterOption]:
|
||||
"""
|
||||
Fetch the parameter options of the trigger.
|
||||
|
||||
Implementation guidelines:
|
||||
When you need to fetch parameter options from an external service, use the credentials
|
||||
and credential_type to call the external service API, then return the options to Dify
|
||||
for user selection.
|
||||
|
||||
Args:
|
||||
parameter: The parameter name for which to fetch options
|
||||
credentials: Authentication credentials for the external service
|
||||
credential_type: The type of credentials (e.g., "api-key", "oauth2", "unauthorized")
|
||||
|
||||
Returns:
|
||||
list[ParameterOption]: A list of available options for the parameter
|
||||
|
||||
Examples:
|
||||
GitHub Repositories:
|
||||
>>> result = provider.fetch_parameter_options(parameter="repository")
|
||||
>>> print(result) # [ParameterOption(label="owner/repo", value="owner/repo")]
|
||||
|
||||
Slack Channels:
|
||||
>>> result = provider.fetch_parameter_options(parameter="channel")
|
||||
>>> print(result)
|
||||
```
|
||||
|
||||
### Event
|
||||
|
||||
```Python
|
||||
class Event(ABC):
|
||||
@abstractmethod
|
||||
def _on_event(self, request: Request, parameters: Mapping[str, Any], payload: Mapping[str, Any]) -> Variables:
|
||||
"""
|
||||
Transform the incoming webhook request into structured Variables.
|
||||
|
||||
This method should:
|
||||
1. Parse the webhook payload from the request
|
||||
2. Apply filtering logic based on parameters
|
||||
3. Extract relevant data matching the output_schema
|
||||
4. Return a structured Variables object
|
||||
|
||||
Args:
|
||||
request: The incoming webhook HTTP request containing the raw payload.
|
||||
Use request.get_json() to parse JSON body.
|
||||
parameters: User-configured parameters for filtering and transformation
|
||||
(e.g., label filters, regex patterns, threshold values).
|
||||
These come from the subscription configuration.
|
||||
payload: The decoded payload from previous step `Trigger.dispatch_event`.
|
||||
It will be delivered into `_on_event` method.
|
||||
Returns:
|
||||
Variables: Structured variables matching the output_schema
|
||||
defined in the event's YAML configuration.
|
||||
|
||||
Raises:
|
||||
EventIgnoreError: When the event should be filtered out based on parameters
|
||||
ValueError: When the payload is invalid or missing required fields
|
||||
|
||||
Example:
|
||||
>>> def _on_event(self, request, parameters):
|
||||
... payload = request.get_json()
|
||||
...
|
||||
... # Apply filters
|
||||
... if not self._matches_filters(payload, parameters):
|
||||
... raise EventIgnoreError()
|
||||
...
|
||||
... # Transform data
|
||||
... return Variables(variables={
|
||||
... "title": payload["issue"]["title"],
|
||||
... "author": payload["issue"]["user"]["login"],
|
||||
... "url": payload["issue"]["html_url"],
|
||||
... })
|
||||
"""
|
||||
|
||||
def _fetch_parameter_options(self, parameter: str) -> list[ParameterOption]:
|
||||
"""
|
||||
Fetch the parameter options of the trigger.
|
||||
|
||||
To be implemented by subclasses.
|
||||
|
||||
Also, it's optional to implement, that's why it's not an abstract method.
|
||||
"""
|
||||
raise NotImplementedError(
|
||||
"This plugin should implement `_fetch_parameter_options` method to enable dynamic select parameter"
|
||||
)
|
||||
```
|
||||
|
||||
{/*
|
||||
Contributing Section
|
||||
DO NOT edit this section!
|
||||
It will be automatically generated by the script.
|
||||
*/}
|
||||
|
||||
---
|
||||
|
||||
[编辑此页面](https://github.com/langgenius/dify-docs/edit/main/plugin-dev-zh/0222-trigger-plugin.mdx) | [提交问题](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)
|
||||
|
||||
@@ -1,34 +1,20 @@
|
||||
---
|
||||
title: 结束
|
||||
title: 输出
|
||||
---
|
||||
|
||||
### 定义
|
||||
|
||||
定义一个工作流程结束的最终输出内容。每一个工作流在完整执行后都需要至少一个结束节点,用于输出完整执行的最终结果。
|
||||
|
||||
结束节点为流程终止节点,后面无法再添加其他节点,工作流应用中只有运行到结束节点才会输出执行结果。若流程中出现条件分叉,则需要定义多个结束节点。
|
||||
|
||||
结束节点需要声明一个或多个输出变量,声明时可以引用任意上游节点的输出变量。
|
||||
## 简介
|
||||
|
||||
<Info>
|
||||
Chatflow 内不支持结束节点。
|
||||
- 输出节点之前称为「结束」节点。与结束节点不同的是,输出节点在 Workflow 中是可选的,仅在需要向最终用户显式返回特定信息时使用即可。
|
||||
|
||||
- 此节点仅适用于 Workflow 应用,而 Chatflow 使用 [直接回复](/zh-hans/guides/workflow/node/answer) 节点在对话流中向用户返回信息。
|
||||
</Info>
|
||||
|
||||
***
|
||||
你可以在输出节点中定义向终端用户返回的内容,例如 LLM 生成的响应。
|
||||
|
||||
### 场景
|
||||
在输出节点中,必须指定至少一个输出变量;否则,不会返回任何内容。
|
||||
|
||||
在以下[长故事生成工作流](/zh-hans/guides/workflow/node/iteration#示例-2:长文章迭代生成器(另一种编排方式))中,结束节点声明的变量 `Output` 为上游代码节点的输出,即该工作流会在 Code3 节点执行完成之后结束,并输出 Code3 的执行结果。
|
||||
|
||||

|
||||
|
||||
**单路执行示例:**
|
||||
|
||||

|
||||
|
||||
**多路执行示例:**
|
||||
|
||||

|
||||
当作为后端服务 API 对外暴露时,没有输出节点的 Workflow 不会向 API 调用方返回任何值。
|
||||
|
||||
{/*
|
||||
Contributing Section
|
||||
|
||||
193
zh-hans/guides/workflow/node/plugin-trigger.mdx
Normal file
@@ -0,0 +1,193 @@
|
||||
---
|
||||
title: 插件触发器
|
||||
---
|
||||
|
||||
## 简介
|
||||
|
||||
<Info>
|
||||
触发器仅适用于 Workflow 应用。
|
||||
</Info>
|
||||
|
||||
插件触发器能够让 Workflow 在特定外部事件发生时自动运行。你只需通过触发器插件订阅事件,并将相应的插件触发器添加到 Workflow 中即可。
|
||||
|
||||
例如,假设你安装了一个 GitHub 触发器插件。它提供许多可订阅的 GitHub 事件,包括 `Pull Request`、`Push` 和 `Issue`。若你订阅了 `Pull Request` 事件,并将对应的 `Pull Request` 插件触发器添加到 Workflow 中,那么每当有人在指定仓库中创建 pull request 时,Workflow 就会自动运行。
|
||||
|
||||
## 添加和配置插件触发器
|
||||
|
||||
1. 在 Workflow 画布上,单击右键并选择 **添加节点** > **开始**,然后选择可用的插件触发器,或在 [Dify 插件市场](https://marketplace.dify.ai/?language=zh-Hans&category=trigger) 中搜索更多插件。
|
||||
|
||||
<Tip>
|
||||
- 若未找到合适的触发器插件,你可以 [向社区请求](https://github.com/langgenius/dify-plugins/issues/new?template=plugin_request.yaml)、[自行开发](/plugin-dev-zh/0222-trigger-plugin),或者改用 [Webhook 触发器](/zh-hans/guides/workflow/node/webhook-trigger)。
|
||||
|
||||
- 一个 Workflow 可同时拥有多个并行的插件触发器。当并行的分支连续包含相同节点时,可在相同部分之前添加 [变量聚合节点](/zh-hans/guides/workflow/node/variable-aggregator) 以合并分支,而无需在每个分支中分别重复添加相同的节点。
|
||||
</Tip>
|
||||
|
||||
2. 选择一个现有订阅或 [创建新订阅](#创建新订阅)。
|
||||
|
||||
<Tip>
|
||||
在 **插件** 页面的插件详情面板中,你可以查看某个特定订阅正在被多少个 Workflow 使用。
|
||||
</Tip>
|
||||
|
||||
3. 配置其他必需设置。
|
||||
|
||||
<Info>
|
||||
插件触发器的输出变量由其触发器插件定义,无法修改。
|
||||
</Info>
|
||||
|
||||
## 创建新订阅
|
||||
|
||||
<Note>
|
||||
订阅一旦创建就无法修改。如需修改,请删除现有订阅并创建新订阅。
|
||||
</Note>
|
||||
|
||||
<Info>
|
||||
每个工作区中,一个触发器插件支持最多创建 10 个订阅。
|
||||
</Info>
|
||||
|
||||
每个订阅都建立在一个 webhook 之上。当你创建订阅时,实际上是在设置一个能够监听外部系统事件的 webhook。
|
||||
|
||||
<Accordion title="什么是 Webhook?">
|
||||
|
||||
Webhook 允许一个系统自动向另一个系统发送实时数据。当某个特定事件发生时,源系统将事件详情打包进一个 HTTP 请求,并发送至目标系统的指定 URL。
|
||||
|
||||
</Accordion>
|
||||
|
||||
Dify 支持通过以下两种方法创建订阅(webhook),但每个插件中的可用选项取决于插件本身的设计。
|
||||
|
||||
- **自动创建**:你只需选择要订阅的事件,Dify 将在外部系统中自动创建相应的 webhook。这需要你先通过 **OAuth** 或 **API key** 对 Dify 进行授权,以便其代表你配置 webhook。
|
||||
|
||||
- **手动创建**:你使用 Dify 提供的回调 URL 自行创建 webhook,无需任何授权。
|
||||
|
||||
<img src="/images/create_subscription_method.png" alt="Ways to Create Subscriptions" width="563" />
|
||||
|
||||
<Tip>
|
||||
创建订阅时,建议选择所有可用的事件。
|
||||
|
||||
仅当关联的订阅中包含触发器对应的事件时,插件触发器才会正常工作。若选择所有可用的事件,后续添加到 Workflow 中的任何插件触发器均可使用同一个订阅,而无需创建新订阅。
|
||||
</Tip>
|
||||
|
||||
<Tabs>
|
||||
<Tab title="通过 OAuth 创建(自动)">
|
||||
|
||||
在 Dify Cloud 上,许多主流触发器插件都有预配置的默认 OAuth 客户端,一键即可授权 Dify。
|
||||
|
||||
在自托管环境中,只能通过自定义 OAuth 客户端进行授权,即你需要在外部系统中自行创建 OAuth 应用。
|
||||
|
||||
<Tabs>
|
||||
<Tab title="默认 OAuth 客户端">
|
||||
|
||||
1. 选择 **通过 OAuth 创建** > **默认** > **保存并授权**。
|
||||
|
||||
<Info>
|
||||
|
||||
**保存** 意味着所选选项将被设置为未来订阅的默认 OAuth 选项。
|
||||
|
||||
如需切换选项,点击 **OAuth 客户端设置** 图标。
|
||||
|
||||
<img src="/images/oauth_client_settings_icon.png" alt="OAuth Client Settings Icon" width="300" />
|
||||
|
||||
</Info>
|
||||
|
||||
2. 在弹出的外部系统授权页面上,点击 **下一步** 以授予 Dify 权限。
|
||||
|
||||
3. 填写订阅名称,选择你想要订阅的事件,并配置其他必需设置。
|
||||
|
||||
<Tip>
|
||||
建议选择所有可用的事件。
|
||||
</Tip>
|
||||
|
||||
4. 点击 **创建**。
|
||||
|
||||
</Tab>
|
||||
|
||||
<Tab title="自定义 OAuth 客户端">
|
||||
|
||||
1. 选择 **通过 OAuth 创建** > **自定义**。
|
||||
|
||||
2. 在外部系统中,使用 Dify 提供的回调 URL 创建一个 OAuth 应用。
|
||||
|
||||
3. 返回 Dify,输入新创建的 OAuth 应用的客户端 ID 和客户端密钥,然后点击 **保存并授权**。
|
||||
|
||||
<Info>
|
||||
保存后,可在未来的订阅中重复使用此客户端凭据。
|
||||
</Info>
|
||||
|
||||
4. 填写订阅名称,选择你想要订阅的事件,并配置其他必需设置。
|
||||
|
||||
<Tip>
|
||||
建议选择所有可用的事件。
|
||||
</Tip>
|
||||
|
||||
5. 点击 **创建**。
|
||||
|
||||
</Tab>
|
||||
|
||||
</Tabs>
|
||||
|
||||
<Info>
|
||||
订阅配置页面上显示的 **回调 URL** 由 Dify 用于代表你在外部系统中创建 webhook。
|
||||
|
||||
你无需对此 URL 执行任何操作。
|
||||
</Info>
|
||||
</Tab>
|
||||
|
||||
<Tab title="通过 API Key 创建(自动)">
|
||||
|
||||
1. 选择 **通过 API Key 创建**。
|
||||
|
||||
2. 输入所需的验证信息,然后点击 **验证**。
|
||||
|
||||
3. 填写订阅名称,选择你想要订阅的事件,并配置其他必需设置。
|
||||
|
||||
<Tip>
|
||||
建议选择所有可用的事件。
|
||||
</Tip>
|
||||
|
||||
4. 点击 **创建**。
|
||||
|
||||
<Info>
|
||||
订阅配置页面上显示的 **回调 URL** 由 Dify 用于代表你在外部系统中创建 webhook。
|
||||
|
||||
你无需对此 URL 执行任何操作。
|
||||
</Info>
|
||||
|
||||
</Tab>
|
||||
|
||||
<Tab title="粘贴 URL 以创建新订阅(手动)">
|
||||
|
||||
1. 选择 **粘贴 URL 以创建新订阅**。
|
||||
|
||||
2. 指定订阅名称,并使用提供的回调 URL 在外部系统中手动创建 webhook。
|
||||
|
||||
3. (可选)测试已创建的 webhook。
|
||||
|
||||
<Info>
|
||||
许多外部系统在新的 webhook 创建后会自动向 Dify 发送 ping 请求以进行测试。
|
||||
</Info>
|
||||
|
||||
1. 手动触发一个订阅的事件,以让外部系统向 Dify 提供的回调 URL 发送 HTTP 请求。
|
||||
|
||||
2. 回到 **手动设置** 页面,查看底部的 **请求日志**。若 webhook 运作正常,你将看到接收到的外部请求与 Dify 的响应。
|
||||
|
||||
<img src="/images/plugin_trigger_manual_setup_request_logs.png" alt="Request Logs" width="563" />
|
||||
|
||||
4. 点击 **创建**。
|
||||
|
||||
</Tab>
|
||||
|
||||
</Tabs>
|
||||
|
||||
## 测试插件触发器
|
||||
|
||||
如需测试未发布的插件触发器,必须先点击 **运行此步骤** 或测试运行整个 Workflow,使触发器进入监听状态。否则,即使订阅的事件发生,也不会被触发器捕获。
|
||||
|
||||
{/*
|
||||
Contributing Section
|
||||
DO NOT edit this section!
|
||||
It will be automatically generated by the script.
|
||||
*/}
|
||||
|
||||
---
|
||||
|
||||
[编辑此页面](https://github.com/langgenius/dify-docs/edit/main/zh-hans/guides/workflow/node/plugin-trigger.mdx) | [提交问题](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)
|
||||
|
||||
114
zh-hans/guides/workflow/node/schedule-trigger.mdx
Normal file
@@ -0,0 +1,114 @@
|
||||
---
|
||||
title: 定时触发器
|
||||
---
|
||||
|
||||
## 简介
|
||||
|
||||
<Info>
|
||||
触发器仅适用于 Workflow 应用。
|
||||
</Info>
|
||||
|
||||
定时触发器能够让 Workflow 在指定的时间自动运行,适用于执行周期性重复任务,如生成每日报告或发送定时通知。
|
||||
|
||||
## 添加定时触发器
|
||||
|
||||
在 Workflow 画布上,单击右键并选择 **添加节点** > **开始** > **定时触发器**。
|
||||
|
||||
<Tip>
|
||||
一个 Workflow 可同时拥有多个并行的定时触发器。当并行的分支连续包含相同节点时,可在相同部分之前添加 [变量聚合节点](/zh-hans/guides/workflow/node/variable-aggregator) 以合并分支,而无需在每个分支中分别重复添加相同的节点。
|
||||
</Tip>
|
||||
|
||||
## 配置定时触发器
|
||||
|
||||
你可以使用默认的可视化配置或 Cron 表达式来配置 Workflow 的运行计划。
|
||||
|
||||
完成配置后,你将看到接下来 5 次的计划运行时间。
|
||||
|
||||
<Info>
|
||||
定时触发器不产生任何输出变量。但每当其触发 Workflow 时,都会更新系统变量 `sys.timestamp`(每次工作流运行的开始时间)。
|
||||
</Info>
|
||||
|
||||
### 使用可视化配置
|
||||
|
||||
适用于简单的时度、日度、周度或月度运行计划。对于周度或月度计划,可同时选择多天。
|
||||
|
||||
### 使用 Cron 表达式
|
||||
|
||||
适用于更复杂和精确的运行计划,例如在工作日的上午 9 点到下午 5 点之间每 15 分钟运行一次。
|
||||
|
||||
<Tip>
|
||||
你可以使用 LLM 来生成 Cron 表达式。
|
||||
</Tip>
|
||||
|
||||
#### 标准格式
|
||||
|
||||
Cron 表达式是一段可用于定义 Workflow 运行计划的字符串,由五个用空格分隔的字段组成,每个字段代表不同的时间单位。
|
||||
|
||||
<Note>
|
||||
确保每个字段之间有一个空格。
|
||||
</Note>
|
||||
|
||||
```
|
||||
* * * * *
|
||||
| | | | |
|
||||
| | | | |── 星期几(0-7 或 SUN-SAT, 0 和 7 均表示星期日)
|
||||
| | | |──── 月份(1-12 或 JAN-DEC)
|
||||
| | |────── 日(1-31)
|
||||
| |──────── 小时(0-23)
|
||||
|────────── 分钟(0-59)
|
||||
```
|
||||
|
||||
<Info>
|
||||
当同时为 **日** 和 **星期几** 字段指定值时,触发器将在匹配 *任一* 字段的日期运行。
|
||||
|
||||
例如,`1 2 3 4 4` 会在 4 月 3 日 *以及* 4 月的每个星期四触发 Workflow,而不仅仅是在 4 月 3 号当天刚好是星期四时触发。
|
||||
</Info>
|
||||
|
||||
#### 特殊字符
|
||||
|
||||
| <div style={{width: '50px'}}>字符</div> | 描述 | 示例 |
|
||||
|:-----------|:-------------|:---------|
|
||||
| `*` | 表示「每个」。 | **小时** 字段中的 `*` 表示「每个小时」。 |
|
||||
| `,` | 分隔多个值。 | **星期几** 字段中的 `1,3,5` 表示「星期一、星期三和星期五」。 |
|
||||
| `-` | 定义值的范围。 | **小时** 字段中的 `9-17` 表示「上午 9 点到下午 5 点」。 |
|
||||
| `/` | 指定步进值。 | **分钟** 字段中的 `*/15` 表示「每 15 分钟」。 |
|
||||
| `L` | 表示「最后」。 <br /><br />在 **日** 字段中,表示「月的最后一天」。<br /><br />在 **星期几** 字段中:<ul><li>单独使用时,表示「周的最后一天」。</li><li>与数字组合使用时,表示「月的最后一个指定的星期几」。</li></ul>| **日** 字段中的 `L` 表示「1 月 31 日、4 月 30 日,或非闰年的 2 月 28 日」。<br /><br />**星期几** 字段中的 `L` 表示「星期日」。<br /><br />**星期几** 字段中的 `5L` 表示「月的最后一个星期五」。 |
|
||||
| `?` | 表示「任意」或「无特定值」。<br /><br />如果你为 **星期几** 字段指定了值,可以用 `?` 来忽略 **日** 字段,反之亦然。<br /><br />非必需,因为 `*` 也可实现相同效果。 | 若要在每个星期一运行,将 **日** 字段设为 `?` 会比设为 `*` 更精确。|
|
||||
|
||||
#### 预定义表达式
|
||||
|
||||
- `@yearly`:每年一次,在 1 月 1 日的凌晨 12 点运行。
|
||||
- `@monthly`:每月一次,在每月第一天的凌晨 12 点运行。
|
||||
- `@weekly`:每周一次,在星期日的凌晨 12 点运行。
|
||||
- `@daily`:每天一次,在凌晨 12 点运行。
|
||||
- `@hourly`:在每小时开始时运行。
|
||||
|
||||
#### 示例
|
||||
|
||||
| 运行时间 | Cron 表达式 |
|
||||
|:----------|:-----------------|
|
||||
| 工作日上午 9 点 | `0 9 * * MON-FRI` or `0 9 * * 1-5` |
|
||||
| 每周三下午 2:30 | `30 14 * * WED` |
|
||||
| 每周日凌晨 12 点 | `0 0 * * 0` |
|
||||
| 每周二每 2 小时一次 | `0 */2 * * 2` |
|
||||
| 每月第一天凌晨 12 点 | `0 0 1 * *` |
|
||||
| 1 月 1 日和 6 月 1 日的中午 12 点 | `0 12 1 JAN,JUN *` |
|
||||
| 每月最后一天下午 5 点 | `0 17 L * *` |
|
||||
| 每月最后一个星期五晚上 10 点 | `0 22 * * 5L` |
|
||||
|
||||
## 测试定时触发器
|
||||
|
||||
当你测试一个定时触发器时(无论是点击 **运行此步骤** 还是选择其用于 Workflow 的测试运行),触发器会立即运行,忽略已配置的时间表。
|
||||
|
||||
然而,当你点击 **测试运行** > **运行所有触发器** 来测试包含多个触发器的 Workflow 时,其中的定时触发器将会等待其下一个计划运行时间,而不会立即运行。
|
||||
|
||||
{/*
|
||||
Contributing Section
|
||||
DO NOT edit this section!
|
||||
It will be automatically generated by the script.
|
||||
*/}
|
||||
|
||||
---
|
||||
|
||||
[编辑此页面](https://github.com/langgenius/dify-docs/edit/main/zh-hans/guides/workflow/node/schedule-trigger.mdx) | [提交问题](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)
|
||||
|
||||
@@ -1,74 +1,23 @@
|
||||
---
|
||||
title: 开始
|
||||
sidebarTitle: "概述"
|
||||
---
|
||||
|
||||
## 定义
|
||||
开始节点是 Workflow 和 Chatflow 的起点。
|
||||
|
||||
**"开始"** 节点是每个工作流应用(Chatflow / Workflow)必备的预设节点,为后续工作流节点以及应用的正常流转提供必要的初始信息,例如应用使用者所输入的内容、以及[上传的文件](/zh-hans/guides/workflow/file-upload)等。
|
||||
Dify 支持两种类型的开始节点,可分别以不同的方式启动你的应用。
|
||||
|
||||
### 配置节点
|
||||
- **[用户输入](/zh-hans/guides/workflow/node/user-input)**:通过用户交互或 API 调用启动应用。
|
||||
|
||||
在开始节点的设置页,你可以看到两部分设置,分别是 **"输入字段"** 和预设的[**系统变量**](/zh-hans/guides/workflow/variables#系统变量)。
|
||||
- **[触发器](/zh-hans/guides/workflow/node/trigger)**(仅适用于 Workflow):应用定时运行,或当特定的第三方事件发生时自动运行。
|
||||
|
||||

|
||||
<Note>
|
||||
只有以用户输入节点为起点的应用,才能被发布为独立的 Web App 或 MCP 服务器、对外暴露为后端服务 API,或作为工具在其他 Dify 应用中使用。
|
||||
</Note>
|
||||
|
||||
### 输入字段
|
||||
|
||||
输入字段功能由应用开发者设置,通常用于让应用使用者主动补全更多信息。例如在周报应用中要求使用者按照格式预先提供更多背景信息,如姓名、工作日期区间、工作详情等。这些前置信息将有助于 LLM 生成质量更高的答复。
|
||||
|
||||
支持以下八种类型输入变量,所有变量均可设置为必填项:
|
||||
|
||||
* **文本**:短文本,由应用使用者自行填写内容,最大长度 256 字符。
|
||||
* **段落**:长文本,允许应用使用者输入较长字符。
|
||||
* **下拉选项**:由应用开发者固定选项,应用使用者仅能选择预设选项,无法自行填写内容。
|
||||
* **数字**:仅允许用户输入数字。
|
||||
* **复选框**:布尔值输入,以复选框形式呈现,允许用户选择真/假值。
|
||||
* **对象**:结构化 JSON 输入,允许用户提供复杂的数据对象。仅在工作流/聊天流应用中可用。
|
||||
* **单文件**:允许应用使用者单独上传文件,支持文档类型文件、图片、音频、视频和其它文件类型。支持通过本地上传文件或粘贴文件 URL。详细用法请参考[文件上传](/zh-hans/guides/workflow/file-upload)。
|
||||
* **文件列表**:允许应用使用者批量上传文件,支持文档类型文件、图片、音频、视频和其它文件类型。支持通过本地上传文件或粘贴文件 URL。详细用法请参考[文件上传](/zh-hans/guides/workflow/file-upload)。
|
||||
|
||||
<Info>
|
||||
Dify 内置的文档提取器节点只能够处理部分格式的文档文件。如需处理图片、音频或视频类型文件,请参考[外部数据工具](/zh-hans/guides/tools/extensions/code-based/external-data-tool)搭建对应文件的处理节点。
|
||||
</Info>
|
||||
|
||||
配置完成后,用户在使用应用前将按照输入项指引,向 LLM 提供必要信息。更多的信息将有助于 LLM 提升问答效率。
|
||||
|
||||

|
||||
|
||||
### 系统变量
|
||||
|
||||
系统变量指的是在 Chatflow / Workflow 应用内预设的系统级参数,可以被应用内的其它节点全局读取。通常用于进阶开发场景,例如搭建多轮次对话应用、收集应用日志与监控、记录不同应用和用户的使用行为等。
|
||||
|
||||
**Workflow**
|
||||
|
||||
Workflow 类型应用提供以下系统变量:
|
||||
|
||||
| 变量名称 | 数据类型 | 说明 | 备注 |
|
||||
|---------|--------|------|------|
|
||||
| `sys.files` [LEGACY] | Array[File] | 文件参数,存储用户初始使用应用时上传的图片 | 图片上传功能需在应用编排页右上角的 "功能" 处开启 |
|
||||
| `sys.user_id` | String | 用户 ID,每个用户在使用工作流应用时,系统会自动向用户分配唯一标识符,用以区分不同的对话用户 | |
|
||||
| `sys.app_id` | String | 应用 ID,系统会向每个 Workflow 应用分配一个唯一的标识符,用以区分不同的应用,并通过此参数记录当前应用的基本信息 | 面向具备开发能力的用户,通过此参数区分并定位不同的 Workflow 应用 |
|
||||
| `sys.workflow_id` | String | Workflow ID,用于记录当前 Workflow 应用内所包含的所有节点信息 | 面向具备开发能力的用户,可以通过此参数追踪并记录 Workflow 内的包含节点信息 |
|
||||
| `sys.workflow_run_id` | String | Workflow 应用运行 ID,用于记录 Workflow 应用中的运行情况 | 面向具备开发能力的用户,可以通过此参数追踪应用的历次运行情况 |
|
||||
|
||||

|
||||
|
||||
**Chatflow**
|
||||
|
||||
Chatflow 类型应用提供以下系统变量:
|
||||
|
||||
| 变量名称 | 数据类型 | 说明 | 备注 |
|
||||
|---------|--------|------|------|
|
||||
| `sys.query` | String | 用户在对话框中初始输入的内容 | |
|
||||
| `sys.files` | Array[File] | 用户在对话框内上传的文件 | 文件上传功能需在应用编排页右上角的 "功能" 处开启 |
|
||||
| `sys.dialogue_count` | Number | 用户在与 Chatflow 类型应用交互时的对话轮数。每轮对话后自动计数增加 1,可以和 if-else 节点搭配出丰富的分支逻辑。例如到第 X 轮对话时,回顾历史对话并给出分析 | |
|
||||
| `sys.conversation_id` | String | 对话框交互会话的唯一标识符,将所有相关的消息分组到同一个对话中,确保 LLM 针对同一个主题和上下文持续对话 | |
|
||||
| `sys.user_id` | String | 分配给每个应用用户的唯一标识符,用以区分不同的对话用户 | |
|
||||
| `sys.app_id` | String | 应用 ID,系统会向每个 Workflow 应用分配一个唯一的标识符,用以区分不同的应用,并通过此参数记录当前应用的基本信息 | 面向具备开发能力的用户,通过此参数区分并定位不同的 Workflow 应用 |
|
||||
| `sys.workflow_id` | String | Workflow ID,用于记录当前 Workflow 应用内所包含的所有节点信息 | 面向具备开发能力的用户,可以通过此参数追踪并记录 Workflow 内的包含节点信息 |
|
||||
| `sys.workflow_run_id` | String | Workflow 应用运行 ID,用于记录 Workflow 应用中的运行情况 | 面向具备开发能力的用户,可以通过此参数追踪应用的历次运行情况 |
|
||||
|
||||

|
||||
<Tip>
|
||||
一个 Workflow 中可同时包含用户输入节点和触发器节点作为并行起点。
|
||||
</Tip>
|
||||
|
||||
{/*
|
||||
Contributing Section
|
||||
|
||||
81
zh-hans/guides/workflow/node/trigger.mdx
Normal file
@@ -0,0 +1,81 @@
|
||||
---
|
||||
title: 触发器
|
||||
sidebarTitle: "概述"
|
||||
---
|
||||
|
||||
## 简介
|
||||
|
||||
<Info>
|
||||
触发器仅适用于 Workflow 应用。
|
||||
</Info>
|
||||
|
||||
触发器是一种开始节点,能够使 Workflow 定时运行或当外部系统(例如 GitHub、Gmail 或你自己的内部系统)的特定事件发生时自动运行,而不是只能通过用户交互或 API 调用才能启动。
|
||||
|
||||
基于以上特性,触发器可用于自动执行重复任务,或将 Workflow 与第三方系统集成以实现自动化数据同步与处理。
|
||||
|
||||
一个 Workflow 可同时拥有多个并行的触发器。你也可以在同一画布上构建多个独立的、以不同触发器作为起点的 Workflow。
|
||||
|
||||
每次 Workflow 执行的触发源将显示在 **日志** 中。
|
||||
|
||||
<img src="/images/trigger.png" alt="Trigger" width="450" />
|
||||
|
||||
## 触发器类型
|
||||
|
||||
- [定时触发器](/zh-hans/guides/workflow/node/schedule-trigger)
|
||||
|
||||
- 在指定的时间点自动运行 Workflow。
|
||||
|
||||
- 示例:每天早上 9 点自动生成销售报告,并通过电子邮件发送给团队成员。
|
||||
|
||||
- [插件触发器](/zh-hans/guides/workflow/node/plugin-trigger)
|
||||
|
||||
- 通过触发器插件订阅外部系统的特定事件,当订阅事件发生时自动运行 Workflow。
|
||||
|
||||
- 示例:通过订阅 Slack 触发器插件中的`频道中的新消息`事件,自动分析并归档特定频道中的新消息。
|
||||
|
||||
- [Webhook 触发器](/zh-hans/guides/workflow/node/webhook-trigger)
|
||||
|
||||
- 通过自定义 webhook 订阅外部系统的特定事件,当订阅事件发生时自动运行 Workflow。
|
||||
|
||||
- 示例:当电商平台通过 HTTP 请求发送包含订单详情的新订单时,自动处理该订单。
|
||||
|
||||
<Tip>
|
||||
插件触发器和 Webhook 触发器均可让 Workflow 具备 *事件驱动*(基于事件运行)的特性。选择时,可参考以下思路:
|
||||
|
||||
1. 当你的目标外部系统有可用的触发器插件时,使用 **插件触发器**。你只需订阅该插件中支持的事件即可。
|
||||
|
||||
2. 当没有合适的插件或需要订阅现有插件不支持的事件时,使用 **Webhook 触发器**。此时,你需要在外部系统中自行配置 webhook。
|
||||
</Tip>
|
||||
|
||||
## 启用或禁用触发器
|
||||
|
||||
在右侧调出的 **快捷设置** 菜单中,你可以启用或禁用 *已发布* 的触发器。被禁用的触发器不会触发 Workflow。
|
||||
|
||||
<Info>
|
||||
只有已发布的触发器才会出现在 **快捷设置** 中。若未看到某个已添加的触发器,请先确保它已被发布。
|
||||
</Info>
|
||||
|
||||
<img src="/images/enable_disable_added_trigger.png" alt="Enable or Disable Published Triggers" width="500" />
|
||||
|
||||
## 测试多个触发器
|
||||
|
||||
当一个 Workflow 有多个触发器时,可点击 **测试运行** > **运行所有触发器** 以测试所有触发器。第一个运行的触发器将启动 Workflow,其余触发器将被忽略。
|
||||
|
||||
点击 **运行所有触发器** 后:
|
||||
|
||||
- 定时触发器将在下一个计划时间运行。
|
||||
|
||||
- 插件触发器将开始监听已订阅的事件。
|
||||
|
||||
- Webhook 触发器将开始监听外部 HTTP 请求。
|
||||
|
||||
{/*
|
||||
Contributing Section
|
||||
DO NOT edit this section!
|
||||
It will be automatically generated by the script.
|
||||
*/}
|
||||
|
||||
---
|
||||
|
||||
[编辑此页面](https://github.com/langgenius/dify-docs/edit/main/zh-hans/guides/workflow/node/trigger.mdx) | [提交问题](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)
|
||||
|
||||
124
zh-hans/guides/workflow/node/user-input.mdx
Normal file
@@ -0,0 +1,124 @@
|
||||
---
|
||||
title: 用户输入
|
||||
---
|
||||
|
||||
## 简介
|
||||
|
||||
用户输入节点是一种开始节点,可用于定义在终端用户运行应用时需要向其收集的信息。
|
||||
|
||||
以用户输入为起点的应用采用 *按需运行* 的方式,通过用户的直接交互或 API 调用启动。你也可以将此类应用发布为独立的 Web 应用或 MCP 服务器,通过后端服务 API 对外暴露,或作为工具在其他 Dify 应用中使用。
|
||||
|
||||
<Info>
|
||||
每个应用画布只能包含一个用户输入节点。
|
||||
</Info>
|
||||
|
||||
## 输入变量
|
||||
|
||||
### 预设
|
||||
|
||||
预设输入变量由系统定义并默认可用。
|
||||
|
||||
- `userinput.files`:终端用户在运行应用时上传的文件。
|
||||
|
||||
<Note>
|
||||
对于 Workflow 应用,此预设变量已被视为*遗留功能*,仅为向后兼容而保留。
|
||||
|
||||
我们推荐使用自定义的 [文件输入字段](#文件输入) 来收集用户文件。
|
||||
</Note>
|
||||
|
||||
- `userinput.query`(仅适用于 Chatflow):从最新一轮对话中自动捕获的用户文本消息。
|
||||
|
||||
### 自定义
|
||||
|
||||
你可以在用户输入节点中配置自定义输入字段,以收集终端用户的信息。每个字段都会成为一个下游节点可引用的变量。例如,若添加了一个变量名为 `user_name` 的输入字段,即可在整个 Workflow 中以 `{{user_name}}` 的形式引用它。
|
||||
|
||||
用户输入字段共有七种类型,可分别用于处理不同形式的输入信息。
|
||||
|
||||
<Info>
|
||||
**显示名称** 将会展示给终端用户。
|
||||
</Info>
|
||||
|
||||
<Tip>
|
||||
在 Chatflow 应用中,可 **隐藏** 任意输入变量,使其对终端用户不可见,但仍可在 Chatflow 内部被引用。
|
||||
</Tip>
|
||||
|
||||
#### 文本输入
|
||||
|
||||
<Tabs>
|
||||
|
||||
<Tab title="文本">
|
||||
文本字段最多可输入 256 个字符,适用于姓名、电子邮件地址、标题或任何适合单行输入的简短文本。
|
||||
</Tab>
|
||||
|
||||
<Tab title="段落">
|
||||
段落字段允许输入多行文本,无长度限制,适用于详细的回复或描述。
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
#### 结构化输入
|
||||
|
||||
<Tabs>
|
||||
|
||||
<Tab title="下拉选项">
|
||||
下拉选项字段以下拉菜单的形式显示预定义选项。用户只能从列表中进行选择,从而确保数据一致性并防止无效输入。
|
||||
|
||||
</Tab>
|
||||
|
||||
<Tab title="数字">
|
||||
数字字段仅允许输入数值,适用于数量、评分、ID 或任何需要数学处理的数据。
|
||||
</Tab>
|
||||
|
||||
<Tab title="复选框">
|
||||
复选框字段提供一个简单的「是/否」选项,勾选时输出 `true`,未勾选时输出 `false`,适用于确认或任何需要二元选择的场景。
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
#### 文件输入
|
||||
|
||||
<Tabs>
|
||||
<Tab title="单文件">
|
||||
单文件字段允许用户从其设备或通过文件 URL 上传单个文件,上传的文件将成为一个包含文件元数据(名称、大小、类型等)的变量。
|
||||
</Tab>
|
||||
|
||||
<Tab title="文件列表">
|
||||
文件列表字段与单文件类似,但支持一次上传多个文件,适用于批量处理文档、图片等文件的场景。
|
||||
<Tip>
|
||||
可使用 [列表操作节点](/zh-hans/guides/workflow/node/list-operator) 对上传的文件列表进行筛选、排序或提取特定文件,以便进一步处理。
|
||||
</Tip>
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
**文件处理**
|
||||
|
||||
通过用户输入节点上传的文件必须由后续节点进行适当处理。用户输入节点只负责收集文件,无法直接读取或解析文件内容。
|
||||
|
||||
因此,需要通过特定节点来提取和处理文件内容。例如:
|
||||
|
||||
- 文档文件可传递给文档提取器节点进行文本提取,以便 LLM 能够理解其内容。
|
||||
|
||||
- 图片可发送到具备视觉能力的 LLM 节点或专门的图像处理工具节点。
|
||||
|
||||
- 结构化数据文件(如 CSV 或 JSON)可使用代码节点进行解析和转换。
|
||||
|
||||
<Tip>
|
||||
当用户上传多个混合类型的文件(如图片和文档)时,可使用列表操作节点按文件类型对其进行分离,再分别路由到合适的处理分支。
|
||||
</Tip>
|
||||
|
||||
## 下一步
|
||||
|
||||
设置好用户输入节点后,可将其连接到其他节点以处理收集到的数据。常见的场景包括:
|
||||
|
||||
- 将输入发送到 LLM 节点进行处理。
|
||||
- 使用知识检索节点根据输入查找相关信息。
|
||||
- 根据输入,使用条件分支节点将执行路径路由到不同的分支。
|
||||
|
||||
{/*
|
||||
Contributing Section
|
||||
DO NOT edit this section!
|
||||
It will be automatically generated by the script.
|
||||
*/}
|
||||
|
||||
---
|
||||
|
||||
[编辑此页面](https://github.com/langgenius/dify-docs/edit/main/zh-hans/guides/workflow/node/user-input.mdx) | [提交问题](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)
|
||||
|
||||
195
zh-hans/guides/workflow/node/webhook-trigger.mdx
Normal file
@@ -0,0 +1,195 @@
|
||||
---
|
||||
title: Webhook 触发器
|
||||
---
|
||||
|
||||
## 简介
|
||||
|
||||
<Info>
|
||||
触发器仅适用于 Workflow 应用。
|
||||
</Info>
|
||||
|
||||
Webhook 允许一个系统自动向另一个系统发送实时数据。当某个特定事件发生时,源系统将事件详情打包进一个 HTTP 请求,并发送至目标系统的指定 URL。
|
||||
|
||||
遵循相同的机制,Webhook 触发器能够让 Workflow 在外部事件发生时自动运行:
|
||||
|
||||
1. 在 Workflow 中添加 Webhook 触发器后,系统将自动生成一个 webhook URL 作为监听外部 HTTP 请求的专用端点。
|
||||
|
||||
2. 你使用此 URL 在外部系统中创建一个 webhook,订阅期望关注的事件。然后,在 Dify 中配置 Webhook 触发器,定义其如何处理接收到的请求并提取请求中的事件数据。
|
||||
|
||||
3. 当订阅的事件发生时,外部系统会将包含事件数据的 HTTP 请求发送到先前提供的 webhook URL。一旦请求被成功接收和处理,你的 Workflow 会被触发,而提取到的事件数据也将成为下游节点可引用的变量。
|
||||
|
||||
<Note>
|
||||
在测试场景中,请始终使用测试专用的 webhook URL,以分离测试与生产数据。
|
||||
<img src="/images/test_webhook_url.png" alt="Test Webhook URL" width="563" />
|
||||
</Note>
|
||||
|
||||
<Tip>
|
||||
若目标外部系统有可用的触发器插件,我们推荐改用 [插件触发器](/zh-hans/guides/workflow/node/plugin-trigger)。
|
||||
</Tip>
|
||||
|
||||
## 添加 Webhook 触发器
|
||||
|
||||
在 Workflow 画布上,单击右键并选择 **添加节点** > **开始** > **Webhook 触发器**。
|
||||
|
||||
<Tip>
|
||||
一个 Workflow 可同时拥有多个并行的 Webhook 触发器。当并行的分支连续包含相同节点时,可在相同部分之前添加 [变量聚合节点](/zh-hans/guides/workflow/node/variable-aggregator) 以合并分支,而无需在每个分支中分别重复添加相同的节点。
|
||||
</Tip>
|
||||
|
||||
## 配置 Webhook 触发器
|
||||
|
||||
你可以定义 Webhook 触发器如何处理接收到的 HTTP 请求,包括:
|
||||
|
||||
- Webhook URL 接受的 HTTP 方法
|
||||
|
||||
- 请求的内容类型
|
||||
|
||||
- 需要从请求中提取的事件数据
|
||||
|
||||
- 当 Workflow 成功触发时,返回至外部系统的响应
|
||||
|
||||
<Note>
|
||||
如需测试未发布的 Webhook 触发器,必须先点击 **运行此步骤** 或测试运行整个 Workflow,使触发器进入监听状态。否则,将无法接收到外部请求。
|
||||
</Note>
|
||||
|
||||
### HTTP 方法
|
||||
|
||||
为了确保传入的请求被成功接收,需指定 webhook URL 接受的 HTTP 方法。
|
||||
|
||||
在此处选择的方法,必须与外部系统发送请求时使用的方法一致。否则,请求将被拒绝。
|
||||
|
||||
<Tip>
|
||||
通常,你可以在外部系统的 webhook 文档或设置界面中找到该信息。
|
||||
</Tip>
|
||||
|
||||
### 内容类型
|
||||
|
||||
为了确保请求体被正确解析且特定数据被成功提取,需指定外部请求的预期内容类型。
|
||||
|
||||
在此处选择的内容类型,必须与外部系统发送的请求的内容类型一致。否则,请求将被拒绝。
|
||||
|
||||
### 查询参数、请求头参数和请求体参数
|
||||
|
||||
你可以从传入请求的查询参数、请求头和请求体中提取特定参数。**每个提取出的参数都将成为一个输出变量,可供下游节点引用。**
|
||||
|
||||
许多外部系统支持查看已发出请求的日志,可在其中浏览请求包含的所有数据,并确定需要提取的参数。
|
||||
|
||||
或者,你也可以让外部系统向 Webhook 触发器发送测试请求,然后在触发器的 **上次运行** 日志中查看接收到的请求数据:
|
||||
|
||||
1. 使用 Dify 提供的测试专用 webhook URL 在外部系统中创建一个 webhook。
|
||||
|
||||
2. 在触发器中设置正确的 HTTP 方法和内容类型。
|
||||
|
||||
3. 点击触发器的 **运行此步骤** 图标,使其开始监听外部请求。
|
||||
|
||||
4. 在外部系统中手动触发已订阅的事件,使其向 Dify 的 webhook URL 发送 HTTP 请求。
|
||||
|
||||
5. 点开触发器的 **上次运行** 日志,在 **输入** 中查看接收到的请求数据。
|
||||
|
||||
<Note>
|
||||
在触发器内定义的变量名,必须与请求中对应参数的键名一致。
|
||||
</Note>
|
||||
|
||||
<Tabs>
|
||||
<Tab title="查询参数">
|
||||
|
||||
- 外部系统在发送请求时添加到 webhook URL(`?` 之后)的键值对参数,每对参数之间用 `&` 分隔。
|
||||
|
||||
- 通常是关于事件的简单、非敏感的标识符或过滤数据。
|
||||
|
||||
- 示例:从 URL `{webhook url}?userID=u-456&source=email` 中,可提取 `userID`(`u-456`)或 `source`(`email`)。
|
||||
</Tab>
|
||||
<Tab title="请求头参数">
|
||||
|
||||
- 包含在请求头中的请求元数据。
|
||||
|
||||
- 处理请求所需的技术信息,例如身份验证令牌或请求体的内容类型。
|
||||
|
||||
- 示例:从类似 `Authorization: Bearer sk-abc...` 和 `Content-Type: application/json` 的请求头中,可提取授权信息(`Bearer sk-abc...`)或内容类型(`application/json`)。
|
||||
</Tab>
|
||||
<Tab title="请求体参数">
|
||||
|
||||
- 发送核心事件数据的主要有效负载,例如客户资料、订单详情或 Slack 消息的具体内容。
|
||||
|
||||
- 示例:从以下请求体中,可提取 `customerName`(`Alex`)、`items` 列表或 `isPriority` 状态(`true`)。
|
||||
|
||||
```JSON
|
||||
"customerName": "Alex",
|
||||
"items":
|
||||
[
|
||||
{ "sku": "A42", "quantity": 2 },
|
||||
{ "sku": "B12", "quantity": 1 }
|
||||
],
|
||||
"isPriority": true
|
||||
```
|
||||
|
||||
<Info>
|
||||
可从请求体中提取的参数数据类型,取决于请求的内容类型。
|
||||
|
||||
| 内容类型 | `String` | `Number` | `Boolean` | `Object` | `File` | `Array[String]` | `Array[Number]` | `Array[Boolean]` | `Array[Object]` | `Array[File]` |
|
||||
|:--------------|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|
|
||||
| application/json | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ |
|
||||
| application/x-www-form-urlencoded | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ | ❌ | ❌ |
|
||||
| multipart/form-data | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ |
|
||||
| text/plain | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
||||
</Info>
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
**参数设置**
|
||||
|
||||
对于要提取的每个参数,可进行以下设置:
|
||||
|
||||
- **变量名**:请求中对应参数的键名(例如,`userID=u-456` 中的 `userID`)。
|
||||
|
||||
<Note>
|
||||
对于请求头参数,变量名中的任何连字符(`-`)将在输出变量中自动转换为下划线(`_`)。
|
||||
</Note>
|
||||
|
||||
- **类型**: 预期的数据格式。仅适用于查询参数和请求体参数,因为请求头参数的格式始终被视为字符串。
|
||||
|
||||
- **必填**: 该参数是否对你的 Workflow 是必需的。若传入请求中缺少任何必填参数,Workflow 将不会被触发。
|
||||
|
||||
### 响应
|
||||
|
||||
默认情况下,当 Workflow 被外部请求成功触发时,Dify 会向外部系统返回如下 `200 OK` 响应:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"status":"success","message":"Webhook processed successfully"
|
||||
}
|
||||
```
|
||||
|
||||
若外部系统对成功响应的格式有特定要求,你可以自定义其状态码和响应体。默认响应将被覆盖。
|
||||
|
||||
- **状态码**: 支持 [200, 399] 范围内的任何状态码。
|
||||
|
||||
- **响应体**: 支持 JSON 或纯文本。
|
||||
|
||||
<Note>
|
||||
在返回的响应体中,非 JSON 内容将自动转换为 JSON。
|
||||
|
||||
例如,`OK` 将被转换为 `"message": "OK"`。
|
||||
</Note>
|
||||
|
||||
<Info>
|
||||
以下错误响应由系统定义,无法自定义。错误详情可在响应体中查看。
|
||||
- 400 Bad Request
|
||||
- 404 Not Found
|
||||
- 413 Payload Too Large
|
||||
- 500 Internal Server Error
|
||||
</Info>
|
||||
|
||||
## 测试 Webhook 触发器
|
||||
|
||||
如需测试未发布的 Webhook 触发器,必须先点击 **运行此步骤** 或测试运行整个 Workflow,使触发器进入监听状态。否则,将无法接收到外部请求。
|
||||
|
||||
{/*
|
||||
Contributing Section
|
||||
DO NOT edit this section!
|
||||
It will be automatically generated by the script.
|
||||
*/}
|
||||
|
||||
---
|
||||
|
||||
[编辑此页面](https://github.com/langgenius/dify-docs/edit/main/zh-hans/guides/workflow/node/webhook-trigger.mdx) | [提交问题](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)
|
||||
|
||||
@@ -2,131 +2,41 @@
|
||||
title: 变量
|
||||
---
|
||||
|
||||
Workflow 和 Chatflow 类型应用由独立节点相构成。大部分节点设有输入和输出项,但每个节点的输入信息不一致,各个节点所输出的答复也不尽相同。
|
||||
变量是一个带标签的数据容器,用于在你的 Workflow 或 Chatflow 中存储信息。每个变量保存一条数据——无论是用户输入、系统生成的值,还是来自前面节点的输出。当你在后续节点中需要使用这些信息时,只需通过变量名引用即可。
|
||||
|
||||
如何用一种固定的符号**指代动态变化的内容?** 变量作为一种动态数据容器,能够存储和传递不固定的内容,在不同的节点内被相互引用,实现信息在节点间的灵活通信。
|
||||
在构建应用时,你将用到不同类型的变量,每种变量都在应用的数据流中承担特定的作用。
|
||||
|
||||
## 变量类型
|
||||
|
||||
### **系统变量**
|
||||
### 系统变量
|
||||
|
||||
系统变量指的是在 Chatflow / Workflow 应用内预设的系统级参数,可以被其它节点全局读取。系统级变量均以 `sys` 开头。
|
||||
系统变量是预设的系统级参数,可在全局范围内使用。
|
||||
|
||||
**Workflow**
|
||||
<Tabs>
|
||||
<Tab title="Workflow">
|
||||
|
||||
Workflow 类型应用提供以下系统变量:
|
||||
| 变量名称 | <div style={{width: '60px'}}>数据类型</div> | 说明 | 备注 |
|
||||
|:----------------|:-----------|:-------------|:--------|
|
||||
| `sys.user_id` | String | 用户 ID,每个用户在使用工作流应用时,系统会自动向用户分配唯一标识符,用以区分不同的对话用户。 | |
|
||||
| `sys.app_id` | String | 应用 ID,系统会向每个 Workflow 应用分配一个唯一的标识符,用以区分不同的应用,并通过此参数记录当前应用的基本信息。| 面向具备开发能力的用户,通过此参数区分并定位不同的 Workflow 应用。 |
|
||||
| `sys.workflow_id` | String | Workflow ID,用于记录当前 Workflow 应用内所包含的所有节点信息。 | 面向具备开发能力的用户,可以通过此参数追踪并记录 Workflow 内的包含节点信息。 |
|
||||
| `sys.workflow_run_id` | String | Workflow 应用运行 ID,用于记录 Workflow 应用中的运行情况。 | 面向具备开发能力的用户,可以通过此参数追踪应用的历次运行情况。 |
|
||||
| `sys.timestamp` | String | 每次 workflow 运行的开始时间。 | |
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="193">变量名称</th>
|
||||
<th width="116">数据类型</th>
|
||||
<th width="278">说明</th>
|
||||
<th>备注</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><p><code>sys.files</code></p><p><code>[LEGACY]</code></p></td>
|
||||
<td>Array[File]</td>
|
||||
<td>文件参数,存储用户初始使用应用时上传的图片</td>
|
||||
<td>图片上传功能需在应用编排页右上角的 "功能" 处开启</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>sys.user_id</code></td>
|
||||
<td>String</td>
|
||||
<td>用户 ID,每个用户在使用工作流应用时,系统会自动向用户分配唯一标识符,用以区分不同的对话用户</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>sys.app_id</code></td>
|
||||
<td>String</td>
|
||||
<td>应用 ID,系统会向每个 Workflow 应用分配一个唯一的标识符,用以区分不同的应用,并通过此参数记录当前应用的基本信息</td>
|
||||
<td>面向具备开发能力的用户,通过此参数区分并定位不同的 Workflow 应用</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>sys.workflow_id</code></td>
|
||||
<td>String</td>
|
||||
<td>Workflow ID,用于记录当前 Workflow 应用内所包含的所有节点信息</td>
|
||||
<td>面向具备开发能力的用户,可以通过此参数追踪并记录 Workflow 内的包含节点信息</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>sys.workflow_run_id</code></td>
|
||||
<td>String</td>
|
||||
<td>Workflow 应用运行 ID,用于记录 Workflow 应用中的运行情况</td>
|
||||
<td>面向具备开发能力的用户,可以通过此参数追踪应用的历次运行情况</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</Tab>
|
||||
<Tab title="Chatflow">
|
||||
|
||||
| 变量名称 | <div style={{width: '60px'}}>数据类型</div> | 说明 | 备注 |
|
||||
|:----------------|:-----------|:-------------|:--------|
|
||||
| `sys.conversation_id` | String | 对话框交互会话的唯一标识符,将所有相关的消息分组到同一个对话中,确保 LLM 针对同一个主题和上下文持续对话。 | |
|
||||
| `sys.dialogue_count` | Number | 用户在与 Chatflow 类型应用交互时的对话轮数。每轮对话后自动计数增加 1,可以和 IF-ELSE 节点搭配出丰富的分支逻辑。 <br /><br />例如到第 X 轮对话时,回顾历史对话并给出分析。 | |
|
||||
| `sys.user_id` | String | 分配给每个应用用户的唯一标识符,用以区分不同的对话用户。 | Service API 不共享 WebApp 创建的对话。这意味着具有相同 ID 的用户在 API 和 WebApp 界面之间会有独立的对话历史。 |
|
||||
| `sys.app_id` | String | 应用 ID,系统会向每个 Workflow 应用分配一个唯一的标识符,用以区分不同的应用,并通过此参数记录当前应用的基本信息。 | 面向具备开发能力的用户,通过此参数区分并定位不同的 Workflow 应用。 |
|
||||
| `sys.workflow_id` | String | Workflow ID,用于记录当前 Workflow 应用内所包含的所有节点信息。 | 面向具备开发能力的用户,可以通过此参数追踪并记录 Workflow 内的包含节点信息。 |
|
||||
| `sys.workflow_run_id` | String | Workflow 应用运行 ID,用于记录 Workflow 应用中的运行情况。 | 面向具备开发能力的用户,可以通过此参数追踪应用的历次运行情况。 |
|
||||
|
||||

|
||||
|
||||
**Chatflow**
|
||||
|
||||
Chatflow 类型应用提供以下系统变量:
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>变量名称</th>
|
||||
<th width="127">数据类型</th>
|
||||
<th width="283">说明</th>
|
||||
<th>备注</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>sys.query</code></td>
|
||||
<td>String</td>
|
||||
<td>用户在对话框中初始输入的内容</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>sys.files</code></td>
|
||||
<td>Array[File]</td>
|
||||
<td>用户在对话框内上传的图片</td>
|
||||
<td>图片上传功能需在应用编排页右上角的 "功能" 处开启</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>sys.dialogue_count</code></td>
|
||||
<td>Number</td>
|
||||
<td><p>用户在与 Chatflow 类型应用交互时的对话轮数。每轮对话后自动计数增加 1,可以和 if-else 节点搭配出丰富的分支逻辑。</p><p>例如到第 X 轮对话时,回顾历史对话并给出分析</p></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>sys.conversation_id</code></td>
|
||||
<td>String</td>
|
||||
<td>对话框交互会话的唯一标识符,将所有相关的消息分组到同一个对话中,确保 LLM 针对同一个主题和上下文持续对话</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>sys.user_id</code></td>
|
||||
<td>String</td>
|
||||
<td>分配给每个应用用户的唯一标识符,用以区分不同的对话用户<br /><br /><strong>注意</strong>:Service API 不共享 WebApp 创建的对话。这意味着具有相同 ID 的用户在 API 和 WebApp 界面之间会有独立的对话历史。</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>sys.app_id</code></td>
|
||||
<td>String</td>
|
||||
<td>应用 ID,系统会向每个 Workflow 应用分配一个唯一的标识符,用以区分不同的应用,并通过此参数记录当前应用的基本信息</td>
|
||||
<td>面向具备开发能力的用户,通过此参数区分并定位不同的 Workflow 应用</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>sys.workflow_id</code></td>
|
||||
<td>String</td>
|
||||
<td>Workflow ID,用于记录当前 Workflow 应用内所包含的所有节点信息</td>
|
||||
<td>面向具备开发能力的用户,可以通过此参数追踪并记录 Workflow 内的包含节点信息</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>sys.workflow_run_id</code></td>
|
||||
<td>String</td>
|
||||
<td>Workflow 应用运行 ID,用于记录 Workflow 应用中的运行情况</td>
|
||||
<td>面向具备开发能力的用户,可以通过此参数追踪应用的历次运行情况</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||

|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### 环境变量
|
||||
|
||||
|
||||