feat(trigger): introduce new error class and enhance event payload handling

- Added `TriggerIgnoreEventError` to handle cases where events should be ignored based on filter criteria.
- Updated various GitHub trigger files to return relevant payload fields directly, improving data accessibility for event handling.
- Enhanced the handling of event filtering in triggers to ensure only relevant events are processed.

These changes improve the robustness and clarity of the GitHub trigger integration, allowing for better error management and data handling.
This commit is contained in:
Harry
2025-09-19 13:17:59 +08:00
parent d6f3ee7fae
commit c67ef57f10
107 changed files with 1901 additions and 2414 deletions
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -18,70 +19,15 @@ class CommitCommentTrigger(TriggerEvent):
def _trigger(self, request: Request, parameters: Mapping[str, Any]) -> Event:
"""
Handle GitHub commit comment event trigger
Parameters:
- commit_filter: Filter by specific commit SHA (optional)
"""
# Get the event payload
payload = request.get_json()
if not payload:
raise ValueError("No payload received")
# This event only has 'created' action, but let's verify it's present
action = payload.get("action", "created")
if action != "created":
# This trigger only handles created events
return Event(variables={})
# Extract comment and repository information
comment = payload.get("comment", {})
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Apply commit filter if specified
commit_filter = parameters.get("commit_filter")
if commit_filter:
commit_id = comment.get("commit_id", "")
if not commit_id.startswith(commit_filter):
# Skip this event if it doesn't match the commit filter
return Event(variables={})
# Build variables for the workflow
variables = {
"comment": {
"id": comment.get("id"),
"body": comment.get("body", ""),
"html_url": comment.get("html_url", ""),
"created_at": comment.get("created_at", ""),
"updated_at": comment.get("updated_at", ""),
"line": comment.get("line"),
"path": comment.get("path", ""),
"position": comment.get("position"),
"commit_id": comment.get("commit_id", ""),
"author": {
"login": comment.get("user", {}).get("login", ""),
"avatar_url": comment.get("user", {}).get("avatar_url", ""),
"html_url": comment.get("user", {}).get("html_url", ""),
},
},
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"comment": payload.get("comment"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -18,64 +19,19 @@ class CreateTrigger(TriggerEvent):
def _trigger(self, request: Request, parameters: Mapping[str, Any]) -> Event:
"""
Handle GitHub create event trigger
Parameters:
- ref_type_filter: Filter by ref type (branch, tag) (optional)
- ref_filter: Filter by specific ref name (optional)
"""
# Get the event payload
payload = request.get_json()
if not payload:
raise ValueError("No payload received")
# Extract create information
ref = payload.get("ref", "")
ref_type = payload.get("ref_type", "")
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Apply ref type filter if specified
ref_type_filter = parameters.get("ref_type_filter")
if ref_type_filter is not None:
if ref_type != ref_type_filter:
# Skip this event if it doesn't match the ref type filter
return Event(variables={})
# Apply ref filter if specified
ref_filter = parameters.get("ref_filter")
if ref_filter is not None:
if ref != ref_filter:
# Skip this event if it doesn't match the ref filter
return Event(variables={})
# Build variables for the workflow
variables = {
"create": {
"ref": ref,
"ref_type": ref_type,
"master_branch": payload.get("master_branch", ""),
"description": payload.get("description", ""),
"pusher_type": payload.get("pusher_type", ""),
},
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"default_branch": repository.get("default_branch", ""),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"ref": payload.get("ref"),
"ref_type": payload.get("ref_type"),
"master_branch": payload.get("master_branch"),
"description": payload.get("description"),
"pusher_type": payload.get("pusher_type"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -18,52 +19,17 @@ class DeleteTrigger(TriggerEvent):
def _trigger(self, request: Request, parameters: Mapping[str, Any]) -> Event:
"""
Handle GitHub delete event trigger
Parameters:
- ref_type_filter: Filter by reference type (branch or tag) (optional)
"""
# Get the event payload
payload = request.get_json()
if not payload:
raise ValueError("No payload received")
# Extract delete information
ref = payload.get("ref", "")
ref_type = payload.get("ref_type", "")
pusher_type = payload.get("pusher_type", "")
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Apply reference type filter if specified
ref_type_filter = parameters.get("ref_type_filter")
if ref_type_filter and ref_type != ref_type_filter:
# Skip this event if it doesn't match the reference type filter
return Event(variables={})
# Build variables for the workflow
variables = {
"ref": ref,
"ref_type": ref_type,
"pusher_type": pusher_type,
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"default_branch": repository.get("default_branch", ""),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"ref": payload.get("ref"),
"ref_type": payload.get("ref_type"),
"pusher_type": payload.get("pusher_type"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,30 +25,9 @@ class DeploymentCreatedTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Extract basic information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Build basic variables for the workflow
variables = {
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"deployment": payload.get("deployment"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,30 +25,10 @@ class DeploymentStatusCreatedTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Extract basic information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Build basic variables for the workflow
variables = {
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"deployment_status": payload.get("deployment_status"),
"deployment": payload.get("deployment"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,30 +25,10 @@ class DiscussionAnsweredTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Extract basic information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Build basic variables for the workflow
variables = {
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"discussion": payload.get("discussion"),
"answer": payload.get("answer"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,30 +25,10 @@ class DiscussionCategoryChangedTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Extract basic information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Build basic variables for the workflow
variables = {
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"discussion": payload.get("discussion"),
"changes": payload.get("changes"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,30 +25,15 @@ class DiscussionCommentCreatedTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Extract basic information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Verify the action
action = payload.get("action", "")
if action != "created":
raise TriggerIgnoreEventError(f"Action '{action}' is not 'created'")
# Build basic variables for the workflow
variables = {
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"comment": payload.get("comment"),
"discussion": payload.get("discussion"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,30 +25,15 @@ class DiscussionCommentDeletedTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Extract basic information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Verify the action
action = payload.get("action", "")
if action != "deleted":
raise TriggerIgnoreEventError(f"Action '{action}' is not 'deleted'")
# Build basic variables for the workflow
variables = {
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"comment": payload.get("comment"),
"discussion": payload.get("discussion"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,30 +25,16 @@ class DiscussionCommentEditedTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Extract basic information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Verify the action
action = payload.get("action", "")
if action != "edited":
raise TriggerIgnoreEventError(f"Action '{action}' is not 'edited'")
# Build basic variables for the workflow
variables = {
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"comment": payload.get("comment"),
"discussion": payload.get("discussion"),
"changes": payload.get("changes"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,30 +25,14 @@ class DiscussionCreatedTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Extract basic information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Verify the action
action = payload.get("action", "")
if action != "created":
raise TriggerIgnoreEventError(f"Action '{action}' is not 'created'")
# Build basic variables for the workflow
variables = {
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"discussion": payload.get("discussion"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,30 +25,14 @@ class DiscussionDeletedTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Extract basic information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Verify the action
action = payload.get("action", "")
if action != "deleted":
raise TriggerIgnoreEventError(f"Action '{action}' is not 'deleted'")
# Build basic variables for the workflow
variables = {
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"discussion": payload.get("discussion"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,30 +25,15 @@ class DiscussionEditedTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Extract basic information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Verify the action
action = payload.get("action", "")
if action != "edited":
raise TriggerIgnoreEventError(f"Action '{action}' is not 'edited'")
# Build basic variables for the workflow
variables = {
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"discussion": payload.get("discussion"),
"changes": payload.get("changes"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,30 +25,10 @@ class DiscussionLabeledTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Extract basic information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Build basic variables for the workflow
variables = {
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"discussion": payload.get("discussion"),
"label": payload.get("label"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,30 +25,9 @@ class DiscussionLockedTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Extract basic information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Build basic variables for the workflow
variables = {
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"discussion": payload.get("discussion"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,30 +25,9 @@ class DiscussionPinnedTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Extract basic information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Build basic variables for the workflow
variables = {
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"discussion": payload.get("discussion"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,30 +25,10 @@ class DiscussionTransferredTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Extract basic information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Build basic variables for the workflow
variables = {
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"discussion": payload.get("discussion"),
"changes": payload.get("changes"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,30 +25,10 @@ class DiscussionUnansweredTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Extract basic information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Build basic variables for the workflow
variables = {
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"discussion": payload.get("discussion"),
"old_answer": payload.get("old_answer"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,30 +25,10 @@ class DiscussionUnlabeledTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Extract basic information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Build basic variables for the workflow
variables = {
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"discussion": payload.get("discussion"),
"label": payload.get("label"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,30 +25,9 @@ class DiscussionUnlockedTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Extract basic information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Build basic variables for the workflow
variables = {
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"discussion": payload.get("discussion"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,30 +25,9 @@ class DiscussionUnpinnedTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Extract basic information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Build basic variables for the workflow
variables = {
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"discussion": payload.get("discussion"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -0,0 +1,89 @@
"""
Common filtering utilities for GitHub triggers
"""
import fnmatch
from typing import List
def check_wildcard_match(value: str, patterns: List[str]) -> bool:
"""
Check if value matches any of the wildcard patterns
Args:
value: The value to check
patterns: List of patterns (supports wildcards)
Returns:
True if value matches any pattern
"""
for pattern in patterns:
if fnmatch.fnmatch(value, pattern):
return True
return False
def parse_comma_list(value: str) -> List[str]:
"""
Parse comma-separated string into list of trimmed values
Args:
value: Comma-separated string
Returns:
List of non-empty trimmed strings
"""
if not value:
return []
return [item.strip() for item in value.split(",") if item.strip()]
def check_label_match(labels: List[dict], required_labels: List[str]) -> bool:
"""
Check if any required label is present
Args:
labels: List of label dictionaries with 'name' field
required_labels: List of required label names
Returns:
True if any required label is present
"""
if not required_labels:
return True
label_names = [label.get("name", "") for label in labels]
return any(label in label_names for label in required_labels)
def is_bot_user(user: dict) -> bool:
"""
Check if a user is a bot
Args:
user: User dictionary with 'login' and 'type' fields
Returns:
True if user is a bot
"""
login = user.get("login", "")
user_type = user.get("type", "")
return "[bot]" in login or user_type == "Bot"
def check_keyword_match(text: str, keywords: List[str]) -> bool:
"""
Check if text contains any of the keywords (case-insensitive)
Args:
text: Text to search in
keywords: List of keywords to search for
Returns:
True if any keyword is found
"""
if not keywords:
return True
text_lower = text.lower()
return any(keyword.lower() in text_lower for keyword in keywords)
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,53 +25,9 @@ class ForkTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Extract fork information
forkee = payload.get("forkee", {})
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Build variables for the workflow
variables = {
"fork": {
"id": forkee.get("id"),
"name": forkee.get("name", ""),
"full_name": forkee.get("full_name", ""),
"html_url": forkee.get("html_url", ""),
"description": forkee.get("description", ""),
"private": forkee.get("private", False),
"created_at": forkee.get("created_at", ""),
"updated_at": forkee.get("updated_at", ""),
"clone_url": forkee.get("clone_url", ""),
"ssh_url": forkee.get("ssh_url", ""),
"default_branch": forkee.get("default_branch", ""),
"owner": {
"login": forkee.get("owner", {}).get("login", ""),
"avatar_url": forkee.get("owner", {}).get("avatar_url", ""),
"html_url": forkee.get("owner", {}).get("html_url", ""),
"type": forkee.get("owner", {}).get("type", ""),
},
},
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"forks_count": repository.get("forks_count", 0),
"stargazers_count": repository.get("stargazers_count", 0),
"watchers_count": repository.get("watchers_count", 0),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"forkee": payload.get("forkee"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -31,7 +32,7 @@ class IssueAssignedTrigger(TriggerEvent):
action = payload.get("action", "")
if action != "assigned":
# This trigger only handles assigned events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action \'{action}\' is not \'assigned\'")
# Extract issue information
issue = payload.get("issue", {})
@@ -45,7 +46,7 @@ class IssueAssignedTrigger(TriggerEvent):
issue_number = issue.get("number")
if issue_number != int(issue_filter):
# Skip this event if it doesn't match the issue filter
return Event(variables={})
raise TriggerIgnoreEventError("Event does not match filter criteria")
# Extract labels
labels = [
@@ -1,11 +1,15 @@
from collections.abc import Mapping
from datetime import datetime
from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
from .filters import check_label_match, parse_comma_list
class IssueClosedTrigger(TriggerEvent):
"""
@@ -17,10 +21,13 @@ class IssueClosedTrigger(TriggerEvent):
def _trigger(self, request: Request, parameters: Mapping[str, Any]) -> Event:
"""
Handle GitHub issue closed event trigger
Handle GitHub issue closed event trigger with practical filtering
Parameters:
- issue_filter: Filter by specific issue number (optional)
- labels: Filter by issue labels
- closed_by: Filter by who closed the issue
- resolution_time_max: Maximum resolution time in hours
- exclude_not_planned: Exclude issues closed as 'not planned'
"""
# Get the event payload
payload = request.get_json()
@@ -31,20 +38,63 @@ class IssueClosedTrigger(TriggerEvent):
action = payload.get("action", "")
if action != "closed":
# This trigger only handles closed events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action '{action}' is not 'closed'")
# Extract issue information
issue = payload.get("issue", {})
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Apply issue number filter if specified
issue_filter = parameters.get("issue_filter")
if issue_filter is not None:
issue_number = issue.get("number")
if issue_number != int(issue_filter):
# Skip this event if it doesn't match the issue filter
return Event(variables={})
# Check if issue was closed as 'not planned'
exclude_not_planned = parameters.get("exclude_not_planned", False)
if exclude_not_planned:
state_reason = issue.get("state_reason", "")
if state_reason == "not_planned":
raise TriggerIgnoreEventError("Issue closed as 'not planned'")
# Label filtering
labels_filter = parameters.get("labels", "")
if labels_filter:
required_labels = parse_comma_list(labels_filter)
if required_labels:
issue_labels = issue.get("labels", [])
if not check_label_match(issue_labels, required_labels):
raise TriggerIgnoreEventError(
f"Issue doesn't have any of the required labels: {', '.join(required_labels)}"
)
# Closed by filtering
closed_by_filter = parameters.get("closed_by", "")
if closed_by_filter:
allowed_users = parse_comma_list(closed_by_filter)
if allowed_users:
closer = sender.get("login", "") # The sender is who closed it
if closer not in allowed_users:
raise TriggerIgnoreEventError(
f"Issue closed by '{closer}' who is not in allowed list: {', '.join(allowed_users)}"
)
# Resolution time filtering
resolution_time_max = parameters.get("resolution_time_max")
if resolution_time_max is not None:
try:
max_hours = float(resolution_time_max)
created_at = issue.get("created_at", "")
closed_at = issue.get("closed_at", "")
if created_at and closed_at:
try:
created = datetime.fromisoformat(created_at.replace("Z", "+00:00"))
closed = datetime.fromisoformat(closed_at.replace("Z", "+00:00"))
resolution_hours = (closed - created).total_seconds() / 3600
if resolution_hours > max_hours:
raise TriggerIgnoreEventError(
f"Issue took {resolution_hours:.1f} hours to resolve, exceeds limit of {max_hours} hours"
)
except (ValueError, TypeError):
pass # Unable to parse dates, skip filtering
except ValueError:
pass # Invalid max_hours value, skip filtering
# Extract labels
labels = [
@@ -17,17 +17,66 @@ description:
pt_BR: Este gatilho é ativado quando uma issue é fechada em um repositório do GitHub, fornecendo informações sobre a issue, repositório e usuário que a fechou.
parameters:
- name: issue_filter
- name: labels
label:
en_US: Issue Number Filter
zh_Hans: Issue 编号过滤
pt_BR: Filtro de Número da Issue
en_US: Label Filter
zh_Hans: 标签过滤
pt_BR: Filtro de Etiquetas
type: string
required: false
placeholder:
en_US: "e.g., bug, fixed, wontfix (comma-separated)"
zh_Hans: "例如:bug, fixed, wontfix(逗号分隔)"
pt_BR: "ex: bug, fixed, wontfix (separados por vírgula)"
help:
en_US: "Only trigger for issues with these labels"
zh_Hans: "仅对带有这些标签的 Issue 触发"
pt_BR: "Disparar apenas para issues com estas etiquetas"
- name: closed_by
label:
en_US: Closed By Filter
zh_Hans: 关闭者过滤
pt_BR: Filtro de Quem Fechou
type: string
required: false
placeholder:
en_US: "e.g., john-doe, @team-leads (comma-separated)"
zh_Hans: "例如:john-doe, @team-leads(逗号分隔)"
pt_BR: "ex: john-doe, @team-leads (separados por vírgula)"
help:
en_US: "Only trigger if closed by specific users"
zh_Hans: "仅当由特定用户关闭时触发"
pt_BR: "Disparar apenas se fechado por usuários específicos"
- name: resolution_time_max
label:
en_US: Max Resolution Time (hours)
zh_Hans: 最大解决时间(小时)
pt_BR: Tempo Máximo de Resolução (horas)
type: number
required: false
description:
en_US: Filter by specific issue number (optional)
zh_Hans: 按特定 issue 编号过滤(可选)
pt_BR: Filtrar por número específico da issue (opcional)
placeholder:
en_US: "e.g., 24 (issues resolved within 24 hours)"
zh_Hans: "例如:2424小时内解决的问题)"
pt_BR: "ex: 24 (issues resolvidas em 24 horas)"
help:
en_US: "Only trigger for issues resolved within this time"
zh_Hans: "仅对在此时间内解决的问题触发"
pt_BR: "Disparar apenas para issues resolvidas dentro deste tempo"
- name: exclude_not_planned
label:
en_US: Exclude 'Not Planned'
zh_Hans: 排除'不计划修复'
pt_BR: Excluir 'Não Planejado'
type: boolean
required: false
default: false
help:
en_US: "Skip issues closed as 'not planned'"
zh_Hans: "跳过标记为'不计划修复'的问题"
pt_BR: "Pular issues fechadas como 'não planejado'"
output_schema:
type: object
@@ -4,8 +4,11 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
from .filters import is_bot_user, parse_comma_list
class IssueCommentCreatedTrigger(TriggerEvent):
"""
@@ -17,10 +20,13 @@ class IssueCommentCreatedTrigger(TriggerEvent):
def _trigger(self, request: Request, parameters: Mapping[str, Any]) -> Event:
"""
Handle GitHub issue comment created event trigger
Handle GitHub issue comment created event trigger with practical filtering
Parameters:
- issue_filter: Filter by specific issue number (optional)
- command_triggers: Only trigger for specific commands (e.g., /deploy)
- exclude_bots: Exclude comments from bot accounts
- issue_state: Filter by issue state (open/closed)
- author_association: Filter by author's association with the repo
"""
# Get the event payload
payload = request.get_json()
@@ -31,7 +37,7 @@ class IssueCommentCreatedTrigger(TriggerEvent):
action = payload.get("action", "")
if action != "created":
# This trigger only handles created events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action \'{action}\' is not \'created\'")
# Extract issue comment information
comment = payload.get("comment", {})
@@ -39,13 +45,45 @@ class IssueCommentCreatedTrigger(TriggerEvent):
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Apply issue number filter if specified
issue_filter = parameters.get("issue_filter")
if issue_filter is not None:
issue_number = issue.get("number")
if issue_number != int(issue_filter):
# Skip this event if it doesn't match the issue filter
return Event(variables={})
# Exclude bot comments if configured
exclude_bots = parameters.get("exclude_bots", True)
if exclude_bots and is_bot_user(sender):
raise TriggerIgnoreEventError(f"Ignoring comment from bot: {sender.get('login', '')}")
# Command trigger filtering
command_triggers = parameters.get("command_triggers", "")
if command_triggers:
commands = parse_comma_list(command_triggers)
if commands:
comment_body = comment.get("body", "").strip()
# Check if comment starts with any of the commands
command_found = False
for cmd in commands:
if comment_body.startswith(cmd):
command_found = True
break
if not command_found:
raise TriggerIgnoreEventError(
f"Comment doesn't start with any command: {', '.join(commands)}"
)
# Issue state filtering
issue_state_filter = parameters.get("issue_state")
if issue_state_filter:
issue_state = issue.get("state", "")
if issue_state != issue_state_filter:
raise TriggerIgnoreEventError(
f"Issue is {issue_state}, not {issue_state_filter}"
)
# Author association filtering
author_association_filter = parameters.get("author_association")
if author_association_filter:
author_association = comment.get("author_association", "")
if author_association != author_association_filter:
raise TriggerIgnoreEventError(
f"Comment author association is {author_association}, not {author_association_filter}"
)
# Check if this is a pull request
is_pull_request = "pull_request" in issue
@@ -17,17 +17,90 @@ description:
pt_BR: Este gatilho é ativado quando um novo comentário é criado em uma issue ou pull request do GitHub, fornecendo informações sobre o comentário, issue e usuário.
parameters:
- name: issue_filter
- name: command_triggers
label:
en_US: Issue Number Filter
zh_Hans: Issue 编号过滤
pt_BR: Filtro de Número da Issue
type: number
en_US: Command Triggers
zh_Hans: 命令触发
pt_BR: Gatilhos de Comando
type: string
required: false
description:
en_US: Filter by specific issue number (optional)
zh_Hans: 按特定 issue 编号过滤(可选)
pt_BR: Filtrar por número específico da issue (opcional)
placeholder:
en_US: "e.g., /deploy, /test, /help (comma-separated)"
zh_Hans: "例如:/deploy, /test, /help(逗号分隔)"
pt_BR: "ex: /deploy, /test, /help (separados por vírgula)"
help:
en_US: "Only trigger if comment starts with these commands"
zh_Hans: "仅当评论以这些命令开头时触发"
pt_BR: "Disparar apenas se o comentário começar com estes comandos"
- name: exclude_bots
label:
en_US: Exclude Bot Comments
zh_Hans: 排除机器人评论
pt_BR: Excluir Comentários de Bot
type: boolean
required: false
default: true
help:
en_US: "Ignore comments from bot accounts"
zh_Hans: "忽略来自机器人账户的评论"
pt_BR: "Ignorar comentários de contas bot"
- name: issue_state
label:
en_US: Issue State Filter
zh_Hans: Issue 状态过滤
pt_BR: Filtro de Estado da Issue
type: select
required: false
options:
- value: open
label:
en_US: Open Issues Only
zh_Hans: 仅开放的 Issue
pt_BR: Apenas Issues Abertas
- value: closed
label:
en_US: Closed Issues Only
zh_Hans: 仅关闭的 Issue
pt_BR: Apenas Issues Fechadas
help:
en_US: "Only trigger for issues in this state"
zh_Hans: "仅对此状态的 Issue 触发"
pt_BR: "Disparar apenas para issues neste estado"
- name: author_association
label:
en_US: Author Association
zh_Hans: 作者关联
pt_BR: Associação do Autor
type: select
required: false
options:
- value: OWNER
label:
en_US: Owner
zh_Hans: 所有者
pt_BR: Proprietário
- value: MEMBER
label:
en_US: Member
zh_Hans: 成员
pt_BR: Membro
- value: COLLABORATOR
label:
en_US: Collaborator
zh_Hans: 协作者
pt_BR: Colaborador
- value: CONTRIBUTOR
label:
en_US: Contributor
zh_Hans: 贡献者
pt_BR: Contribuidor
help:
en_US: "Only trigger for comments from users with this association"
zh_Hans: "仅对具有此关联的用户的评论触发"
pt_BR: "Disparar apenas para comentários de usuários com esta associação"
output_schema:
type: object
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -31,7 +32,7 @@ class IssueCommentDeletedTrigger(TriggerEvent):
action = payload.get("action", "")
if action != "deleted":
# This trigger only handles deleted events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action \'{action}\' is not \'deleted\'")
# Extract issue comment information
comment = payload.get("comment", {})
@@ -45,7 +46,7 @@ class IssueCommentDeletedTrigger(TriggerEvent):
issue_number = issue.get("number")
if issue_number != int(issue_filter):
# Skip this event if it doesn't match the issue filter
return Event(variables={})
raise TriggerIgnoreEventError("Event does not match filter criteria")
# Check if this is a pull request
is_pull_request = "pull_request" in issue
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -31,7 +32,7 @@ class IssueCommentEditedTrigger(TriggerEvent):
action = payload.get("action", "")
if action != "edited":
# This trigger only handles edited events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action \'{action}\' is not \'edited\'")
# Extract issue comment information
comment = payload.get("comment", {})
@@ -46,7 +47,7 @@ class IssueCommentEditedTrigger(TriggerEvent):
issue_number = issue.get("number")
if issue_number != int(issue_filter):
# Skip this event if it doesn't match the issue filter
return Event(variables={})
raise TriggerIgnoreEventError("Event does not match filter criteria")
# Check if this is a pull request
is_pull_request = "pull_request" in issue
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -31,7 +32,7 @@ class IssueEditedTrigger(TriggerEvent):
action = payload.get("action", "")
if action != "edited":
# This trigger only handles edited events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action \'{action}\' is not \'edited\'")
# Extract issue information
issue = payload.get("issue", {})
@@ -45,7 +46,7 @@ class IssueEditedTrigger(TriggerEvent):
issue_number = issue.get("number")
if issue_number != int(issue_filter):
# Skip this event if it doesn't match the issue filter
return Event(variables={})
raise TriggerIgnoreEventError("Event does not match filter criteria")
# Extract labels
labels = [
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -31,7 +32,7 @@ class IssueLabeledTrigger(TriggerEvent):
action = payload.get("action", "")
if action != "labeled":
# This trigger only handles labeled events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action \'{action}\' is not \'labeled\'")
# Extract issue information
issue = payload.get("issue", {})
@@ -45,7 +46,7 @@ class IssueLabeledTrigger(TriggerEvent):
issue_number = issue.get("number")
if issue_number != int(issue_filter):
# Skip this event if it doesn't match the issue filter
return Event(variables={})
raise TriggerIgnoreEventError("Event does not match filter criteria")
# Extract all labels
labels = [
@@ -4,48 +4,89 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
class IssueOpenedTrigger(TriggerEvent):
"""
GitHub Issue Opened Event Trigger
This trigger handles GitHub issue opened events and extracts relevant
information from the webhook payload to provide as variables to the workflow.
"""
def _trigger(self, request: Request, parameters: Mapping[str, Any]) -> Event:
"""
Handle GitHub issue opened event trigger
Handle GitHub issue opened event trigger with practical filtering
Parameters:
- issue_filter: Filter by specific issue number (optional)
- labels: Filter by issue labels (comma-separated)
- exclude_authors: Exclude issues from these authors
- title_keywords: Only trigger if title contains these keywords
- body_keywords: Only trigger if body contains these keywords
"""
# Get the event payload
payload = request.get_json()
if not payload:
raise ValueError("No payload received")
# Verify this is an opened action
action = payload.get("action", "")
if action != "opened":
# This trigger only handles opened events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action '{action}' is not 'opened'")
# Extract issue information
issue = payload.get("issue", {})
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Apply issue number filter if specified
issue_filter = parameters.get("issue_filter")
if issue_filter is not None:
issue_number = issue.get("number")
if issue_number != int(issue_filter):
# Skip this event if it doesn't match the issue filter
return Event(variables={})
# Author filtering
exclude_authors = parameters.get("exclude_authors", "")
if exclude_authors:
excluded = [a.strip() for a in exclude_authors.split(",") if a.strip()]
author = issue.get("user", {}).get("login", "")
if author in excluded:
raise TriggerIgnoreEventError(f"Issue created by excluded author: {author}")
# Label filtering
labels_filter = parameters.get("labels", "")
if labels_filter:
required_labels = [l.strip() for l in labels_filter.split(",") if l.strip()]
if required_labels:
issue_labels = [label.get("name", "") for label in issue.get("labels", [])]
# Check if issue has at least one of the required labels
has_required_label = any(label in issue_labels for label in required_labels)
if not has_required_label:
raise TriggerIgnoreEventError(
f"Issue doesn't have any of the required labels: {', '.join(required_labels)}"
)
# Title keyword filtering
title_keywords = parameters.get("title_keywords", "")
if title_keywords:
keywords = [k.strip().lower() for k in title_keywords.split(",") if k.strip()]
if keywords:
title = issue.get("title", "").lower()
has_keyword = any(keyword in title for keyword in keywords)
if not has_keyword:
raise TriggerIgnoreEventError(
f"Issue title doesn't contain any required keywords: {', '.join(keywords)}"
)
# Body keyword filtering
body_keywords = parameters.get("body_keywords", "")
if body_keywords:
keywords = [k.strip().lower() for k in body_keywords.split(",") if k.strip()]
if keywords:
body = (issue.get("body") or "").lower()
has_keyword = any(keyword in body for keyword in keywords)
if not has_keyword:
raise TriggerIgnoreEventError(
f"Issue body doesn't contain any required keywords: {', '.join(keywords)}"
)
# Extract labels
labels = [
{
@@ -55,7 +96,7 @@ class IssueOpenedTrigger(TriggerEvent):
}
for label in issue.get("labels", [])
]
# Build variables for the workflow
variables = {
"issue": {
@@ -79,6 +120,11 @@ class IssueOpenedTrigger(TriggerEvent):
"avatar_url": issue.get("user", {}).get("avatar_url", ""),
"html_url": issue.get("user", {}).get("html_url", ""),
},
"milestone": {
"title": issue.get("milestone", {}).get("title", "") if issue.get("milestone") else "",
"description": issue.get("milestone", {}).get("description", "") if issue.get("milestone") else "",
"due_on": issue.get("milestone", {}).get("due_on", "") if issue.get("milestone") else "",
} if issue.get("milestone") else None,
},
"repository": {
"name": repository.get("name", ""),
@@ -99,5 +145,5 @@ class IssueOpenedTrigger(TriggerEvent):
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
@@ -17,17 +17,69 @@ description:
pt_BR: Este gatilho é ativado quando uma nova issue é aberta em um repositório do GitHub, fornecendo informações sobre a issue, repositório e usuário que a abriu.
parameters:
- name: issue_filter
- name: labels
label:
en_US: Issue Number Filter
zh_Hans: Issue 编号过滤
pt_BR: Filtro de Número da Issue
type: number
en_US: Label Filter
zh_Hans: 标签过滤
pt_BR: Filtro de Etiquetas
type: string
required: false
description:
en_US: Filter by specific issue number (optional)
zh_Hans: 按特定 issue 编号过滤(可选)
pt_BR: Filtrar por número específico da issue (opcional)
placeholder:
en_US: "e.g., bug, urgent, customer-reported (comma-separated)"
zh_Hans: "例如:bug, urgent, 客户反馈(逗号分隔)"
pt_BR: "ex: bug, urgent, relatado-cliente (separados por vírgula)"
help:
en_US: "Only trigger for issues with these labels"
zh_Hans: "仅对带有这些标签的 Issue 触发"
pt_BR: "Disparar apenas para issues com estas etiquetas"
- name: exclude_authors
label:
en_US: Exclude Authors
zh_Hans: 排除作者
pt_BR: Excluir Autores
type: string
required: false
placeholder:
en_US: "e.g., bot-user, test-account (comma-separated)"
zh_Hans: "例如:bot-user, test-account(逗号分隔)"
pt_BR: "ex: bot-user, test-account (separados por vírgula)"
help:
en_US: "Ignore issues from these authors"
zh_Hans: "忽略这些作者创建的 Issue"
pt_BR: "Ignorar issues destes autores"
- name: title_keywords
label:
en_US: Title Keywords
zh_Hans: 标题关键词
pt_BR: Palavras-chave do Título
type: string
required: false
placeholder:
en_US: "e.g., production, critical, outage (comma-separated)"
zh_Hans: "例如:生产环境, 紧急, 故障(逗号分隔)"
pt_BR: "ex: produção, crítico, interrupção (separados por vírgula)"
help:
en_US: "Only trigger if title contains any of these keywords (case-insensitive)"
zh_Hans: "仅当标题包含这些关键词之一时触发(不区分大小写)"
pt_BR: "Disparar apenas se o título contiver alguma destas palavras-chave"
- name: body_keywords
label:
en_US: Body Keywords
zh_Hans: 内容关键词
pt_BR: Palavras-chave do Corpo
type: string
required: false
placeholder:
en_US: "e.g., error, exception, crash (comma-separated)"
zh_Hans: "例如:错误, 异常, 崩溃(逗号分隔)"
pt_BR: "ex: erro, exceção, crash (separados por vírgula)"
help:
en_US: "Only trigger if body contains any of these keywords (case-insensitive)"
zh_Hans: "仅当内容包含这些关键词之一时触发(不区分大小写)"
pt_BR: "Disparar apenas se o corpo contiver alguma destas palavras-chave"
output_schema:
type: object
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -31,7 +32,7 @@ class IssueReopenedTrigger(TriggerEvent):
action = payload.get("action", "")
if action != "reopened":
# This trigger only handles reopened events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action \'{action}\' is not \'reopened\'")
# Extract issue information
issue = payload.get("issue", {})
@@ -44,7 +45,7 @@ class IssueReopenedTrigger(TriggerEvent):
issue_number = issue.get("number")
if issue_number != int(issue_filter):
# Skip this event if it doesn't match the issue filter
return Event(variables={})
raise TriggerIgnoreEventError("Event does not match filter criteria")
# Extract labels
labels = [
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -31,7 +32,7 @@ class IssueUnassignedTrigger(TriggerEvent):
action = payload.get("action", "")
if action != "unassigned":
# This trigger only handles unassigned events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action \'{action}\' is not \'unassigned\'")
# Extract issue information
issue = payload.get("issue", {})
@@ -45,7 +46,7 @@ class IssueUnassignedTrigger(TriggerEvent):
issue_number = issue.get("number")
if issue_number != int(issue_filter):
# Skip this event if it doesn't match the issue filter
return Event(variables={})
raise TriggerIgnoreEventError("Event does not match filter criteria")
# Extract labels
labels = [
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -31,7 +32,7 @@ class IssueUnlabeledTrigger(TriggerEvent):
action = payload.get("action", "")
if action != "unlabeled":
# This trigger only handles unlabeled events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action \'{action}\' is not \'unlabeled\'")
# Extract issue information
issue = payload.get("issue", {})
@@ -45,7 +46,7 @@ class IssueUnlabeledTrigger(TriggerEvent):
issue_number = issue.get("number")
if issue_number != int(issue_filter):
# Skip this event if it doesn't match the issue filter
return Event(variables={})
raise TriggerIgnoreEventError("Event does not match filter criteria")
# Extract remaining labels
labels = [
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,30 +25,9 @@ class LabelCreatedTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Extract basic information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Build basic variables for the workflow
variables = {
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"label": payload.get("label"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,30 +25,9 @@ class LabelDeletedTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Extract basic information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Build basic variables for the workflow
variables = {
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"label": payload.get("label"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,30 +25,10 @@ class LabelEditedTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Extract basic information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Build basic variables for the workflow
variables = {
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"label": payload.get("label"),
"changes": payload.get("changes"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,30 +25,10 @@ class MemberAddedTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Extract basic information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Build basic variables for the workflow
variables = {
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"member": payload.get("member"),
"changes": payload.get("changes"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,30 +25,10 @@ class MemberEditedTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Extract basic information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Build basic variables for the workflow
variables = {
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"member": payload.get("member"),
"changes": payload.get("changes"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,30 +25,9 @@ class MemberRemovedTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Extract basic information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Build basic variables for the workflow
variables = {
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"member": payload.get("member"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,30 +25,9 @@ class MilestoneClosedTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Extract basic information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Build basic variables for the workflow
variables = {
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"milestone": payload.get("milestone"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,30 +25,9 @@ class MilestoneCreatedTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Extract basic information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Build basic variables for the workflow
variables = {
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"milestone": payload.get("milestone"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,30 +25,9 @@ class MilestoneDeletedTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Extract basic information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Build basic variables for the workflow
variables = {
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"milestone": payload.get("milestone"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,30 +25,10 @@ class MilestoneEditedTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Extract basic information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Build basic variables for the workflow
variables = {
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"milestone": payload.get("milestone"),
"changes": payload.get("changes"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,30 +25,9 @@ class MilestoneOpenedTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Extract basic information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Build basic variables for the workflow
variables = {
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"milestone": payload.get("milestone"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,30 +25,9 @@ class PackagePublishedTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Extract basic information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Build basic variables for the workflow
variables = {
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"package": payload.get("package"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,30 +25,9 @@ class PackageUpdatedTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Extract basic information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Build basic variables for the workflow
variables = {
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"package": payload.get("package"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,30 +25,11 @@ class PingTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Extract basic information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Build basic variables for the workflow
variables = {
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"zen": payload.get("zen"),
"hook_id": payload.get("hook_id"),
"hook": payload.get("hook"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -31,7 +32,7 @@ class PullRequestAssignedTrigger(TriggerEvent):
action = payload.get("action", "")
if action != "assigned":
# This trigger only handles assigned events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action \'{action}\' is not \'assigned\'")
# Extract pull request information
pull_request = payload.get("pull_request", {})
@@ -44,7 +45,7 @@ class PullRequestAssignedTrigger(TriggerEvent):
pr_number = pull_request.get("number")
if pr_number != int(pr_filter):
# Skip this event if it doesn't match the PR filter
return Event(variables={})
raise TriggerIgnoreEventError("Event does not match filter criteria")
# Build variables for the workflow
variables = {
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -31,7 +32,7 @@ class PullRequestAutoMergeDisabledTrigger(TriggerEvent):
action = payload.get("action", "")
if action != "auto_merge_disabled":
# This trigger only handles auto_merge_disabled events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action \'{action}\' is not \'auto_merge_disabled\'")
# Extract pull request information
pull_request = payload.get("pull_request", {})
@@ -44,7 +45,7 @@ class PullRequestAutoMergeDisabledTrigger(TriggerEvent):
pr_number = pull_request.get("number")
if pr_number != int(pr_filter):
# Skip this event if it doesn't match the PR filter
return Event(variables={})
raise TriggerIgnoreEventError("Event does not match filter criteria")
# Build variables for the workflow
variables = {
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -31,7 +32,7 @@ class PullRequestAutoMergeEnabledTrigger(TriggerEvent):
action = payload.get("action", "")
if action != "auto_merge_enabled":
# This trigger only handles auto_merge_enabled events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action \'{action}\' is not \'auto_merge_enabled\'")
# Extract pull request information
pull_request = payload.get("pull_request", {})
@@ -44,7 +45,7 @@ class PullRequestAutoMergeEnabledTrigger(TriggerEvent):
pr_number = pull_request.get("number")
if pr_number != int(pr_filter):
# Skip this event if it doesn't match the PR filter
return Event(variables={})
raise TriggerIgnoreEventError("Event does not match filter criteria")
# Build variables for the workflow
variables = {
@@ -1,9 +1,11 @@
import fnmatch
from collections.abc import Mapping
from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -17,10 +19,13 @@ class PullRequestClosedTrigger(TriggerEvent):
def _trigger(self, request: Request, parameters: Mapping[str, Any]) -> Event:
"""
Handle GitHub pull request closed event trigger
Handle GitHub pull request closed event trigger with practical filtering
Parameters:
- pr_filter: Filter by specific pull request number (optional)
- merged_only: Only trigger for merged PRs
- target_branches: Filter by target branch (comma-separated, supports wildcards)
- labels: Filter by PR labels (comma-separated)
- min_approvals: Minimum number of approvals required
"""
# Get the event payload
payload = request.get_json()
@@ -31,20 +36,62 @@ class PullRequestClosedTrigger(TriggerEvent):
action = payload.get("action", "")
if action != "closed":
# This trigger only handles closed events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action '{action}' is not 'closed'")
# Extract pull request information
pull_request = payload.get("pull_request", {})
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Apply PR number filter if specified
pr_filter = parameters.get("pr_filter")
if pr_filter is not None:
pr_number = pull_request.get("number")
if pr_number != int(pr_filter):
# Skip this event if it doesn't match the PR filter
return Event(variables={})
# Check if merged_only filter is enabled
merged_only = parameters.get("merged_only", False)
if merged_only and not pull_request.get("merged", False):
raise TriggerIgnoreEventError("PR was closed without merging")
# Target branch filtering
target_branches = parameters.get("target_branches", "")
if target_branches:
allowed_branches = [b.strip() for b in target_branches.split(",") if b.strip()]
if allowed_branches:
base_branch = pull_request.get("base", {}).get("ref", "")
# Check if target branch matches any of the patterns
branch_matched = False
for pattern in allowed_branches:
if fnmatch.fnmatch(base_branch, pattern):
branch_matched = True
break
if not branch_matched:
raise TriggerIgnoreEventError(
f"PR targets '{base_branch}' which doesn't match allowed patterns: {', '.join(allowed_branches)}"
)
# Label filtering
labels_filter = parameters.get("labels", "")
if labels_filter:
required_labels = [label.strip() for label in labels_filter.split(",") if label.strip()]
if required_labels:
pr_labels = [label.get("name", "") for label in pull_request.get("labels", [])]
# Check if PR has at least one of the required labels
has_required_label = any(label in pr_labels for label in required_labels)
if not has_required_label:
raise TriggerIgnoreEventError(
f"PR doesn't have any of the required labels: {', '.join(required_labels)}"
)
# Minimum approvals filtering
min_approvals = parameters.get("min_approvals")
if min_approvals is not None:
try:
min_count = int(min_approvals)
# Get the approval count from review_comments_url
# Note: In a real implementation, you'd need to fetch this data
# For now, we check if it was merged (which usually requires approvals)
if min_count > 0 and not pull_request.get("merged", False):
raise TriggerIgnoreEventError(
f"PR doesn't meet minimum approval requirement of {min_count}"
)
except ValueError:
pass # Invalid min_approvals value, skip filtering
# Extract labels
labels = [
@@ -17,17 +17,66 @@ description:
pt_BR: Este gatilho é ativado quando um pull request é fechado em um repositório do GitHub, seja mesclado ou fechado sem mesclar, fornecendo informações sobre o pull request, repositório e usuário que o fechou.
parameters:
- name: pr_filter
- name: merged_only
label:
en_US: Pull Request Number Filter
zh_Hans: Pull Request 编号过滤器
pt_BR: Filtro de Número do Pull Request
en_US: Merged Only
zh_Hans: 仅已合并
pt_BR: Apenas Mesclados
type: boolean
required: false
default: false
help:
en_US: "Only trigger for merged pull requests"
zh_Hans: "仅对已合并的 Pull Request 触发"
pt_BR: "Disparar apenas para pull requests mesclados"
- name: target_branches
label:
en_US: Target Branch Filter
zh_Hans: 目标分支过滤
pt_BR: Filtro de Branch de Destino
type: string
required: false
placeholder:
en_US: "e.g., main, release/*, production (comma-separated, supports wildcards)"
zh_Hans: "例如:main, release/*, production(逗号分隔,支持通配符)"
pt_BR: "ex: main, release/*, production (separados por vírgula, suporta wildcards)"
help:
en_US: "Only trigger for PRs closed into these branches"
zh_Hans: "仅对合并到这些分支的 PR 触发"
pt_BR: "Disparar apenas para PRs fechados nestas branches"
- name: labels
label:
en_US: Label Filter
zh_Hans: 标签过滤
pt_BR: Filtro de Etiquetas
type: string
required: false
placeholder:
en_US: "e.g., ready-to-deploy, hotfix, feature (comma-separated)"
zh_Hans: "例如:ready-to-deploy, hotfix, feature(逗号分隔)"
pt_BR: "ex: ready-to-deploy, hotfix, feature (separados por vírgula)"
help:
en_US: "Only trigger for PRs with these labels"
zh_Hans: "仅对带有这些标签的 PR 触发"
pt_BR: "Disparar apenas para PRs com estas etiquetas"
- name: min_approvals
label:
en_US: Minimum Approvals
zh_Hans: 最少批准数
pt_BR: Aprovações Mínimas
type: number
required: false
description:
en_US: Filter by specific pull request number (optional)
zh_Hans: 按特定 pull request 编号过滤(可选)
pt_BR: Filtrar por número específico do pull request (opcional)
placeholder:
en_US: "e.g., 2 (leave empty for no requirement)"
zh_Hans: "例如:2(留空表示不限制)"
pt_BR: "ex: 2 (deixe vazio para sem requisito)"
help:
en_US: "Only trigger if PR had at least this many approvals"
zh_Hans: "仅当 PR 有至少这么多批准时触发"
pt_BR: "Disparar apenas se o PR teve pelo menos este número de aprovações"
output_schema:
type: object
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -31,7 +32,7 @@ class PullRequestConvertedToDraftTrigger(TriggerEvent):
action = payload.get("action", "")
if action != "converted_to_draft":
# This trigger only handles converted_to_draft events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action \'{action}\' is not \'converted_to_draft\'")
# Extract pull request information
pull_request = payload.get("pull_request", {})
@@ -44,7 +45,7 @@ class PullRequestConvertedToDraftTrigger(TriggerEvent):
pr_number = pull_request.get("number")
if pr_number != int(pr_filter):
# Skip this event if it doesn't match the PR filter
return Event(variables={})
raise TriggerIgnoreEventError("Event does not match filter criteria")
# Build variables for the workflow
variables = {
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -31,7 +32,7 @@ class PullRequestEditedTrigger(TriggerEvent):
action = payload.get("action", "")
if action != "edited":
# This trigger only handles edited events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action \'{action}\' is not \'edited\'")
# Extract pull request information
pull_request = payload.get("pull_request", {})
@@ -45,7 +46,7 @@ class PullRequestEditedTrigger(TriggerEvent):
pr_number = pull_request.get("number")
if pr_number != int(pr_filter):
# Skip this event if it doesn't match the PR filter
return Event(variables={})
raise TriggerIgnoreEventError("Event does not match filter criteria")
# Build variables for the workflow
variables = {
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -31,7 +32,7 @@ class PullRequestLabeledTrigger(TriggerEvent):
action = payload.get("action", "")
if action != "labeled":
# This trigger only handles labeled events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action \'{action}\' is not \'labeled\'")
# Extract pull request information
pull_request = payload.get("pull_request", {})
@@ -44,7 +45,7 @@ class PullRequestLabeledTrigger(TriggerEvent):
pr_number = pull_request.get("number")
if pr_number != int(pr_filter):
# Skip this event if it doesn't match the PR filter
return Event(variables={})
raise TriggerIgnoreEventError("Event does not match filter criteria")
# Build variables for the workflow
variables = {
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -31,7 +32,7 @@ class PullRequestLockedTrigger(TriggerEvent):
action = payload.get("action", "")
if action != "locked":
# This trigger only handles locked events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action \'{action}\' is not \'locked\'")
# Extract pull request information
pull_request = payload.get("pull_request", {})
@@ -44,7 +45,7 @@ class PullRequestLockedTrigger(TriggerEvent):
pr_number = pull_request.get("number")
if pr_number != int(pr_filter):
# Skip this event if it doesn't match the PR filter
return Event(variables={})
raise TriggerIgnoreEventError("Event does not match filter criteria")
# Build variables for the workflow
variables = {
@@ -1,9 +1,11 @@
import fnmatch
from collections.abc import Mapping
from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -17,10 +19,14 @@ class PullRequestOpenedTrigger(TriggerEvent):
def _trigger(self, request: Request, parameters: Mapping[str, Any]) -> Event:
"""
Handle GitHub pull request opened event trigger
Handle GitHub pull request opened event trigger with practical filtering
Parameters:
- pr_filter: Filter by specific pull request number (optional)
- target_branches: Filter by target branch (comma-separated, supports wildcards)
- labels: Filter by PR labels (comma-separated)
- skip_draft: Skip draft PRs (default: true)
- exclude_authors: Exclude PRs from these authors
- file_count_limit: Ignore PRs with too many file changes
"""
# Get the event payload
payload = request.get_json()
@@ -31,20 +37,68 @@ class PullRequestOpenedTrigger(TriggerEvent):
action = payload.get("action", "")
if action != "opened":
# This trigger only handles opened events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action '{action}' is not 'opened'")
# Extract pull request information
pull_request = payload.get("pull_request", {})
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Apply PR number filter if specified
pr_filter = parameters.get("pr_filter")
if pr_filter is not None:
pr_number = pull_request.get("number")
if pr_number != int(pr_filter):
# Skip this event if it doesn't match the PR filter
return Event(variables={})
# Skip draft PRs if configured
skip_draft = parameters.get("skip_draft", True)
if skip_draft and pull_request.get("draft", False):
raise TriggerIgnoreEventError("Skipping draft pull request")
# Author filtering
exclude_authors = parameters.get("exclude_authors", "")
if exclude_authors:
excluded = [a.strip() for a in exclude_authors.split(",") if a.strip()]
author = pull_request.get("user", {}).get("login", "")
if author in excluded:
raise TriggerIgnoreEventError(f"PR created by excluded author: {author}")
# Target branch filtering
target_branches = parameters.get("target_branches", "")
if target_branches:
allowed_branches = [b.strip() for b in target_branches.split(",") if b.strip()]
if allowed_branches:
base_branch = pull_request.get("base", {}).get("ref", "")
# Check if target branch matches any of the patterns
branch_matched = False
for pattern in allowed_branches:
if fnmatch.fnmatch(base_branch, pattern):
branch_matched = True
break
if not branch_matched:
raise TriggerIgnoreEventError(
f"PR targets '{base_branch}' which doesn't match allowed patterns: {', '.join(allowed_branches)}"
)
# Label filtering
labels_filter = parameters.get("labels", "")
if labels_filter:
required_labels = [label.strip() for label in labels_filter.split(",") if label.strip()]
if required_labels:
pr_labels = [label.get("name", "") for label in pull_request.get("labels", [])]
# Check if PR has at least one of the required labels
has_required_label = any(label in pr_labels for label in required_labels)
if not has_required_label:
raise TriggerIgnoreEventError(
f"PR doesn't have any of the required labels: {', '.join(required_labels)}"
)
# File count filtering
file_count_limit = parameters.get("file_count_limit")
if file_count_limit is not None:
try:
limit = int(file_count_limit)
changed_files = pull_request.get("changed_files", 0)
if changed_files > limit:
raise TriggerIgnoreEventError(
f"PR changes {changed_files} files, exceeds limit of {limit}"
)
except ValueError:
pass # Invalid limit value, skip filtering
# Extract labels
labels = [
@@ -67,9 +121,33 @@ class PullRequestOpenedTrigger(TriggerEvent):
"created_at": pull_request.get("created_at", ""),
"updated_at": pull_request.get("updated_at", ""),
"draft": pull_request.get("draft", False),
"merged": pull_request.get("merged", False),
"mergeable": pull_request.get("mergeable"),
"mergeable_state": pull_request.get("mergeable_state", ""),
"changed_files": pull_request.get("changed_files", 0),
"additions": pull_request.get("additions", 0),
"deletions": pull_request.get("deletions", 0),
"labels": labels,
"head": {
"ref": pull_request.get("head", {}).get("ref", ""),
"sha": pull_request.get("head", {}).get("sha", ""),
"repo": {
"name": pull_request.get("head", {}).get("repo", {}).get("name", "") if pull_request.get("head", {}).get("repo") else "",
"full_name": pull_request.get("head", {}).get("repo", {}).get("full_name", "") if pull_request.get("head", {}).get("repo") else "",
} if pull_request.get("head", {}).get("repo") else None,
},
"base": {
"ref": pull_request.get("base", {}).get("ref", ""),
"sha": pull_request.get("base", {}).get("sha", ""),
"repo": {
"name": pull_request.get("base", {}).get("repo", {}).get("name", "") if pull_request.get("base", {}).get("repo") else "",
"full_name": pull_request.get("base", {}).get("repo", {}).get("full_name", "") if pull_request.get("base", {}).get("repo") else "",
} if pull_request.get("base", {}).get("repo") else None,
},
"author": {
"login": pull_request.get("user", {}).get("login", ""),
"avatar_url": pull_request.get("user", {}).get("avatar_url", ""),
"html_url": pull_request.get("user", {}).get("html_url", ""),
},
"assignees": [
{
"login": assignee.get("login", ""),
@@ -86,21 +164,11 @@ class PullRequestOpenedTrigger(TriggerEvent):
}
for reviewer in pull_request.get("requested_reviewers", [])
],
"author": {
"login": pull_request.get("user", {}).get("login", ""),
"avatar_url": pull_request.get("user", {}).get("avatar_url", ""),
"html_url": pull_request.get("user", {}).get("html_url", ""),
},
"head": {
"ref": pull_request.get("head", {}).get("ref", ""),
"sha": pull_request.get("head", {}).get("sha", ""),
"repo_name": pull_request.get("head", {}).get("repo", {}).get("full_name", ""),
},
"base": {
"ref": pull_request.get("base", {}).get("ref", ""),
"sha": pull_request.get("base", {}).get("sha", ""),
"repo_name": pull_request.get("base", {}).get("repo", {}).get("full_name", ""),
},
"milestone": {
"title": pull_request.get("milestone", {}).get("title", "") if pull_request.get("milestone") else "",
"description": pull_request.get("milestone", {}).get("description", "") if pull_request.get("milestone") else "",
"due_on": pull_request.get("milestone", {}).get("due_on", "") if pull_request.get("milestone") else "",
} if pull_request.get("milestone") else None,
},
"repository": {
"name": repository.get("name", ""),
@@ -17,17 +17,82 @@ description:
pt_BR: Este gatilho é ativado quando um novo pull request é aberto em um repositório do GitHub, fornecendo informações sobre o pull request, repositório e usuário que o abriu.
parameters:
- name: pr_filter
- name: target_branches
label:
en_US: Pull Request Number Filter
zh_Hans: Pull Request 编号过滤
pt_BR: Filtro de Número do Pull Request
en_US: Target Branch Filter
zh_Hans: 目标分支过滤
pt_BR: Filtro de Branch de Destino
type: string
required: false
placeholder:
en_US: "e.g., main, master, release/* (comma-separated, supports wildcards)"
zh_Hans: "例如:main, master, release/*(逗号分隔,支持通配符)"
pt_BR: "ex: main, master, release/* (separados por vírgula, suporta wildcards)"
help:
en_US: "Only trigger for PRs targeting these branches"
zh_Hans: "仅对合并到这些分支的 PR 触发"
pt_BR: "Disparar apenas para PRs direcionados a estes branches"
- name: labels
label:
en_US: Label Filter
zh_Hans: 标签过滤
pt_BR: Filtro de Etiquetas
type: string
required: false
placeholder:
en_US: "e.g., ready-for-review, needs-review (comma-separated)"
zh_Hans: "例如:ready-for-review, needs-review(逗号分隔)"
pt_BR: "ex: ready-for-review, needs-review (separados por vírgula)"
help:
en_US: "Only trigger for PRs with these labels"
zh_Hans: "仅对带有这些标签的 PR 触发"
pt_BR: "Disparar apenas para PRs com estas etiquetas"
- name: skip_draft
label:
en_US: Skip Draft PRs
zh_Hans: 跳过草稿 PR
pt_BR: Pular PRs de Rascunho
type: boolean
required: false
default: true
help:
en_US: "Ignore draft pull requests"
zh_Hans: "忽略草稿状态的 Pull Request"
pt_BR: "Ignorar pull requests em rascunho"
- name: exclude_authors
label:
en_US: Exclude Authors
zh_Hans: 排除作者
pt_BR: Excluir Autores
type: string
required: false
placeholder:
en_US: "e.g., dependabot[bot], renovate[bot] (comma-separated)"
zh_Hans: "例如:dependabot[bot], renovate[bot](逗号分隔)"
pt_BR: "ex: dependabot[bot], renovate[bot] (separados por vírgula)"
help:
en_US: "Ignore PRs from these authors"
zh_Hans: "忽略这些作者创建的 PR"
pt_BR: "Ignorar PRs destes autores"
- name: file_count_limit
label:
en_US: Max File Changes
zh_Hans: 最大文件变更数
pt_BR: Máximo de Arquivos Alterados
type: number
required: false
description:
en_US: Filter by specific pull request number (optional)
zh_Hans: 按特定 pull request 编号过滤(可选)
pt_BR: Filtrar por número específico do pull request (opcional)
placeholder:
en_US: "e.g., 50 (leave empty for no limit)"
zh_Hans: "例如:50(留空表示不限制)"
pt_BR: "ex: 50 (deixe vazio para sem limite)"
help:
en_US: "Ignore PRs with more than this many files changed"
zh_Hans: "忽略变更文件数超过此值的 PR"
pt_BR: "Ignorar PRs com mais arquivos alterados que este valor"
output_schema:
type: object
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -31,7 +32,7 @@ class PullRequestReadyForReviewTrigger(TriggerEvent):
action = payload.get("action", "")
if action != "ready_for_review":
# This trigger only handles ready_for_review events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action \'{action}\' is not \'ready_for_review\'")
# Extract pull request information
pull_request = payload.get("pull_request", {})
@@ -44,7 +45,7 @@ class PullRequestReadyForReviewTrigger(TriggerEvent):
pr_number = pull_request.get("number")
if pr_number != int(pr_filter):
# Skip this event if it doesn't match the PR filter
return Event(variables={})
raise TriggerIgnoreEventError("Event does not match filter criteria")
# Build variables for the workflow
variables = {
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -31,7 +32,7 @@ class PullRequestReopenedTrigger(TriggerEvent):
action = payload.get("action", "")
if action != "reopened":
# This trigger only handles reopened events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action \'{action}\' is not \'reopened\'")
# Extract pull request information
pull_request = payload.get("pull_request", {})
@@ -44,7 +45,7 @@ class PullRequestReopenedTrigger(TriggerEvent):
pr_number = pull_request.get("number")
if pr_number != int(pr_filter):
# Skip this event if it doesn't match the PR filter
return Event(variables={})
raise TriggerIgnoreEventError("Event does not match filter criteria")
# Extract labels
labels = [
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -31,7 +32,7 @@ class PullRequestReviewCommentCreatedTrigger(TriggerEvent):
action = payload.get("action", "")
if action != "created":
# This trigger only handles created events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action \'{action}\' is not \'created\'")
# Extract comment, pull request, and repository information
comment = payload.get("comment", {})
@@ -45,7 +46,7 @@ class PullRequestReviewCommentCreatedTrigger(TriggerEvent):
pr_number = pull_request.get("number")
if pr_number != int(pr_filter):
# Skip this event if it doesn't match the PR filter
return Event(variables={})
raise TriggerIgnoreEventError("Event does not match filter criteria")
# Build variables for the workflow
variables = {
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -31,7 +32,7 @@ class PullRequestReviewCommentDeletedTrigger(TriggerEvent):
action = payload.get("action", "")
if action != "deleted":
# This trigger only handles deleted events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action \'{action}\' is not \'deleted\'")
# Extract comment, pull request, and repository information
comment = payload.get("comment", {})
@@ -45,7 +46,7 @@ class PullRequestReviewCommentDeletedTrigger(TriggerEvent):
pr_number = pull_request.get("number")
if pr_number != int(pr_filter):
# Skip this event if it doesn't match the PR filter
return Event(variables={})
raise TriggerIgnoreEventError("Event does not match filter criteria")
# Build variables for the workflow
variables = {
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -31,7 +32,7 @@ class PullRequestReviewCommentEditedTrigger(TriggerEvent):
action = payload.get("action", "")
if action != "edited":
# This trigger only handles edited events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action \'{action}\' is not \'edited\'")
# Extract comment, pull request, and repository information
comment = payload.get("comment", {})
@@ -45,7 +46,7 @@ class PullRequestReviewCommentEditedTrigger(TriggerEvent):
pr_number = pull_request.get("number")
if pr_number != int(pr_filter):
# Skip this event if it doesn't match the PR filter
return Event(variables={})
raise TriggerIgnoreEventError("Event does not match filter criteria")
# Build variables for the workflow
variables = {
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -31,7 +32,7 @@ class PullRequestReviewDismissedTrigger(TriggerEvent):
action = payload.get("action", "")
if action != "dismissed":
# This trigger only handles dismissed events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action \'{action}\' is not \'dismissed\'")
# Extract review, pull request, and repository information
review = payload.get("review", {})
@@ -45,7 +46,7 @@ class PullRequestReviewDismissedTrigger(TriggerEvent):
pr_number = pull_request.get("number")
if pr_number != int(pr_filter):
# Skip this event if it doesn't match the PR filter
return Event(variables={})
raise TriggerIgnoreEventError("Event does not match filter criteria")
# Build variables for the workflow
variables = {
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -31,7 +32,7 @@ class PullRequestReviewEditedTrigger(TriggerEvent):
action = payload.get("action", "")
if action != "edited":
# This trigger only handles edited events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action \'{action}\' is not \'edited\'")
# Extract review, pull request, and repository information
review = payload.get("review", {})
@@ -45,7 +46,7 @@ class PullRequestReviewEditedTrigger(TriggerEvent):
pr_number = pull_request.get("number")
if pr_number != int(pr_filter):
# Skip this event if it doesn't match the PR filter
return Event(variables={})
raise TriggerIgnoreEventError("Event does not match filter criteria")
# Build variables for the workflow
variables = {
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -31,7 +32,7 @@ class PullRequestReviewRequestRemovedTrigger(TriggerEvent):
action = payload.get("action", "")
if action != "review_request_removed":
# This trigger only handles review_request_removed events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action \'{action}\' is not \'review_request_removed\'")
# Extract pull request information
pull_request = payload.get("pull_request", {})
@@ -44,7 +45,7 @@ class PullRequestReviewRequestRemovedTrigger(TriggerEvent):
pr_number = pull_request.get("number")
if pr_number != int(pr_filter):
# Skip this event if it doesn't match the PR filter
return Event(variables={})
raise TriggerIgnoreEventError("Event does not match filter criteria")
# Build variables for the workflow
variables = {
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -31,7 +32,7 @@ class PullRequestReviewRequestedTrigger(TriggerEvent):
action = payload.get("action", "")
if action != "review_requested":
# This trigger only handles review_requested events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action \'{action}\' is not \'review_requested\'")
# Extract pull request information
pull_request = payload.get("pull_request", {})
@@ -44,7 +45,7 @@ class PullRequestReviewRequestedTrigger(TriggerEvent):
pr_number = pull_request.get("number")
if pr_number != int(pr_filter):
# Skip this event if it doesn't match the PR filter
return Event(variables={})
raise TriggerIgnoreEventError("Event does not match filter criteria")
# Build variables for the workflow
variables = {
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -17,10 +18,12 @@ class PullRequestReviewSubmittedTrigger(TriggerEvent):
def _trigger(self, request: Request, parameters: Mapping[str, Any]) -> Event:
"""
Handle GitHub pull request review submitted event trigger
Handle GitHub pull request review submitted event trigger with practical filtering
Parameters:
- pr_filter: Filter by specific PR number (optional)
- review_state: Filter by review state (approved, changes_requested, commented)
- author_type: Filter by author type (human_only, bot_only)
- required_reviewers: Only from specific reviewers (comma-separated)
"""
# Get the event payload
payload = request.get_json()
@@ -31,7 +34,7 @@ class PullRequestReviewSubmittedTrigger(TriggerEvent):
action = payload.get("action", "")
if action != "submitted":
# This trigger only handles submitted events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action '{action}' is not 'submitted'")
# Extract review, pull request, and repository information
review = payload.get("review", {})
@@ -39,13 +42,50 @@ class PullRequestReviewSubmittedTrigger(TriggerEvent):
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Apply PR number filter if specified
pr_filter = parameters.get("pr_filter")
if pr_filter is not None:
pr_number = pull_request.get("number")
if pr_number != int(pr_filter):
# Skip this event if it doesn't match the PR filter
return Event(variables={})
# Review state filtering
review_state_filter = parameters.get("review_state")
if review_state_filter:
review_state = review.get("state", "").lower()
if review_state != review_state_filter.lower():
raise TriggerIgnoreEventError(
f"Review state '{review_state}' doesn't match required state '{review_state_filter}'"
)
# Author type filtering
author_type_filter = parameters.get("author_type")
if author_type_filter:
reviewer_login = review.get("user", {}).get("login", "")
reviewer_type = review.get("user", {}).get("type", "")
is_bot = "[bot]" in reviewer_login or reviewer_type == "Bot"
if author_type_filter == "human_only" and is_bot:
raise TriggerIgnoreEventError(f"Ignoring review from bot: {reviewer_login}")
elif author_type_filter == "bot_only" and not is_bot:
raise TriggerIgnoreEventError(f"Ignoring review from human user: {reviewer_login}")
# Required reviewers filtering
required_reviewers = parameters.get("required_reviewers", "")
if required_reviewers:
allowed_reviewers = [r.strip() for r in required_reviewers.split(",") if r.strip()]
if allowed_reviewers:
reviewer_login = review.get("user", {}).get("login", "")
# Check if reviewer is in the allowed list (support @team mentions)
reviewer_matched = False
for allowed in allowed_reviewers:
if allowed.startswith("@"):
# Team mention - would need additional API call to verify team membership
# For now, just check if the reviewer is mentioned
if reviewer_login == allowed[1:]:
reviewer_matched = True
break
elif reviewer_login == allowed:
reviewer_matched = True
break
if not reviewer_matched:
raise TriggerIgnoreEventError(
f"Review from '{reviewer_login}' is not from required reviewers: {', '.join(allowed_reviewers)}"
)
# Build variables for the workflow
variables = {
@@ -17,17 +17,72 @@ description:
pt_BR: Este gatilho é ativado quando uma revisão de pull request é submitted em um repositório do GitHub, fornecendo informações sobre a revisão, pull request, repositório e usuário que a submitted.
parameters:
- name: pr_filter
- name: review_state
label:
en_US: PR Number Filter
zh_Hans: PR 编号过滤
pt_BR: Filtro de Número do PR
type: number
en_US: Review State Filter
zh_Hans: 审查状态过滤
pt_BR: Filtro de Estado de Revisão
type: select
required: false
description:
en_US: Filter by specific PR number (optional)
zh_Hans: 按特定 PR 编号过滤(可选)
pt_BR: Filtrar por número específico do PR (opcional)
options:
- value: approved
label:
en_US: Approved
zh_Hans: 已批准
pt_BR: Aprovado
- value: changes_requested
label:
en_US: Changes Requested
zh_Hans: 请求更改
pt_BR: Alterações Solicitadas
- value: commented
label:
en_US: Commented
zh_Hans: 已评论
pt_BR: Comentado
help:
en_US: "Only trigger for specific review states"
zh_Hans: "仅对特定审查状态触发"
pt_BR: "Disparar apenas para estados de revisão específicos"
- name: author_type
label:
en_US: Author Type Filter
zh_Hans: 作者类型过滤
pt_BR: Filtro de Tipo de Autor
type: select
required: false
options:
- value: human_only
label:
en_US: Human Only (exclude bots)
zh_Hans: 仅人类(排除机器人)
pt_BR: Apenas Humanos (excluir bots)
- value: bot_only
label:
en_US: Bot Only
zh_Hans: 仅机器人
pt_BR: Apenas Bots
help:
en_US: "Filter reviews by author type"
zh_Hans: "按作者类型过滤审查"
pt_BR: "Filtrar revisões por tipo de autor"
- name: required_reviewers
label:
en_US: Required Reviewers
zh_Hans: 必需审查者
pt_BR: Revisores Obrigatórios
type: string
required: false
placeholder:
en_US: "e.g., john-doe, jane-smith, @team-leads (comma-separated)"
zh_Hans: "例如:john-doe, jane-smith, @team-leads(逗号分隔)"
pt_BR: "ex: john-doe, jane-smith, @team-leads (separados por vírgula)"
help:
en_US: "Only trigger if review is from one of these users/teams"
zh_Hans: "仅当审查来自这些用户/团队之一时触发"
pt_BR: "Disparar apenas se a revisão for de um destes usuários/equipes"
output_schema:
type: object
@@ -4,8 +4,11 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
from .filters import check_wildcard_match, parse_comma_list
class PullRequestSynchronizeTrigger(TriggerEvent):
"""
@@ -17,10 +20,13 @@ class PullRequestSynchronizeTrigger(TriggerEvent):
def _trigger(self, request: Request, parameters: Mapping[str, Any]) -> Event:
"""
Handle GitHub pull request synchronize event trigger
Handle GitHub pull request synchronize event trigger with practical filtering
Parameters:
- pr_filter: Filter by specific pull request number (optional)
- file_patterns: Filter by modified file patterns
- max_commits: Maximum number of commits allowed
- skip_draft: Skip draft PRs
- force_push_only: Only trigger for force pushes
"""
# Get the event payload
payload = request.get_json()
@@ -31,20 +37,54 @@ class PullRequestSynchronizeTrigger(TriggerEvent):
action = payload.get("action", "")
if action != "synchronize":
# This trigger only handles synchronize events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action \'{action}\' is not \'synchronize\'")
# Extract pull request information
pull_request = payload.get("pull_request", {})
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Apply PR number filter if specified
pr_filter = parameters.get("pr_filter")
if pr_filter is not None:
pr_number = pull_request.get("number")
if pr_number != int(pr_filter):
# Skip this event if it doesn't match the PR filter
return Event(variables={})
# Skip draft PRs if configured
skip_draft = parameters.get("skip_draft", False)
if skip_draft and pull_request.get("draft", False):
raise TriggerIgnoreEventError("Skipping draft pull request synchronization")
# Force push only filter
force_push_only = parameters.get("force_push_only", False)
if force_push_only:
# Check if this was a force push by comparing before/after
before = payload.get("before", "")
# In a force push, the before commit might not be an ancestor
# This is a simplified check - a proper check would need git history
if not before or before == "0000000000000000000000000000000000000000":
# Not a force push (new branch)
raise TriggerIgnoreEventError("Not a force push")
# Maximum commits filter
max_commits = parameters.get("max_commits")
if max_commits is not None:
try:
max_count = int(max_commits)
# Count commits in this push
# Note: GitHub doesn't always provide full commit list in sync events
# This is a best-effort check
commits_count = pull_request.get("commits", 0)
if commits_count > max_count:
raise TriggerIgnoreEventError(
f"PR has {commits_count} commits, exceeds limit of {max_count}"
)
except ValueError:
pass # Invalid max_commits value, skip filtering
# File pattern filtering
file_patterns_filter = parameters.get("file_patterns", "")
if file_patterns_filter:
patterns = parse_comma_list(file_patterns_filter)
if patterns:
# Note: GitHub sync events don't always include file changes
# This would need an API call to get changed files
# For now, we'll document this limitation
pass # File filtering would require additional API calls
# Build variables for the workflow
variables = {
@@ -17,17 +17,63 @@ description:
pt_BR: Este gatilho é ativado quando um pull request é sincronizado em um repositório do GitHub, tipicamente quando novos commits são enviados para o branch head, fornecendo informações sobre o pull request atualizado e as mudanças de commit.
parameters:
- name: pr_filter
- name: file_patterns
label:
en_US: Pull Request Number Filter
zh_Hans: Pull Request 编号过滤
pt_BR: Filtro de Número do Pull Request
en_US: File Pattern Filter
zh_Hans: 文件模式过滤
pt_BR: Filtro de Padrão de Arquivo
type: string
required: false
placeholder:
en_US: "e.g., *.js, src/**/*.ts, !*.test.* (comma-separated, supports wildcards)"
zh_Hans: "例如:*.js, src/**/*.ts, !*.test.*(逗号分隔,支持通配符)"
pt_BR: "ex: *.js, src/**/*.ts, !*.test.* (separados por vírgula, suporta wildcards)"
help:
en_US: "Only trigger if modified files match these patterns (! prefix to exclude)"
zh_Hans: "仅当修改的文件匹配这些模式时触发(!前缀表示排除)"
pt_BR: "Disparar apenas se arquivos modificados corresponderem a estes padrões (! para excluir)"
- name: max_commits
label:
en_US: Maximum Commits
zh_Hans: 最大提交数
pt_BR: Máximo de Commits
type: number
required: false
description:
en_US: Filter by specific pull request number (optional)
zh_Hans: 按特定 pull request 编号过滤(可选)
pt_BR: Filtrar por número específico do pull request (opcional)
placeholder:
en_US: "e.g., 10 (ignore large updates)"
zh_Hans: "例如:10(忽略大型更新)"
pt_BR: "ex: 10 (ignorar grandes atualizações)"
help:
en_US: "Skip if PR sync includes more than this many commits"
zh_Hans: "如果 PR 同步包含超过此数量的提交则跳过"
pt_BR: "Pular se a sincronização do PR incluir mais commits que este número"
- name: skip_draft
label:
en_US: Skip Draft PRs
zh_Hans: 跳过草稿 PR
pt_BR: Pular PRs de Rascunho
type: boolean
required: false
default: false
help:
en_US: "Don't trigger for draft pull requests"
zh_Hans: "不对草稿 Pull Request 触发"
pt_BR: "Não disparar para pull requests em rascunho"
- name: force_push_only
label:
en_US: Force Push Only
zh_Hans: 仅强制推送
pt_BR: Apenas Force Push
type: boolean
required: false
default: false
help:
en_US: "Only trigger for force pushes (rebases, amends)"
zh_Hans: "仅对强制推送触发(rebase、amend"
pt_BR: "Disparar apenas para force pushes (rebases, amends)"
output_schema:
type: object
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -31,7 +32,7 @@ class PullRequestUnassignedTrigger(TriggerEvent):
action = payload.get("action", "")
if action != "unassigned":
# This trigger only handles unassigned events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action \'{action}\' is not \'unassigned\'")
# Extract pull request information
pull_request = payload.get("pull_request", {})
@@ -44,7 +45,7 @@ class PullRequestUnassignedTrigger(TriggerEvent):
pr_number = pull_request.get("number")
if pr_number != int(pr_filter):
# Skip this event if it doesn't match the PR filter
return Event(variables={})
raise TriggerIgnoreEventError("Event does not match filter criteria")
# Build variables for the workflow
variables = {
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -31,7 +32,7 @@ class PullRequestUnlabeledTrigger(TriggerEvent):
action = payload.get("action", "")
if action != "unlabeled":
# This trigger only handles unlabeled events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action \'{action}\' is not \'unlabeled\'")
# Extract pull request information
pull_request = payload.get("pull_request", {})
@@ -44,7 +45,7 @@ class PullRequestUnlabeledTrigger(TriggerEvent):
pr_number = pull_request.get("number")
if pr_number != int(pr_filter):
# Skip this event if it doesn't match the PR filter
return Event(variables={})
raise TriggerIgnoreEventError("Event does not match filter criteria")
# Build variables for the workflow
variables = {
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -31,7 +32,7 @@ class PullRequestUnlockedTrigger(TriggerEvent):
action = payload.get("action", "")
if action != "unlocked":
# This trigger only handles unlocked events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action \'{action}\' is not \'unlocked\'")
# Extract pull request information
pull_request = payload.get("pull_request", {})
@@ -44,7 +45,7 @@ class PullRequestUnlockedTrigger(TriggerEvent):
pr_number = pull_request.get("number")
if pr_number != int(pr_filter):
# Skip this event if it doesn't match the PR filter
return Event(variables={})
raise TriggerIgnoreEventError("Event does not match filter criteria")
# Build variables for the workflow
variables = {
+74 -11
View File
@@ -1,9 +1,11 @@
import fnmatch
from collections.abc import Mapping
from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -17,28 +19,89 @@ class PushTrigger(TriggerEvent):
def _trigger(self, request: Request, parameters: Mapping[str, Any]) -> Event:
"""
Handle GitHub push event trigger
Handle GitHub push event trigger with advanced filtering
Parameters:
- branch_filter: Filter by specific branch name (optional)
- branches: Filter by branch names (comma-separated, supports wildcards)
- paths: Filter by file paths (comma-separated glob patterns)
- ignore_patterns: Ignore commits with these patterns in messages
- exclude_authors: Exclude commits from these authors
"""
# Get the event payload
payload = request.get_json()
if not payload:
raise ValueError("No payload received")
# Extract push information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Extract basic information
ref = payload.get("ref", "")
branch_name = ref.replace("refs/heads/", "") if ref.startswith("refs/heads/") else ref
# Apply branch filter if specified
branch_filter = parameters.get("branch_filter")
if branch_filter is not None:
if branch_name != branch_filter:
# Skip this event if it doesn't match the branch filter
return Event(variables={})
# Branch filtering
branches_filter = parameters.get("branches", "")
if branches_filter:
allowed_branches = [b.strip() for b in branches_filter.split(",") if b.strip()]
if allowed_branches:
# Check if current branch matches any of the patterns
branch_matched = False
for pattern in allowed_branches:
if fnmatch.fnmatch(branch_name, pattern):
branch_matched = True
break
if not branch_matched:
raise TriggerIgnoreEventError(
f"Branch '{branch_name}' doesn't match any allowed patterns: {', '.join(allowed_branches)}"
)
# Author filtering
exclude_authors = parameters.get("exclude_authors", "")
if exclude_authors:
excluded = [a.strip() for a in exclude_authors.split(",") if a.strip()]
pusher = payload.get("pusher", {}).get("name", "")
if pusher in excluded:
raise TriggerIgnoreEventError(f"Push from excluded author: {pusher}")
# Commit message filtering
ignore_patterns = parameters.get("ignore_patterns", "")
if ignore_patterns:
patterns = [p.strip() for p in ignore_patterns.split(",") if p.strip()]
head_commit = payload.get("head_commit", {})
commit_message = head_commit.get("message", "")
for pattern in patterns:
if pattern.lower() in commit_message.lower():
raise TriggerIgnoreEventError(
f"Commit message contains ignored pattern: '{pattern}'"
)
# Path filtering
paths_filter = parameters.get("paths", "")
if paths_filter:
patterns = [p.strip() for p in paths_filter.split(",") if p.strip()]
if patterns:
# Collect all changed files
all_files = set()
for commit in payload.get("commits", []):
all_files.update(commit.get("added", []))
all_files.update(commit.get("modified", []))
all_files.update(commit.get("removed", []))
# Check if any file matches the patterns
file_matched = False
for file_path in all_files:
for pattern in patterns:
if fnmatch.fnmatch(file_path, pattern):
file_matched = True
break
if file_matched:
break
if not file_matched and all_files: # Only filter if there are files to check
raise TriggerIgnoreEventError(
f"No files match the path patterns: {', '.join(patterns)}"
)
# Extract repository and sender information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Extract commits information
commits = []
@@ -17,17 +17,69 @@ description:
pt_BR: Este gatilho é ativado quando commits são enviados para um repositório do GitHub, fornecendo informações detalhadas sobre os commits, o branch para o qual foram enviados e o repositório.
parameters:
- name: branch_filter
- name: branches
label:
en_US: Branch Name Filter
zh_Hans: 分支名称过滤
pt_BR: Filtro de Nome do Branch
en_US: Branch Filter
zh_Hans: 分支过滤
pt_BR: Filtro de Branch
type: string
required: false
description:
en_US: Filter by specific branch name (optional)
zh_Hans: 按特定分支名称过滤(可选)
pt_BR: Filtrar por nome específico do branch (opcional)
placeholder:
en_US: "e.g., main, develop, release/* (comma-separated, supports wildcards)"
zh_Hans: "例如:main, develop, release/*(逗号分隔,支持通配符)"
pt_BR: "ex: main, develop, release/* (separados por vírgula, suporta wildcards)"
help:
en_US: "Only trigger for commits to these branches. Leave empty for all branches."
zh_Hans: "仅对这些分支的提交触发。留空则监听所有分支。"
pt_BR: "Disparar apenas para commits nestes branches. Deixe vazio para todos."
- name: paths
label:
en_US: Path Filter
zh_Hans: 路径过滤
pt_BR: Filtro de Caminho
type: string
required: false
placeholder:
en_US: "e.g., src/**, *.js, docs/*.md (comma-separated glob patterns)"
zh_Hans: "例如:src/**, *.js, docs/*.md(逗号分隔的 glob 模式)"
pt_BR: "ex: src/**, *.js, docs/*.md (padrões glob separados por vírgula)"
help:
en_US: "Only trigger when files matching these patterns are changed"
zh_Hans: "仅当匹配这些模式的文件发生变化时触发"
pt_BR: "Disparar apenas quando arquivos correspondentes forem alterados"
- name: ignore_patterns
label:
en_US: Ignore Commit Messages
zh_Hans: 忽略提交消息
pt_BR: Ignorar Mensagens de Commit
type: string
required: false
placeholder:
en_US: "e.g., [skip ci], WIP, [no-trigger] (comma-separated)"
zh_Hans: "例如:[skip ci], WIP, [no-trigger](逗号分隔)"
pt_BR: "ex: [skip ci], WIP, [no-trigger] (separados por vírgula)"
help:
en_US: "Ignore commits with messages containing these patterns"
zh_Hans: "忽略包含这些模式的提交消息"
pt_BR: "Ignorar commits com mensagens contendo estes padrões"
- name: exclude_authors
label:
en_US: Exclude Authors
zh_Hans: 排除作者
pt_BR: Excluir Autores
type: string
required: false
placeholder:
en_US: "e.g., dependabot[bot], renovate[bot] (comma-separated)"
zh_Hans: "例如:dependabot[bot], renovate[bot](逗号分隔)"
pt_BR: "ex: dependabot[bot], renovate[bot] (separados por vírgula)"
help:
en_US: "Ignore commits from these authors"
zh_Hans: "忽略这些作者的提交"
pt_BR: "Ignorar commits destes autores"
output_schema:
type: object
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -18,84 +19,20 @@ class ReleaseCreatedTrigger(TriggerEvent):
def _trigger(self, request: Request, parameters: Mapping[str, Any]) -> Event:
"""
Handle GitHub release created event trigger
Parameters:
- tag_filter: Filter by specific tag name (optional)
"""
# Get the event payload
payload = request.get_json()
if not payload:
raise ValueError("No payload received")
# Verify this is a created action
# Verify this is the expected action
action = payload.get("action", "")
if action != "created":
# This trigger only handles created events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action '{action}' is not 'created'")
# Extract release and repository information
release = payload.get("release", {})
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Apply tag filter if specified
tag_filter = parameters.get("tag_filter")
if tag_filter:
tag_name = release.get("tag_name", "")
if tag_name != tag_filter:
# Skip this event if it doesn't match the tag filter
return Event(variables={})
# Extract assets
assets = [
{
"id": asset.get("id"),
"name": asset.get("name", ""),
"size": asset.get("size", 0),
"download_count": asset.get("download_count", 0),
"browser_download_url": asset.get("browser_download_url", ""),
}
for asset in release.get("assets", [])
]
# Build variables for the workflow
variables = {
"release": {
"id": release.get("id"),
"name": release.get("name", ""),
"tag_name": release.get("tag_name", ""),
"target_commitish": release.get("target_commitish", ""),
"body": release.get("body", ""),
"draft": release.get("draft", False),
"prerelease": release.get("prerelease", False),
"html_url": release.get("html_url", ""),
"created_at": release.get("created_at", ""),
"published_at": release.get("published_at", ""),
"assets": assets,
"author": {
"login": release.get("author", {}).get("login", ""),
"avatar_url": release.get("author", {}).get("avatar_url", ""),
"html_url": release.get("author", {}).get("html_url", ""),
},
},
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"release": payload.get("release"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -18,84 +19,20 @@ class ReleaseDeletedTrigger(TriggerEvent):
def _trigger(self, request: Request, parameters: Mapping[str, Any]) -> Event:
"""
Handle GitHub release deleted event trigger
Parameters:
- tag_filter: Filter by specific tag name (optional)
"""
# Get the event payload
payload = request.get_json()
if not payload:
raise ValueError("No payload received")
# Verify this is a deleted action
# Verify this is the expected action
action = payload.get("action", "")
if action != "deleted":
# This trigger only handles deleted events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action '{action}' is not 'deleted'")
# Extract release and repository information
release = payload.get("release", {})
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Apply tag filter if specified
tag_filter = parameters.get("tag_filter")
if tag_filter:
tag_name = release.get("tag_name", "")
if tag_name != tag_filter:
# Skip this event if it doesn't match the tag filter
return Event(variables={})
# Extract assets
assets = [
{
"id": asset.get("id"),
"name": asset.get("name", ""),
"size": asset.get("size", 0),
"download_count": asset.get("download_count", 0),
"browser_download_url": asset.get("browser_download_url", ""),
}
for asset in release.get("assets", [])
]
# Build variables for the workflow
variables = {
"release": {
"id": release.get("id"),
"name": release.get("name", ""),
"tag_name": release.get("tag_name", ""),
"target_commitish": release.get("target_commitish", ""),
"body": release.get("body", ""),
"draft": release.get("draft", False),
"prerelease": release.get("prerelease", False),
"html_url": release.get("html_url", ""),
"created_at": release.get("created_at", ""),
"published_at": release.get("published_at", ""),
"assets": assets,
"author": {
"login": release.get("author", {}).get("login", ""),
"avatar_url": release.get("author", {}).get("avatar_url", ""),
"html_url": release.get("author", {}).get("html_url", ""),
},
},
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"release": payload.get("release"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -18,84 +19,21 @@ class ReleaseEditedTrigger(TriggerEvent):
def _trigger(self, request: Request, parameters: Mapping[str, Any]) -> Event:
"""
Handle GitHub release edited event trigger
Parameters:
- tag_filter: Filter by specific tag name (optional)
"""
# Get the event payload
payload = request.get_json()
if not payload:
raise ValueError("No payload received")
# Verify this is a edited action
# Verify this is the expected action
action = payload.get("action", "")
if action != "edited":
# This trigger only handles edited events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action '{action}' is not 'edited'")
# Extract release and repository information
release = payload.get("release", {})
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Apply tag filter if specified
tag_filter = parameters.get("tag_filter")
if tag_filter:
tag_name = release.get("tag_name", "")
if tag_name != tag_filter:
# Skip this event if it doesn't match the tag filter
return Event(variables={})
# Extract assets
assets = [
{
"id": asset.get("id"),
"name": asset.get("name", ""),
"size": asset.get("size", 0),
"download_count": asset.get("download_count", 0),
"browser_download_url": asset.get("browser_download_url", ""),
}
for asset in release.get("assets", [])
]
# Build variables for the workflow
variables = {
"release": {
"id": release.get("id"),
"name": release.get("name", ""),
"tag_name": release.get("tag_name", ""),
"target_commitish": release.get("target_commitish", ""),
"body": release.get("body", ""),
"draft": release.get("draft", False),
"prerelease": release.get("prerelease", False),
"html_url": release.get("html_url", ""),
"created_at": release.get("created_at", ""),
"published_at": release.get("published_at", ""),
"assets": assets,
"author": {
"login": release.get("author", {}).get("login", ""),
"avatar_url": release.get("author", {}).get("avatar_url", ""),
"html_url": release.get("author", {}).get("html_url", ""),
},
},
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"release": payload.get("release"),
"changes": payload.get("changes"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -18,84 +19,20 @@ class ReleasePrereleasedTrigger(TriggerEvent):
def _trigger(self, request: Request, parameters: Mapping[str, Any]) -> Event:
"""
Handle GitHub release prereleased event trigger
Parameters:
- tag_filter: Filter by specific tag name (optional)
"""
# Get the event payload
payload = request.get_json()
if not payload:
raise ValueError("No payload received")
# Verify this is a prereleased action
# Verify this is the expected action
action = payload.get("action", "")
if action != "prereleased":
# This trigger only handles prereleased events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action '{action}' is not 'prereleased'")
# Extract release and repository information
release = payload.get("release", {})
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Apply tag filter if specified
tag_filter = parameters.get("tag_filter")
if tag_filter:
tag_name = release.get("tag_name", "")
if tag_name != tag_filter:
# Skip this event if it doesn't match the tag filter
return Event(variables={})
# Extract assets
assets = [
{
"id": asset.get("id"),
"name": asset.get("name", ""),
"size": asset.get("size", 0),
"download_count": asset.get("download_count", 0),
"browser_download_url": asset.get("browser_download_url", ""),
}
for asset in release.get("assets", [])
]
# Build variables for the workflow
variables = {
"release": {
"id": release.get("id"),
"name": release.get("name", ""),
"tag_name": release.get("tag_name", ""),
"target_commitish": release.get("target_commitish", ""),
"body": release.get("body", ""),
"draft": release.get("draft", False),
"prerelease": release.get("prerelease", False),
"html_url": release.get("html_url", ""),
"created_at": release.get("created_at", ""),
"published_at": release.get("published_at", ""),
"assets": assets,
"author": {
"login": release.get("author", {}).get("login", ""),
"avatar_url": release.get("author", {}).get("avatar_url", ""),
"html_url": release.get("author", {}).get("html_url", ""),
},
},
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"release": payload.get("release"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -1,9 +1,11 @@
import fnmatch
from collections.abc import Mapping
from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -17,10 +19,12 @@ class ReleasePublishedTrigger(TriggerEvent):
def _trigger(self, request: Request, parameters: Mapping[str, Any]) -> Event:
"""
Handle GitHub release published event trigger
Handle GitHub release published event trigger with practical filtering
Parameters:
- tag_filter: Filter by specific release tag (optional)
- prerelease_filter: Filter prereleases (exclude/only)
- tag_pattern: Filter by tag patterns with wildcards
- required_assets: Require specific assets to be present
"""
# Get the event payload
payload = request.get_json()
@@ -31,20 +35,63 @@ class ReleasePublishedTrigger(TriggerEvent):
action = payload.get("action", "")
if action != "published":
# This trigger only handles published events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action '{action}' is not 'published'")
# Extract release information
release = payload.get("release", {})
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Apply tag filter if specified
tag_filter = parameters.get("tag_filter")
if tag_filter is not None:
tag_name = release.get("tag_name", "")
if tag_name != tag_filter:
# Skip this event if it doesn't match the tag filter
return Event(variables={})
# Prerelease filtering
prerelease_filter = parameters.get("prerelease_filter")
if prerelease_filter:
is_prerelease = release.get("prerelease", False)
if prerelease_filter == "exclude" and is_prerelease:
raise TriggerIgnoreEventError("Ignoring prerelease")
elif prerelease_filter == "only" and not is_prerelease:
raise TriggerIgnoreEventError("Only prereleases are allowed")
# Tag pattern filtering with wildcards
tag_pattern_filter = parameters.get("tag_pattern", "")
if tag_pattern_filter:
allowed_patterns = [p.strip() for p in tag_pattern_filter.split(",") if p.strip()]
if allowed_patterns:
tag_name = release.get("tag_name", "")
# Check if tag matches any of the patterns
tag_matched = False
for pattern in allowed_patterns:
if fnmatch.fnmatch(tag_name, pattern):
tag_matched = True
break
if not tag_matched:
raise TriggerIgnoreEventError(
f"Tag '{tag_name}' doesn't match allowed patterns: {', '.join(allowed_patterns)}"
)
# Required assets filtering
required_assets_filter = parameters.get("required_assets", "")
if required_assets_filter:
required_patterns = [a.strip() for a in required_assets_filter.split(",") if a.strip()]
if required_patterns:
release_assets = release.get("assets", [])
asset_names = [asset.get("name", "") for asset in release_assets]
# Check if all required assets are present
missing_assets = []
for pattern in required_patterns:
# Check if any asset matches this pattern
pattern_matched = False
for asset_name in asset_names:
if fnmatch.fnmatch(asset_name, pattern):
pattern_matched = True
break
if not pattern_matched:
missing_assets.append(pattern)
if missing_assets:
raise TriggerIgnoreEventError(
f"Release missing required assets: {', '.join(missing_assets)}"
)
# Extract assets information
assets = []
@@ -17,17 +17,60 @@ description:
pt_BR: Este gatilho é ativado quando um release é publicado em um repositório do GitHub, fornecendo informações detalhadas sobre o release incluindo versão, assets e notas de release.
parameters:
- name: tag_filter
- name: prerelease_filter
label:
en_US: Tag Name Filter
zh_Hans: 标签名称过滤
pt_BR: Filtro de Nome da Tag
en_US: Prerelease Filter
zh_Hans: 预发布过滤
pt_BR: Filtro de Pré-release
type: select
required: false
options:
- value: exclude
label:
en_US: Exclude Prereleases
zh_Hans: 排除预发布
pt_BR: Excluir Pré-releases
- value: only
label:
en_US: Only Prereleases
zh_Hans: 仅预发布
pt_BR: Apenas Pré-releases
help:
en_US: "Filter prereleases"
zh_Hans: "过滤预发布版本"
pt_BR: "Filtrar pré-releases"
- name: tag_pattern
label:
en_US: Tag Pattern Filter
zh_Hans: 标签模式过滤
pt_BR: Filtro de Padrão de Tag
type: string
required: false
description:
en_US: Filter by specific release tag (optional)
zh_Hans: 按特定发布标签过滤(可选)
pt_BR: Filtrar por tag específica do release (opcional)
placeholder:
en_US: "e.g., v*.*.*, release-*, 2024.* (comma-separated, supports wildcards)"
zh_Hans: "例如:v*.*.*, release-*, 2024.*(逗号分隔,支持通配符)"
pt_BR: "ex: v*.*.*, release-*, 2024.* (separados por vírgula, suporta wildcards)"
help:
en_US: "Only trigger for releases matching these tag patterns"
zh_Hans: "仅对匹配这些标签模式的发布触发"
pt_BR: "Disparar apenas para releases que correspondam a estes padrões de tag"
- name: required_assets
label:
en_US: Required Assets
zh_Hans: 必需资产
pt_BR: Assets Obrigatórios
type: string
required: false
placeholder:
en_US: "e.g., *.dmg, *.exe, checksums.txt (comma-separated, supports wildcards)"
zh_Hans: "例如:*.dmg, *.exe, checksums.txt(逗号分隔,支持通配符)"
pt_BR: "ex: *.dmg, *.exe, checksums.txt (separados por vírgula, suporta wildcards)"
help:
en_US: "Only trigger if release contains these assets"
zh_Hans: "仅当发布包含这些资产时触发"
pt_BR: "Disparar apenas se o release contiver estes assets"
output_schema:
type: object
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -18,84 +19,20 @@ class ReleaseReleasedTrigger(TriggerEvent):
def _trigger(self, request: Request, parameters: Mapping[str, Any]) -> Event:
"""
Handle GitHub release released event trigger
Parameters:
- tag_filter: Filter by specific tag name (optional)
"""
# Get the event payload
payload = request.get_json()
if not payload:
raise ValueError("No payload received")
# Verify this is a released action
# Verify this is the expected action
action = payload.get("action", "")
if action != "released":
# This trigger only handles released events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action '{action}' is not 'released'")
# Extract release and repository information
release = payload.get("release", {})
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Apply tag filter if specified
tag_filter = parameters.get("tag_filter")
if tag_filter:
tag_name = release.get("tag_name", "")
if tag_name != tag_filter:
# Skip this event if it doesn't match the tag filter
return Event(variables={})
# Extract assets
assets = [
{
"id": asset.get("id"),
"name": asset.get("name", ""),
"size": asset.get("size", 0),
"download_count": asset.get("download_count", 0),
"browser_download_url": asset.get("browser_download_url", ""),
}
for asset in release.get("assets", [])
]
# Build variables for the workflow
variables = {
"release": {
"id": release.get("id"),
"name": release.get("name", ""),
"tag_name": release.get("tag_name", ""),
"target_commitish": release.get("target_commitish", ""),
"body": release.get("body", ""),
"draft": release.get("draft", False),
"prerelease": release.get("prerelease", False),
"html_url": release.get("html_url", ""),
"created_at": release.get("created_at", ""),
"published_at": release.get("published_at", ""),
"assets": assets,
"author": {
"login": release.get("author", {}).get("login", ""),
"avatar_url": release.get("author", {}).get("avatar_url", ""),
"html_url": release.get("author", {}).get("html_url", ""),
},
},
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"release": payload.get("release"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -18,84 +19,20 @@ class ReleaseUnpublishedTrigger(TriggerEvent):
def _trigger(self, request: Request, parameters: Mapping[str, Any]) -> Event:
"""
Handle GitHub release unpublished event trigger
Parameters:
- tag_filter: Filter by specific tag name (optional)
"""
# Get the event payload
payload = request.get_json()
if not payload:
raise ValueError("No payload received")
# Verify this is a unpublished action
# Verify this is the expected action
action = payload.get("action", "")
if action != "unpublished":
# This trigger only handles unpublished events
return Event(variables={})
raise TriggerIgnoreEventError(f"Action '{action}' is not 'unpublished'")
# Extract release and repository information
release = payload.get("release", {})
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Apply tag filter if specified
tag_filter = parameters.get("tag_filter")
if tag_filter:
tag_name = release.get("tag_name", "")
if tag_name != tag_filter:
# Skip this event if it doesn't match the tag filter
return Event(variables={})
# Extract assets
assets = [
{
"id": asset.get("id"),
"name": asset.get("name", ""),
"size": asset.get("size", 0),
"download_count": asset.get("download_count", 0),
"browser_download_url": asset.get("browser_download_url", ""),
}
for asset in release.get("assets", [])
]
# Build variables for the workflow
variables = {
"release": {
"id": release.get("id"),
"name": release.get("name", ""),
"tag_name": release.get("tag_name", ""),
"target_commitish": release.get("target_commitish", ""),
"body": release.get("body", ""),
"draft": release.get("draft", False),
"prerelease": release.get("prerelease", False),
"html_url": release.get("html_url", ""),
"created_at": release.get("created_at", ""),
"published_at": release.get("published_at", ""),
"assets": assets,
"author": {
"login": release.get("author", {}).get("login", ""),
"avatar_url": release.get("author", {}).get("avatar_url", ""),
"html_url": release.get("author", {}).get("html_url", ""),
},
},
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"release": payload.get("release"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,50 +25,8 @@ class RepositoryArchivedTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Verify this is a archived action
action = payload.get("action", "")
if action != "archived":
# This trigger only handles archived events
return Event(variables={})
# Extract repository information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Build variables for the workflow
variables = {
"repository": {
"id": repository.get("id"),
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"archived": repository.get("archived", False),
"disabled": repository.get("disabled", False),
"default_branch": repository.get("default_branch", ""),
"topics": repository.get("topics", []),
"language": repository.get("language", ""),
"size": repository.get("size", 0),
"stargazers_count": repository.get("stargazers_count", 0),
"watchers_count": repository.get("watchers_count", 0),
"forks_count": repository.get("forks_count", 0),
"open_issues_count": repository.get("open_issues_count", 0),
"created_at": repository.get("created_at", ""),
"updated_at": repository.get("updated_at", ""),
"pushed_at": repository.get("pushed_at", ""),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,50 +25,8 @@ class RepositoryCreatedTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Verify this is a created action
action = payload.get("action", "")
if action != "created":
# This trigger only handles created events
return Event(variables={})
# Extract repository information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Build variables for the workflow
variables = {
"repository": {
"id": repository.get("id"),
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"archived": repository.get("archived", False),
"disabled": repository.get("disabled", False),
"default_branch": repository.get("default_branch", ""),
"topics": repository.get("topics", []),
"language": repository.get("language", ""),
"size": repository.get("size", 0),
"stargazers_count": repository.get("stargazers_count", 0),
"watchers_count": repository.get("watchers_count", 0),
"forks_count": repository.get("forks_count", 0),
"open_issues_count": repository.get("open_issues_count", 0),
"created_at": repository.get("created_at", ""),
"updated_at": repository.get("updated_at", ""),
"pushed_at": repository.get("pushed_at", ""),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,50 +25,8 @@ class RepositoryDeletedTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Verify this is a deleted action
action = payload.get("action", "")
if action != "deleted":
# This trigger only handles deleted events
return Event(variables={})
# Extract repository information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Build variables for the workflow
variables = {
"repository": {
"id": repository.get("id"),
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"archived": repository.get("archived", False),
"disabled": repository.get("disabled", False),
"default_branch": repository.get("default_branch", ""),
"topics": repository.get("topics", []),
"language": repository.get("language", ""),
"size": repository.get("size", 0),
"stargazers_count": repository.get("stargazers_count", 0),
"watchers_count": repository.get("watchers_count", 0),
"forks_count": repository.get("forks_count", 0),
"open_issues_count": repository.get("open_issues_count", 0),
"created_at": repository.get("created_at", ""),
"updated_at": repository.get("updated_at", ""),
"pushed_at": repository.get("pushed_at", ""),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,50 +25,9 @@ class RepositoryEditedTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Verify this is a edited action
action = payload.get("action", "")
if action != "edited":
# This trigger only handles edited events
return Event(variables={})
# Extract repository information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Build variables for the workflow
variables = {
"repository": {
"id": repository.get("id"),
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"archived": repository.get("archived", False),
"disabled": repository.get("disabled", False),
"default_branch": repository.get("default_branch", ""),
"topics": repository.get("topics", []),
"language": repository.get("language", ""),
"size": repository.get("size", 0),
"stargazers_count": repository.get("stargazers_count", 0),
"watchers_count": repository.get("watchers_count", 0),
"forks_count": repository.get("forks_count", 0),
"open_issues_count": repository.get("open_issues_count", 0),
"created_at": repository.get("created_at", ""),
"updated_at": repository.get("updated_at", ""),
"pushed_at": repository.get("pushed_at", ""),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"changes": payload.get("changes"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,50 +25,8 @@ class RepositoryPrivatizedTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Verify this is a privatized action
action = payload.get("action", "")
if action != "privatized":
# This trigger only handles privatized events
return Event(variables={})
# Extract repository information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Build variables for the workflow
variables = {
"repository": {
"id": repository.get("id"),
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"archived": repository.get("archived", False),
"disabled": repository.get("disabled", False),
"default_branch": repository.get("default_branch", ""),
"topics": repository.get("topics", []),
"language": repository.get("language", ""),
"size": repository.get("size", 0),
"stargazers_count": repository.get("stargazers_count", 0),
"watchers_count": repository.get("watchers_count", 0),
"forks_count": repository.get("forks_count", 0),
"open_issues_count": repository.get("open_issues_count", 0),
"created_at": repository.get("created_at", ""),
"updated_at": repository.get("updated_at", ""),
"pushed_at": repository.get("pushed_at", ""),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,50 +25,8 @@ class RepositoryPublicizedTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Verify this is a publicized action
action = payload.get("action", "")
if action != "publicized":
# This trigger only handles publicized events
return Event(variables={})
# Extract repository information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Build variables for the workflow
variables = {
"repository": {
"id": repository.get("id"),
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"archived": repository.get("archived", False),
"disabled": repository.get("disabled", False),
"default_branch": repository.get("default_branch", ""),
"topics": repository.get("topics", []),
"language": repository.get("language", ""),
"size": repository.get("size", 0),
"stargazers_count": repository.get("stargazers_count", 0),
"watchers_count": repository.get("watchers_count", 0),
"forks_count": repository.get("forks_count", 0),
"open_issues_count": repository.get("open_issues_count", 0),
"created_at": repository.get("created_at", ""),
"updated_at": repository.get("updated_at", ""),
"pushed_at": repository.get("pushed_at", ""),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,50 +25,9 @@ class RepositoryRenamedTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Verify this is a renamed action
action = payload.get("action", "")
if action != "renamed":
# This trigger only handles renamed events
return Event(variables={})
# Extract repository information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Build variables for the workflow
variables = {
"repository": {
"id": repository.get("id"),
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"archived": repository.get("archived", False),
"disabled": repository.get("disabled", False),
"default_branch": repository.get("default_branch", ""),
"topics": repository.get("topics", []),
"language": repository.get("language", ""),
"size": repository.get("size", 0),
"stargazers_count": repository.get("stargazers_count", 0),
"watchers_count": repository.get("watchers_count", 0),
"forks_count": repository.get("forks_count", 0),
"open_issues_count": repository.get("open_issues_count", 0),
"created_at": repository.get("created_at", ""),
"updated_at": repository.get("updated_at", ""),
"pushed_at": repository.get("pushed_at", ""),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"changes": payload.get("changes"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,50 +25,9 @@ class RepositoryTransferredTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Verify this is a transferred action
action = payload.get("action", "")
if action != "transferred":
# This trigger only handles transferred events
return Event(variables={})
# Extract repository information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Build variables for the workflow
variables = {
"repository": {
"id": repository.get("id"),
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"archived": repository.get("archived", False),
"disabled": repository.get("disabled", False),
"default_branch": repository.get("default_branch", ""),
"topics": repository.get("topics", []),
"language": repository.get("language", ""),
"size": repository.get("size", 0),
"stargazers_count": repository.get("stargazers_count", 0),
"watchers_count": repository.get("watchers_count", 0),
"forks_count": repository.get("forks_count", 0),
"open_issues_count": repository.get("open_issues_count", 0),
"created_at": repository.get("created_at", ""),
"updated_at": repository.get("updated_at", ""),
"pushed_at": repository.get("pushed_at", ""),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"changes": payload.get("changes"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,50 +25,8 @@ class RepositoryUnarchivedTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Verify this is a unarchived action
action = payload.get("action", "")
if action != "unarchived":
# This trigger only handles unarchived events
return Event(variables={})
# Extract repository information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Build variables for the workflow
variables = {
"repository": {
"id": repository.get("id"),
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"archived": repository.get("archived", False),
"disabled": repository.get("disabled", False),
"default_branch": repository.get("default_branch", ""),
"topics": repository.get("topics", []),
"language": repository.get("language", ""),
"size": repository.get("size", 0),
"stargazers_count": repository.get("stargazers_count", 0),
"watchers_count": repository.get("watchers_count", 0),
"forks_count": repository.get("forks_count", 0),
"open_issues_count": repository.get("open_issues_count", 0),
"created_at": repository.get("created_at", ""),
"updated_at": repository.get("updated_at", ""),
"pushed_at": repository.get("pushed_at", ""),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,43 +25,9 @@ class StarCreatedTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Verify this is a created action
action = payload.get("action", "")
if action != "created":
# This trigger only handles created events
return Event(variables={})
# Extract information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
starred_at = payload.get("starred_at", "")
# Build variables for the workflow
variables = {
"star": {
"starred_at": starred_at,
},
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"stargazers_count": repository.get("stargazers_count", 0),
"watchers_count": repository.get("watchers_count", 0),
"forks_count": repository.get("forks_count", 0),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"starred_at": payload.get("starred_at"),
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,38 +25,8 @@ class StarDeletedTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Verify this is a deleted action
action = payload.get("action", "")
if action != "deleted":
# This trigger only handles deleted events
return Event(variables={})
# Extract repository information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Build variables for the workflow
variables = {
"starred_at": payload.get("starred_at"), # Usually null for deleted events
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"stargazers_count": repository.get("stargazers_count", 0),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})
@@ -4,6 +4,7 @@ from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Event
from dify_plugin.errors.trigger import TriggerIgnoreEventError
from dify_plugin.interfaces.trigger import TriggerEvent
@@ -24,39 +25,8 @@ class WatchTrigger(TriggerEvent):
if not payload:
raise ValueError("No payload received")
# Verify this is a started action (watch events are usually "started")
action = payload.get("action", "started")
if action != "started":
# This trigger only handles started events
return Event(variables={})
# Extract repository information
repository = payload.get("repository", {})
sender = payload.get("sender", {})
# Build variables for the workflow
variables = {
"repository": {
"name": repository.get("name", ""),
"full_name": repository.get("full_name", ""),
"html_url": repository.get("html_url", ""),
"description": repository.get("description", ""),
"private": repository.get("private", False),
"watchers_count": repository.get("watchers_count", 0),
"stargazers_count": repository.get("stargazers_count", 0),
"forks_count": repository.get("forks_count", 0),
"owner": {
"login": repository.get("owner", {}).get("login", ""),
"avatar_url": repository.get("owner", {}).get("avatar_url", ""),
"html_url": repository.get("owner", {}).get("html_url", ""),
},
},
"sender": {
"login": sender.get("login", ""),
"avatar_url": sender.get("avatar_url", ""),
"html_url": sender.get("html_url", ""),
"type": sender.get("type", ""),
},
}
return Event(variables=variables)
# Return the relevant payload fields directly
return Event(variables={
"repository": payload.get("repository"),
"sender": payload.get("sender"),
})

Some files were not shown because too many files have changed in this diff Show More