mirror of
https://github.com/langgenius/dify.git
synced 2026-01-14 06:07:33 +08:00
361 lines
12 KiB
Python
361 lines
12 KiB
Python
"""
|
|
Trigger Manager for loading and managing trigger providers and triggers
|
|
"""
|
|
|
|
import logging
|
|
from typing import Optional
|
|
|
|
from core.trigger.entities import (
|
|
ProviderConfig,
|
|
TriggerEntity,
|
|
)
|
|
from core.trigger.plugin_trigger import PluginTriggerController
|
|
from core.trigger.provider import PluginTriggerProviderController
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class TriggerManager:
|
|
"""
|
|
Manager for trigger providers and triggers
|
|
"""
|
|
|
|
@classmethod
|
|
def list_plugin_trigger_providers(cls, tenant_id: str) -> list[PluginTriggerProviderController]:
|
|
"""
|
|
List all plugin trigger providers for a tenant
|
|
|
|
:param tenant_id: Tenant ID
|
|
:return: List of trigger provider controllers
|
|
"""
|
|
manager = PluginTriggerController()
|
|
provider_entities = manager.fetch_trigger_providers(tenant_id)
|
|
|
|
controllers = []
|
|
for provider in provider_entities:
|
|
try:
|
|
controller = PluginTriggerProviderController(
|
|
entity=provider.declaration,
|
|
plugin_id=provider.plugin_id,
|
|
plugin_unique_identifier=provider.plugin_unique_identifier,
|
|
tenant_id=tenant_id,
|
|
)
|
|
controllers.append(controller)
|
|
except Exception as e:
|
|
logger.exception("Failed to load trigger provider {provider.plugin_id}")
|
|
continue
|
|
|
|
return controllers
|
|
|
|
@classmethod
|
|
def get_plugin_trigger_provider(
|
|
cls, tenant_id: str, plugin_id: str, provider_name: str
|
|
) -> Optional[PluginTriggerProviderController]:
|
|
"""
|
|
Get a specific plugin trigger provider
|
|
|
|
:param tenant_id: Tenant ID
|
|
:param plugin_id: Plugin ID
|
|
:param provider_name: Provider name
|
|
:return: Trigger provider controller or None
|
|
"""
|
|
manager = PluginTriggerManager()
|
|
provider = manager.fetch_trigger_provider(tenant_id, plugin_id, provider_name)
|
|
|
|
if not provider:
|
|
return None
|
|
|
|
try:
|
|
return PluginTriggerProviderController(
|
|
entity=provider.declaration,
|
|
plugin_id=provider.plugin_id,
|
|
plugin_unique_identifier=provider.plugin_unique_identifier,
|
|
tenant_id=tenant_id,
|
|
)
|
|
except Exception as e:
|
|
logger.exception("Failed to load trigger provider")
|
|
return None
|
|
|
|
@classmethod
|
|
def list_all_trigger_providers(cls, tenant_id: str) -> list[PluginTriggerProviderController]:
|
|
"""
|
|
List all trigger providers (plugin and builtin)
|
|
|
|
:param tenant_id: Tenant ID
|
|
:return: List of all trigger provider controllers
|
|
"""
|
|
providers = []
|
|
|
|
# Get plugin providers
|
|
plugin_providers = cls.list_plugin_trigger_providers(tenant_id)
|
|
providers.extend(plugin_providers)
|
|
|
|
# TODO: Add builtin providers when implemented
|
|
# builtin_providers = cls.list_builtin_trigger_providers(tenant_id)
|
|
# providers.extend(builtin_providers)
|
|
|
|
return providers
|
|
|
|
@classmethod
|
|
def list_triggers_by_provider(cls, tenant_id: str, plugin_id: str, provider_name: str) -> list[TriggerEntity]:
|
|
"""
|
|
List all triggers for a specific provider
|
|
|
|
:param tenant_id: Tenant ID
|
|
:param plugin_id: Plugin ID
|
|
:param provider_name: Provider name
|
|
:return: List of trigger entities
|
|
"""
|
|
provider = cls.get_plugin_trigger_provider(tenant_id, plugin_id, provider_name)
|
|
|
|
if not provider:
|
|
return []
|
|
|
|
return provider.get_triggers()
|
|
|
|
@classmethod
|
|
def get_trigger(
|
|
cls, tenant_id: str, plugin_id: str, provider_name: str, trigger_name: str
|
|
) -> Optional[TriggerEntity]:
|
|
"""
|
|
Get a specific trigger
|
|
|
|
:param tenant_id: Tenant ID
|
|
:param plugin_id: Plugin ID
|
|
:param provider_name: Provider name
|
|
:param trigger_name: Trigger name
|
|
:return: Trigger entity or None
|
|
"""
|
|
provider = cls.get_plugin_trigger_provider(tenant_id, plugin_id, provider_name)
|
|
|
|
if not provider:
|
|
return None
|
|
|
|
return provider.get_trigger(trigger_name)
|
|
|
|
@classmethod
|
|
def validate_trigger_credentials(
|
|
cls, tenant_id: str, plugin_id: str, provider_name: str, credentials: dict
|
|
) -> tuple[bool, str]:
|
|
"""
|
|
Validate trigger provider credentials
|
|
|
|
:param tenant_id: Tenant ID
|
|
:param plugin_id: Plugin ID
|
|
:param provider_name: Provider name
|
|
:param credentials: Credentials to validate
|
|
:return: Tuple of (is_valid, error_message)
|
|
"""
|
|
provider = cls.get_plugin_trigger_provider(tenant_id, plugin_id, provider_name)
|
|
|
|
if not provider:
|
|
return False, "Provider not found"
|
|
|
|
try:
|
|
provider.validate_credentials(credentials)
|
|
return True, ""
|
|
except Exception as e:
|
|
return False, str(e)
|
|
|
|
@classmethod
|
|
def execute_trigger(
|
|
cls, tenant_id: str, plugin_id: str, provider_name: str, trigger_name: str, parameters: dict, credentials: dict
|
|
) -> dict:
|
|
"""
|
|
Execute a trigger
|
|
|
|
:param tenant_id: Tenant ID
|
|
:param plugin_id: Plugin ID
|
|
:param provider_name: Provider name
|
|
:param trigger_name: Trigger name
|
|
:param parameters: Trigger parameters
|
|
:param credentials: Provider credentials
|
|
:return: Trigger execution result
|
|
"""
|
|
provider = cls.get_plugin_trigger_provider(tenant_id, plugin_id, provider_name)
|
|
|
|
if not provider:
|
|
raise ValueError(f"Provider {plugin_id}/{provider_name} not found")
|
|
|
|
trigger = provider.get_trigger(trigger_name)
|
|
if not trigger:
|
|
raise ValueError(f"Trigger {trigger_name} not found in provider {provider_name}")
|
|
|
|
return provider.execute_trigger(trigger_name, parameters, credentials)
|
|
|
|
@classmethod
|
|
def subscribe_trigger(
|
|
cls,
|
|
tenant_id: str,
|
|
plugin_id: str,
|
|
provider_name: str,
|
|
trigger_name: str,
|
|
subscription_params: dict,
|
|
credentials: dict,
|
|
) -> dict:
|
|
"""
|
|
Subscribe to a trigger (e.g., register webhook)
|
|
|
|
:param tenant_id: Tenant ID
|
|
:param plugin_id: Plugin ID
|
|
:param provider_name: Provider name
|
|
:param trigger_name: Trigger name
|
|
:param subscription_params: Subscription parameters
|
|
:param credentials: Provider credentials
|
|
:return: Subscription result
|
|
"""
|
|
provider = cls.get_plugin_trigger_provider(tenant_id, plugin_id, provider_name)
|
|
|
|
if not provider:
|
|
raise ValueError(f"Provider {plugin_id}/{provider_name} not found")
|
|
|
|
return provider.subscribe_trigger(trigger_name, subscription_params, credentials)
|
|
|
|
@classmethod
|
|
def unsubscribe_trigger(
|
|
cls,
|
|
tenant_id: str,
|
|
plugin_id: str,
|
|
provider_name: str,
|
|
trigger_name: str,
|
|
subscription_metadata: dict,
|
|
credentials: dict,
|
|
) -> dict:
|
|
"""
|
|
Unsubscribe from a trigger
|
|
|
|
:param tenant_id: Tenant ID
|
|
:param plugin_id: Plugin ID
|
|
:param provider_name: Provider name
|
|
:param trigger_name: Trigger name
|
|
:param subscription_metadata: Subscription metadata from subscribe operation
|
|
:param credentials: Provider credentials
|
|
:return: Unsubscription result
|
|
"""
|
|
provider = cls.get_plugin_trigger_provider(tenant_id, plugin_id, provider_name)
|
|
|
|
if not provider:
|
|
raise ValueError(f"Provider {plugin_id}/{provider_name} not found")
|
|
|
|
return provider.unsubscribe_trigger(trigger_name, subscription_metadata, credentials)
|
|
|
|
@classmethod
|
|
def handle_webhook(
|
|
cls,
|
|
tenant_id: str,
|
|
plugin_id: str,
|
|
provider_name: str,
|
|
webhook_path: str,
|
|
request_data: dict,
|
|
credentials: dict,
|
|
) -> dict:
|
|
"""
|
|
Handle incoming webhook for a trigger
|
|
|
|
:param tenant_id: Tenant ID
|
|
:param plugin_id: Plugin ID
|
|
:param provider_name: Provider name
|
|
:param webhook_path: Webhook path
|
|
:param request_data: Webhook request data
|
|
:param credentials: Provider credentials
|
|
:return: Webhook handling result
|
|
"""
|
|
provider = cls.get_plugin_trigger_provider(tenant_id, plugin_id, provider_name)
|
|
|
|
if not provider:
|
|
raise ValueError(f"Provider {plugin_id}/{provider_name} not found")
|
|
|
|
return provider.handle_webhook(webhook_path, request_data, credentials)
|
|
|
|
@classmethod
|
|
def get_provider_credentials_schema(
|
|
cls, tenant_id: str, plugin_id: str, provider_name: str
|
|
) -> list[ProviderConfig]:
|
|
"""
|
|
Get provider credentials schema
|
|
|
|
:param tenant_id: Tenant ID
|
|
:param plugin_id: Plugin ID
|
|
:param provider_name: Provider name
|
|
:return: List of provider config schemas
|
|
"""
|
|
provider = cls.get_plugin_trigger_provider(tenant_id, plugin_id, provider_name)
|
|
|
|
if not provider:
|
|
return []
|
|
|
|
return provider.get_credentials_schema()
|
|
|
|
@classmethod
|
|
def get_provider_subscription_schema(
|
|
cls, tenant_id: str, plugin_id: str, provider_name: str
|
|
) -> list[ProviderConfig]:
|
|
"""
|
|
Get provider subscription schema
|
|
|
|
:param tenant_id: Tenant ID
|
|
:param plugin_id: Plugin ID
|
|
:param provider_name: Provider name
|
|
:return: List of subscription config schemas
|
|
"""
|
|
provider = cls.get_plugin_trigger_provider(tenant_id, plugin_id, provider_name)
|
|
|
|
if not provider:
|
|
return []
|
|
|
|
return provider.get_subscription_schema()
|
|
|
|
@classmethod
|
|
def get_provider_info(cls, tenant_id: str, plugin_id: str, provider_name: str) -> Optional[dict]:
|
|
"""
|
|
Get provider information
|
|
|
|
:param tenant_id: Tenant ID
|
|
:param plugin_id: Plugin ID
|
|
:param provider_name: Provider name
|
|
:return: Provider info dict or None
|
|
"""
|
|
provider = cls.get_plugin_trigger_provider(tenant_id, plugin_id, provider_name)
|
|
|
|
if not provider:
|
|
return None
|
|
|
|
return {
|
|
"plugin_id": plugin_id,
|
|
"provider_name": provider_name,
|
|
"identity": provider.entity.identity.model_dump() if provider.entity.identity else {},
|
|
"credentials_schema": [c.model_dump() for c in provider.entity.credentials_schema],
|
|
"subscription_schema": [s.model_dump() for s in provider.entity.subscription_schema],
|
|
"oauth_enabled": provider.entity.oauth_schema is not None,
|
|
"trigger_count": len(provider.entity.triggers),
|
|
"triggers": [t.identity.model_dump() for t in provider.entity.triggers],
|
|
}
|
|
|
|
@classmethod
|
|
def list_providers_for_workflow(cls, tenant_id: str) -> list[dict]:
|
|
"""
|
|
List trigger providers suitable for workflow usage
|
|
|
|
:param tenant_id: Tenant ID
|
|
:return: List of provider info dicts
|
|
"""
|
|
providers = cls.list_all_trigger_providers(tenant_id)
|
|
|
|
result = []
|
|
for provider in providers:
|
|
info = {
|
|
"plugin_id": provider.plugin_id,
|
|
"provider_name": provider.entity.identity.name,
|
|
"label": provider.entity.identity.label.model_dump(),
|
|
"description": provider.entity.identity.description.model_dump(),
|
|
"icon": provider.entity.identity.icon,
|
|
"trigger_count": len(provider.entity.triggers),
|
|
}
|
|
result.append(info)
|
|
|
|
return result
|
|
|
|
|
|
# Export
|
|
__all__ = ["TriggerManager"]
|