refactor(trigger): rename trigger references to event for consistency

- Updated variable names and types from 'trigger' to 'event' across multiple files to enhance clarity and maintain consistency in the codebase.
- Adjusted related data structures and API responses to reflect the new naming convention.
- Improved type annotations and error handling in the workflow trigger run API and associated services.
This commit is contained in:
Harry 2025-10-09 03:12:35 +08:00
parent a33d04d1ac
commit 91318d3d04
22 changed files with 114 additions and 96 deletions

View File

@ -31,6 +31,7 @@ from libs.login import current_user, login_required
from models import App
from models.account import Account
from models.model import AppMode
from models.provider_ids import TriggerProviderID
from models.workflow import NodeType, Workflow
from services.app_generate_service import AppGenerateService
from services.errors.app import WorkflowHashNotEqualError
@ -1091,8 +1092,6 @@ class DraftWorkflowTriggerRunApi(Resource):
"DraftWorkflowTriggerRunRequest",
{
"node_id": fields.String(required=True, description="Node ID"),
"trigger_name": fields.String(required=True, description="Trigger name"),
"subscription_id": fields.String(required=True, description="Subscription ID"),
},
)
)
@ -1112,17 +1111,33 @@ class DraftWorkflowTriggerRunApi(Resource):
parser = reqparse.RequestParser()
parser.add_argument("node_id", type=str, required=True, location="json", nullable=False)
parser.add_argument("trigger_name", type=str, required=True, location="json", nullable=False)
parser.add_argument("subscription_id", type=str, required=True, location="json", nullable=False)
args = parser.parse_args()
node_id = args["node_id"]
trigger_name = args["trigger_name"]
subscription_id = args["subscription_id"]
workflow_service = WorkflowService()
workflow: Workflow | None = workflow_service.get_draft_workflow(
app_model=app_model,
workflow_id=None,
)
pool_key = PluginTriggerDebugEvent.build_pool_key(
if not workflow:
return jsonable_encoder({"status": "error", "message": "Workflow not found"}), 404
node_data = workflow.get_node_config_by_id(node_id=node_id).get("data")
if not node_data:
return jsonable_encoder({"status": "error", "message": "Node config not found"}), 404
event_name = node_data.get("event_name")
subscription_id = node_data.get("subscription_id")
if not subscription_id:
return jsonable_encoder({"status": "error", "message": "Subscription ID not found"}), 404
# TODO Frontend data management is completely messy here
provider_id = TriggerProviderID(node_data.get("provider_name"))
pool_key: str = PluginTriggerDebugEvent.build_pool_key(
tenant_id=app_model.tenant_id,
provider_id=provider_id,
subscription_id=subscription_id,
trigger_name=trigger_name,
event_name=event_name,
)
event: PluginTriggerDebugEvent | None = TriggerDebugService.poll(
event_type=PluginTriggerDebugEvent,

View File

@ -251,7 +251,7 @@ class TriggerInvokeResponse(BaseModel):
class PluginTriggerDispatchResponse(BaseModel):
triggers: list[str]
events: list[str]
raw_http_response: str

View File

@ -259,9 +259,9 @@ class PluginTriggerProviderController:
:return: Dispatch response with triggers and raw HTTP response
"""
manager = PluginTriggerManager()
provider_id = self.get_provider_id()
provider_id: TriggerProviderID = self.get_provider_id()
response = manager.dispatch_event(
response: TriggerDispatchResponse = manager.dispatch_event(
tenant_id=self.tenant_id,
user_id=user_id,
provider=str(provider_id),

View File

@ -13,7 +13,7 @@ class PluginTriggerData(BaseNodeData):
desc: Optional[str] = None
plugin_id: str = Field(..., description="Plugin ID")
provider_id: str = Field(..., description="Provider ID")
trigger_name: str = Field(..., description="Trigger name")
event_name: str = Field(..., description="Event name")
subscription_id: str = Field(..., description="Subscription ID")
plugin_unique_identifier: str = Field(..., description="Plugin unique identifier")
parameters: dict[str, Any] = Field(default_factory=dict, description="Trigger parameters")

View File

@ -43,7 +43,7 @@ class TriggerPluginNode(Node):
"config": {
"plugin_id": "",
"provider_id": "",
"trigger_name": "",
"event_name": "",
"subscription_id": "",
"parameters": {},
},
@ -67,7 +67,7 @@ class TriggerPluginNode(Node):
WorkflowNodeExecutionMetadataKey.TRIGGER_INFO: {
**trigger_inputs,
"provider_id": self._node_data.provider_id,
"trigger_name": self._node_data.trigger_name,
"event_name": self._node_data.event_name,
"plugin_unique_identifier": self._node_data.plugin_unique_identifier,
},
}

View File

@ -98,6 +98,7 @@ def init_app(app: DifyApp) -> Celery:
imports = [
"tasks.async_workflow_tasks", # trigger workers
"tasks.trigger_processing_tasks", # async trigger processing
]
day = dify_config.CELERY_BEAT_SCHEDULER_TIME

View File

@ -49,13 +49,15 @@ class PluginTriggerDebugEvent(BaseDebugEvent):
Args:
tenant_id: Tenant ID
provider_id: Provider ID
subscription_id: Subscription ID
trigger_name: Trigger name
event_name: Event name
"""
tenant_id = kwargs["tenant_id"]
provider_id = kwargs["provider_id"]
subscription_id = kwargs["subscription_id"]
trigger_name = kwargs["trigger_name"]
return f"trigger_debug_waiting_pool:{{{tenant_id}}}:{subscription_id}:{trigger_name}"
event_name = kwargs["event_name"]
return f"trigger_debug_waiting_pool:{{{tenant_id}}}:{str(provider_id)}:{subscription_id}:{event_name}"
class WebhookDebugEvent(BaseDebugEvent):
@ -132,14 +134,14 @@ class TriggerDebugService:
Returns:
Number of addresses the event was dispatched to
"""
event_json = event.model_dump_json()
event_data = event.model_dump_json()
try:
result = redis_client.eval(
cls.LUA_DISPATCH,
1,
pool_key,
tenant_id,
event_json,
event_data,
)
return int(result)
except RedisError:

View File

@ -8,8 +8,10 @@ from sqlalchemy import func, select
from sqlalchemy.orm import Session
from core.plugin.entities.plugin_daemon import CredentialType
from core.plugin.entities.request import TriggerDispatchResponse
from core.plugin.utils.http_parser import deserialize_request, serialize_request
from core.trigger.entities.entities import EventEntity
from core.trigger.provider import PluginTriggerProviderController
from core.trigger.trigger_manager import TriggerManager
from core.workflow.enums import NodeType
from core.workflow.nodes.trigger_schedule.exc import TenantOwnerNotFoundError
@ -70,13 +72,13 @@ class TriggerService:
@classmethod
def dispatch_triggered_workflows(
cls, subscription: TriggerSubscription, trigger: EventEntity, request_id: str
cls, subscription: TriggerSubscription, event: EventEntity, request_id: str
) -> int:
"""Process triggered workflows.
Args:
subscription: The trigger subscription
trigger: The trigger entity that was activated
event: The trigger entity that was activated
request_id: The ID of the stored request in storage system
"""
request = deserialize_request(storage.load_once(f"triggers/{request_id}"))
@ -85,12 +87,12 @@ class TriggerService:
return 0
subscribers: list[WorkflowPluginTrigger] = cls.get_subscriber_triggers(
tenant_id=subscription.tenant_id, subscription_id=subscription.id, trigger_name=trigger.identity.name
tenant_id=subscription.tenant_id, subscription_id=subscription.id, trigger_name=event.identity.name
)
if not subscribers:
logger.warning(
"No workflows found for trigger '%s' in subscription '%s'",
trigger.identity.name,
event.identity.name,
subscription.id,
)
return 0
@ -125,7 +127,7 @@ class TriggerService:
tenant_id=subscription.tenant_id,
user_id=subscription.user_id,
provider_id=TriggerProviderID(subscription.provider_id),
trigger_name=trigger.identity.name,
trigger_name=event.identity.name,
parameters=trigger_node.get("config", {}),
credentials=subscription.credentials,
credential_type=CredentialType.of(subscription.credential_type),
@ -135,7 +137,7 @@ class TriggerService:
logger.info(
"Trigger ignored for app %s with trigger %s",
plugin_trigger.app_id,
trigger.identity.name,
event.identity.name,
)
continue
@ -158,7 +160,7 @@ class TriggerService:
logger.info(
"Triggered workflow for app %s with trigger %s",
plugin_trigger.app_id,
trigger.identity.name,
event.identity.name,
)
except Exception:
logger.exception(
@ -178,16 +180,18 @@ class TriggerService:
request: Request
"""
timestamp = int(time.time())
subscription = TriggerProviderService.get_subscription_by_endpoint(endpoint_id)
subscription: TriggerSubscription | None = TriggerProviderService.get_subscription_by_endpoint(endpoint_id)
if not subscription:
return None
provider_id = TriggerProviderID(subscription.provider_id)
controller = TriggerManager.get_trigger_provider(subscription.tenant_id, provider_id)
controller: PluginTriggerProviderController = TriggerManager.get_trigger_provider(
tenant_id=subscription.tenant_id, provider_id=provider_id
)
if not controller:
return None
dispatch_response = controller.dispatch(
dispatch_response: TriggerDispatchResponse = controller.dispatch(
user_id=subscription.user_id, request=request, subscription=subscription.to_entity()
)

View File

@ -87,8 +87,8 @@ def dispatch_triggered_workflows_async(
dispatched_count = 0
for event_name in events:
try:
trigger = controller.get_event(event_name)
if trigger is None:
event = controller.get_event(event_name)
if event is None:
logger.error(
"Trigger '%s' not found in provider '%s'",
event_name,
@ -98,7 +98,7 @@ def dispatch_triggered_workflows_async(
dispatched_count += TriggerService.dispatch_triggered_workflows(
subscription=subscription,
trigger=trigger,
event=event,
request_id=request_id,
)
@ -118,7 +118,8 @@ def dispatch_triggered_workflows_async(
pool_key: str = PluginTriggerDebugEvent.build_pool_key(
tenant_id=subscription.tenant_id,
subscription_id=subscription_id,
trigger_name=event_name,
event_name=event_name,
provider_id=provider_id,
)
event = PluginTriggerDebugEvent(
subscription_id=subscription_id,
@ -141,11 +142,6 @@ def dispatch_triggered_workflows_async(
len(events),
)
# Note: Stored request is not deleted here. It should be handled by:
# 1. Storage system's lifecycle policy (e.g., S3 lifecycle rules for triggers/* prefix)
# 2. Or periodic cleanup job if using local/persistent storage
# This ensures request data is available for debugging/retry purposes
return {
"status": "completed",
"total_count": len(events),

View File

@ -102,7 +102,7 @@ export type TriggerParameter = {
}
// Action
export type Trigger = {
export type Event = {
name: string
author: string
label: TypeWithI18N

View File

@ -50,11 +50,11 @@ const getTriggerPluginNodeData = (
provider_id: triggerConfig.provider_id,
provider_type: triggerConfig.provider_type,
provider_name: triggerConfig.provider_name,
trigger_name: triggerConfig.trigger_name,
trigger_label: triggerConfig.trigger_label,
trigger_description: triggerConfig.trigger_description,
title: triggerConfig.trigger_label || triggerConfig.title || fallbackTitle,
desc: triggerConfig.trigger_description || fallbackDesc,
event_name: triggerConfig.event_name,
event_label: triggerConfig.event_label,
event_description: triggerConfig.event_description,
title: triggerConfig.event_label || triggerConfig.title || fallbackTitle,
desc: triggerConfig.event_description || fallbackDesc,
output_schema: { ...(triggerConfig.output_schema || {}) },
parameters_schema: triggerConfig.paramSchemas ? [...triggerConfig.paramSchemas] : [],
config: { ...(triggerConfig.params || {}) },

View File

@ -2,7 +2,7 @@
import type { FC } from 'react'
import React from 'react'
import type { TriggerWithProvider } from '../types'
import type { Trigger } from '@/app/components/tools/types'
import type { Event } from '@/app/components/tools/types'
import { BlockEnum } from '../../types'
import type { TriggerDefaultValue } from '../types'
import Tooltip from '@/app/components/base/tooltip'
@ -13,7 +13,7 @@ import { useTranslation } from 'react-i18next'
type Props = {
provider: TriggerWithProvider
payload: Trigger
payload: Event
disabled?: boolean
isAdded?: boolean
onSelect: (type: BlockEnum, trigger?: TriggerDefaultValue) => void
@ -63,9 +63,9 @@ const TriggerPluginActionItem: FC<Props> = ({
provider_id: provider.id,
provider_type: provider.type as string,
provider_name: provider.name,
trigger_name: payload.name,
trigger_label: payload.label[language],
trigger_description: payload.description[language],
event_name: payload.name,
event_label: payload.label[language],
event_description: payload.description[language],
plugin_unique_identifier: provider.plugin_unique_identifier,
title: payload.label[language],
is_team_authorization: provider.is_team_authorization,

View File

@ -27,7 +27,7 @@ const TriggerPluginItem: FC<Props> = ({
const { t } = useTranslation()
const language = useGetLanguage()
const notShowProvider = payload.type === CollectionType.workflow
const actions = payload.triggers
const actions = payload.events
const hasAction = !notShowProvider
const [isFold, setFold] = React.useState<boolean>(true)
const ref = useRef(null)
@ -71,10 +71,10 @@ const TriggerPluginItem: FC<Props> = ({
return
}
const trigger = actions[0]
const event = actions[0]
const params: Record<string, string> = {}
if (trigger.parameters) {
trigger.parameters.forEach((item) => {
if (event.parameters) {
event.parameters.forEach((item: any) => {
params[item.name] = ''
})
}
@ -82,14 +82,14 @@ const TriggerPluginItem: FC<Props> = ({
provider_id: payload.id,
provider_type: payload.type,
provider_name: payload.name,
trigger_name: trigger.name,
trigger_label: trigger.label[language],
trigger_description: trigger.description[language],
title: trigger.label[language],
event_name: event.name,
event_label: event.label[language],
event_description: event.description[language],
title: event.label[language],
plugin_unique_identifier: payload.plugin_unique_identifier,
is_team_authorization: payload.is_team_authorization,
output_schema: trigger.output_schema || {},
paramSchemas: trigger.parameters,
output_schema: event.output_schema || {},
paramSchemas: event.parameters,
params,
})
}}

View File

@ -1,6 +1,6 @@
import type { TypeWithI18N } from '@/app/components/header/account-setting/model-provider-page/declarations'
import type { PluginMeta, SupportedCreationMethods } from '../../plugins/types'
import type { Collection, Trigger } from '../../tools/types'
import type { Collection, Event } from '../../tools/types'
export enum TabsEnum {
Start = 'start',
@ -32,9 +32,9 @@ type PluginCommonDefaultValue = {
}
export type TriggerDefaultValue = PluginCommonDefaultValue & {
trigger_name: string
trigger_label: string
trigger_description: string
event_name: string
event_label: string
event_description: string
title: string
plugin_unique_identifier: string
is_team_authorization: boolean
@ -207,7 +207,7 @@ export type TriggerProviderApiEntity = {
// Frontend types - compatible with ToolWithProvider
export type TriggerWithProvider = Collection & {
triggers: Trigger[]
events: Event[]
meta: PluginMeta
plugin_unique_identifier: string
credentials_schema?: TriggerCredentialField[]

View File

@ -27,7 +27,7 @@ import cn from '@/utils/classnames'
import { Listbox, ListboxButton, ListboxOption, ListboxOptions } from '@headlessui/react'
import { ChevronDownIcon } from '@heroicons/react/20/solid'
import { RiCheckLine, RiLoader4Line } from '@remixicon/react'
import type { Trigger } from '@/app/components/tools/types'
import type { Event } from '@/app/components/tools/types'
type Props = {
readOnly: boolean
@ -36,7 +36,7 @@ type Props = {
value: ResourceVarInputs
onChange: (value: any) => void
inPanel?: boolean
currentTool?: Tool | Trigger
currentTool?: Tool | Event
currentProvider?: ToolWithProvider | TriggerWithProvider
showManageInputField?: boolean
onManageInputField?: () => void

View File

@ -3,7 +3,7 @@ import type { FC } from 'react'
import { useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import type { TriggerWithProvider } from '@/app/components/workflow/block-selector/types'
import type { Trigger } from '@/app/components/tools/types'
import type { Event } from '@/app/components/tools/types'
import { toolCredentialToFormSchemas, toolParametersToFormSchemas } from '@/app/components/tools/utils/to-form-schema'
import TriggerForm from './trigger-form'
import Button from '@/app/components/base/button'
@ -11,7 +11,7 @@ import Input from '@/app/components/base/input'
type ParametersFormProps = {
provider: TriggerWithProvider
trigger?: Trigger
trigger?: Event
builderId: string
parametersValue: Record<string, any>
propertiesValue: Record<string, any>

View File

@ -1,6 +1,6 @@
'use client'
import type { CredentialFormSchema } from '@/app/components/header/account-setting/model-provider-page/declarations'
import type { Trigger } from '@/app/components/tools/types'
import type { Event } from '@/app/components/tools/types'
import type { FC } from 'react'
import type { PluginTriggerVarInputs } from '@/app/components/workflow/nodes/trigger-plugin/types'
import TriggerFormItem from './item'
@ -14,7 +14,7 @@ type Props = {
onChange: (value: PluginTriggerVarInputs) => void
onOpen?: (index: number) => void
inPanel?: boolean
currentTrigger?: Trigger
currentTrigger?: Event
currentProvider?: TriggerWithProvider
extraParams?: Record<string, any>
}

View File

@ -12,7 +12,7 @@ import Tooltip from '@/app/components/base/tooltip'
import FormInputItem from '@/app/components/workflow/nodes/_base/components/form-input-item'
import { useBoolean } from 'ahooks'
import SchemaModal from '@/app/components/plugins/plugin-detail-panel/tool-selector/schema-modal'
import type { Trigger } from '@/app/components/tools/types'
import type { Event } from '@/app/components/tools/types'
import type { TriggerWithProvider } from '@/app/components/workflow/block-selector/types'
type Props = {
@ -22,7 +22,7 @@ type Props = {
value: PluginTriggerVarInputs
onChange: (value: PluginTriggerVarInputs) => void
inPanel?: boolean
currentTrigger?: Trigger
currentTrigger?: Event
currentProvider?: TriggerWithProvider
extraParams?: Record<string, any>
}

View File

@ -13,7 +13,7 @@ const nodeDefault: NodeDefault<PluginTriggerNodeType> = {
metaData,
defaultValue: {
plugin_id: '',
trigger_name: '',
event_name: '',
// event_type: '',
config: {},
},

View File

@ -6,14 +6,14 @@ export type PluginTriggerNodeType = CommonNodeType & {
provider_id: string
provider_type: CollectionType
provider_name: string
trigger_name: string
trigger_label: string
trigger_parameters: PluginTriggerVarInputs
trigger_configurations: Record<string, any>
event_name: string
event_label: string
event_parameters: PluginTriggerVarInputs
event_configurations: Record<string, any>
output_schema: Record<string, any>
parameters_schema?: Record<string, any>[]
version?: string
trigger_node_version?: string
event_node_version?: string
plugin_id?: string
config?: Record<string, any>
}

View File

@ -13,7 +13,7 @@ import {
} from '@/app/components/tools/utils/to-form-schema'
import type { InputVar } from '@/app/components/workflow/types'
import type { TriggerWithProvider } from '@/app/components/workflow/block-selector/types'
import type { Trigger } from '@/app/components/tools/types'
import type { Event } from '@/app/components/tools/types'
const useConfig = (id: string, payload: PluginTriggerNodeType) => {
const { nodesReadOnly: readOnly } = useNodesReadOnly()
@ -24,7 +24,7 @@ const useConfig = (id: string, payload: PluginTriggerNodeType) => {
payload,
)
const { provider_id, provider_name, trigger_name, config } = inputs
const { provider_id, provider_name, event_name: event_name, config } = inputs
// Construct provider for authentication check
const authProvider = useMemo(() => {
@ -45,11 +45,11 @@ const useConfig = (id: string, payload: PluginTriggerNodeType) => {
)
}, [triggerPlugins, provider_name, provider_id])
const currentTrigger = useMemo<Trigger | undefined>(() => {
return currentProvider?.triggers.find(
trigger => trigger.name === trigger_name,
const currentEvent = useMemo<Event | undefined>(() => {
return currentProvider?.events.find(
event => event.name === event_name,
)
}, [currentProvider, trigger_name])
}, [currentProvider, event_name])
// Dynamic subscription parameters (from subscription_schema.parameters_schema)
const subscriptionParameterSchema = useMemo(() => {
@ -61,9 +61,9 @@ const useConfig = (id: string, payload: PluginTriggerNodeType) => {
// Dynamic trigger parameters (from specific trigger.parameters)
const triggerSpecificParameterSchema = useMemo(() => {
if (!currentTrigger) return []
return toolParametersToFormSchemas(currentTrigger.parameters)
}, [currentTrigger])
if (!currentEvent) return []
return toolParametersToFormSchemas(currentEvent.parameters)
}, [currentEvent])
// Combined parameter schema (subscription + trigger specific)
const triggerParameterSchema = useMemo(() => {
@ -106,8 +106,8 @@ const useConfig = (id: string, payload: PluginTriggerNodeType) => {
// Get output schema
const outputSchema = useMemo(() => {
return currentTrigger?.output_schema || {}
}, [currentTrigger])
return currentEvent?.output_schema || {}
}, [currentEvent])
// Check if trigger has complex output structure
const hasObjectOutput = useMemo(() => {
@ -151,7 +151,7 @@ const useConfig = (id: string, payload: PluginTriggerNodeType) => {
readOnly,
inputs,
currentProvider,
currentTrigger,
currentTrigger: currentEvent,
triggerParameterSchema,
triggerParameterValue,
subscriptionParameterSchema,

View File

@ -33,12 +33,12 @@ const convertToTriggerWithProvider = (provider: TriggerProviderApiEntity): Trigg
labels: provider.tags || [],
plugin_id: provider.plugin_id,
plugin_unique_identifier: provider.plugin_unique_identifier || '',
triggers: provider.events.map(trigger => ({
name: trigger.name,
events: provider.events.map(event => ({
name: event.name,
author: provider.author,
label: trigger.identity.label,
description: trigger.description.llm,
parameters: trigger.parameters.map(param => ({
label: event.identity.label,
description: event.description.llm,
parameters: event.parameters.map(param => ({
name: param.name,
label: param.label,
human_description: param.description || param.label,
@ -54,7 +54,7 @@ const convertToTriggerWithProvider = (provider: TriggerProviderApiEntity): Trigg
multiple: param.multiple || false,
})),
labels: provider.tags || [],
output_schema: trigger.output_schema || {},
output_schema: event.output_schema || {},
})),
// Trigger-specific schema fields