mirror of
https://github.com/langgenius/dify-plugin-sdks.git
synced 2026-08-25 12:29:32 -04:00
refactor: streamline GitHub issue trigger implementation
- Removed the deprecated IssuesTrigger class and replaced it with a more focused IssueOpenedTrigger class to handle specific events when a new issue is opened. - Updated the GitHub trigger YAML configuration to reflect changes in the subscription schema and parameters. - Enhanced the validation logic for issue parameters, including title patterns, labels, assignees, authors, milestones, and body content. - Improved the overall structure and clarity of the trigger implementation, ensuring better maintainability and functionality. These changes contribute to a more efficient and organized handling of GitHub issue events, enhancing the plugin's responsiveness to user interactions.
This commit is contained in:
@@ -30,9 +30,10 @@ from dify_plugin.interfaces.trigger import TriggerProvider, TriggerSubscriptionC
|
||||
class GithubProvider(TriggerProvider):
|
||||
"""Handle GitHub webhook event dispatch."""
|
||||
|
||||
_TRIGGER_EVENTS: ClassVar[dict[str, list[str]]] = {
|
||||
"issues": ["issues"],
|
||||
"issue_comment": ["issues"],
|
||||
__TRIGGER_EVENTS_MAPPING: ClassVar[Mapping[str, Mapping[str, list[str]]]] = {
|
||||
"issues": {
|
||||
"opened": ["issue_opened"],
|
||||
}
|
||||
}
|
||||
|
||||
def _dispatch_event(self, subscription: Subscription, request: Request) -> TriggerDispatch:
|
||||
@@ -44,14 +45,19 @@ class GithubProvider(TriggerProvider):
|
||||
if not event_type:
|
||||
raise TriggerDispatchError("Missing GitHub event type header")
|
||||
|
||||
# Validate payload and raise meaningful errors when parsing fails.
|
||||
self._parse_payload(request)
|
||||
|
||||
triggers = self._TRIGGER_EVENTS.get(event_type, [])
|
||||
payload = self._validate_payload(request)
|
||||
triggers = self._dispatch_event_triggers(event_type, payload)
|
||||
response = Response(response='{"status": "ok"}', status=200, mimetype="application/json")
|
||||
return TriggerDispatch(triggers=triggers, response=response)
|
||||
|
||||
def _parse_payload(self, request: Request) -> Mapping[str, Any]:
|
||||
def _dispatch_event_triggers(self, event_type: str, payload: Mapping[str, Any]) -> list[str]:
|
||||
event_type = event_type.lower()
|
||||
if event_type == "issues":
|
||||
action = payload.get("action")
|
||||
return self.__TRIGGER_EVENTS_MAPPING["issues"].get(action, [])
|
||||
return []
|
||||
|
||||
def _validate_payload(self, request: Request) -> Mapping[str, Any]:
|
||||
try:
|
||||
content_type = request.headers.get("Content-Type", "")
|
||||
if "application/x-www-form-urlencoded" in content_type:
|
||||
|
||||
@@ -1,33 +1,47 @@
|
||||
subscription_schema:
|
||||
- name: "webhook_secret"
|
||||
type: "secret-input"
|
||||
required: false
|
||||
label:
|
||||
zh_Hans: "Webhook Secret"
|
||||
en_US: "Webhook Secret"
|
||||
ja_JP: "Webhookシークレット"
|
||||
help:
|
||||
en_US: "Optional webhook secret for validating GitHub webhook requests"
|
||||
ja_JP: "GitHub Webhookリクエストの検証用のオプションのWebhookシークレット"
|
||||
zh_Hans: "可选的用于验证 GitHub webhook 请求的 webhook 密钥"
|
||||
- name: "webhook_secret"
|
||||
type: "secret-input"
|
||||
required: false
|
||||
label:
|
||||
zh_Hans: "Webhook Secret"
|
||||
en_US: "Webhook Secret"
|
||||
ja_JP: "Webhookシークレット"
|
||||
help:
|
||||
en_US: "Optional webhook secret for validating GitHub webhook requests"
|
||||
ja_JP: "GitHub Webhookリクエストの検証用のオプションのWebhookシークレット"
|
||||
zh_Hans: "可选的用于验证 GitHub webhook 请求的 webhook 密钥"
|
||||
|
||||
subscription_constructor: # OPTIONAL
|
||||
subscription_constructor:
|
||||
parameters:
|
||||
- name: "repository"
|
||||
- name: "repository"
|
||||
label:
|
||||
en_US: "Repository"
|
||||
zh_Hans: "仓库"
|
||||
ja_JP: "リポジトリ"
|
||||
type: "dynamic-select"
|
||||
required: true
|
||||
placeholder:
|
||||
en_US: "owner/repo"
|
||||
zh_Hans: "owner/repo"
|
||||
ja_JP: "owner/repo"
|
||||
help:
|
||||
en_US: "GitHub repository in format owner/repo (e.g., microsoft/vscode)"
|
||||
zh_Hans: "GitHub 仓库,格式为 owner/repo(例如:microsoft/vscode)"
|
||||
ja_JP: "GitHubリポジトリは owner/repo 形式で入力してください(例: microsoft/vscode)"
|
||||
|
||||
- name: "triggers"
|
||||
label:
|
||||
en_US: "Triggers"
|
||||
zh_Hans: "触发器"
|
||||
ja_JP: "トリガー"
|
||||
type: "checkbox"
|
||||
required: true
|
||||
options:
|
||||
- value: "issues"
|
||||
label:
|
||||
en_US: "Repository"
|
||||
zh_Hans: "仓库"
|
||||
ja_JP: "リポジトリ"
|
||||
type: "dynamic-select"
|
||||
required: true
|
||||
placeholder:
|
||||
en_US: "owner/repo"
|
||||
zh_Hans: "owner/repo"
|
||||
ja_JP: "owner/repo"
|
||||
help:
|
||||
en_US: "GitHub repository in format owner/repo (e.g., microsoft/vscode)"
|
||||
zh_Hans: "GitHub 仓库,格式为 owner/repo(例如:microsoft/vscode)"
|
||||
ja_JP: "GitHubリポジトリは owner/repo 形式で入力してください(例: microsoft/vscode)"
|
||||
en_US: "Issues"
|
||||
zh_Hans: "议题"
|
||||
ja_JP: "イシュー"
|
||||
credentials_schema:
|
||||
access_tokens:
|
||||
help:
|
||||
@@ -47,52 +61,51 @@ subscription_constructor: # OPTIONAL
|
||||
url: https://github.com/settings/tokens?type=beta
|
||||
oauth_schema:
|
||||
client_schema:
|
||||
- name: "client_id"
|
||||
type: "secret-input"
|
||||
required: true
|
||||
url: https://github.com/settings/applications/new
|
||||
placeholder:
|
||||
en_US: "Please input your Client ID"
|
||||
zh_Hans: "请输入你的 Client ID"
|
||||
ja_JP: "クライアントIDを入力してください"
|
||||
help:
|
||||
en_US: "Client ID is used to authenticate requests to the GitHub API."
|
||||
zh_Hans: "Client ID 用于认证请求到 GitHub API。"
|
||||
ja_JP: "クライアントIDはGitHub APIへのリクエスト認証に使用されます。"
|
||||
label:
|
||||
zh_Hans: "Client ID"
|
||||
en_US: "Client ID"
|
||||
ja_JP: "クライアントID"
|
||||
- name: "client_secret"
|
||||
type: "secret-input"
|
||||
required: true
|
||||
url: https://github.com/settings/applications/new
|
||||
placeholder:
|
||||
en_US: "Please input your Client Secret"
|
||||
zh_Hans: "请输入你的 Client Secret"
|
||||
ja_JP: "クライアントシークレットを入力してください"
|
||||
help:
|
||||
en_US: "Client Secret is used to authenticate requests to the GitHub API."
|
||||
zh_Hans: "Client Secret 用于认证请求到 GitHub API。"
|
||||
ja_JP: "クライアントシークレットはGitHub APIへのリクエスト認証に使用されます。"
|
||||
label:
|
||||
zh_Hans: "Client Secret"
|
||||
en_US: "Client Secret"
|
||||
ja_JP: "クライアントシークレット"
|
||||
- name: "client_id"
|
||||
type: "secret-input"
|
||||
required: true
|
||||
url: https://github.com/settings/applications/new
|
||||
placeholder:
|
||||
en_US: "Please input your Client ID"
|
||||
zh_Hans: "请输入你的 Client ID"
|
||||
ja_JP: "クライアントIDを入力してください"
|
||||
help:
|
||||
en_US: "Client ID is used to authenticate requests to the GitHub API."
|
||||
zh_Hans: "Client ID 用于认证请求到 GitHub API。"
|
||||
ja_JP: "クライアントIDはGitHub APIへのリクエスト認証に使用されます。"
|
||||
label:
|
||||
zh_Hans: "Client ID"
|
||||
en_US: "Client ID"
|
||||
ja_JP: "クライアントID"
|
||||
- name: "client_secret"
|
||||
type: "secret-input"
|
||||
required: true
|
||||
url: https://github.com/settings/applications/new
|
||||
placeholder:
|
||||
en_US: "Please input your Client Secret"
|
||||
zh_Hans: "请输入你的 Client Secret"
|
||||
ja_JP: "クライアントシークレットを入力してください"
|
||||
help:
|
||||
en_US: "Client Secret is used to authenticate requests to the GitHub API."
|
||||
zh_Hans: "Client Secret 用于认证请求到 GitHub API。"
|
||||
ja_JP: "クライアントシークレットはGitHub APIへのリクエスト認証に使用されます。"
|
||||
label:
|
||||
zh_Hans: "Client Secret"
|
||||
en_US: "Client Secret"
|
||||
ja_JP: "クライアントシークレット"
|
||||
credentials_schema:
|
||||
- name: "access_tokens"
|
||||
type: "secret-input"
|
||||
label:
|
||||
zh_Hans: "Access Token"
|
||||
en_US: "Access Token"
|
||||
ja_JP: "アクセストークン"
|
||||
- name: "access_tokens"
|
||||
type: "secret-input"
|
||||
label:
|
||||
zh_Hans: "Access Token"
|
||||
en_US: "Access Token"
|
||||
ja_JP: "アクセストークン"
|
||||
extra:
|
||||
python:
|
||||
source: provider/github.py
|
||||
|
||||
triggers:
|
||||
# Core Events (Consolidated)
|
||||
- triggers/issues.yaml # Handles: opened, closed, reopened, edited, assigned, unassigned, labeled, unlabeled, etc.
|
||||
- triggers/issues/issue_opened.yaml
|
||||
|
||||
identity:
|
||||
author: langgenius
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
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
|
||||
|
||||
|
||||
class IssuesTrigger(TriggerEvent):
|
||||
"""
|
||||
GitHub Issue Event Trigger
|
||||
|
||||
This unified trigger handles all GitHub issue 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 event trigger with comprehensive filtering
|
||||
|
||||
Parameters:
|
||||
- event: Select which issue actions to trigger on (opened, closed, reopened, edited, assigned, labeled, etc.)
|
||||
- labels: Only trigger if issue has these labels (comma-separated)
|
||||
- exclude_labels: Don't trigger if issue has these labels (comma-separated)
|
||||
- assignee: Only trigger if assigned to these users (comma-separated)
|
||||
- authors: Only trigger for issues from these authors (comma-separated)
|
||||
- exclude_authors: Don't trigger for issues from these authors (comma-separated)
|
||||
- milestone: Only trigger for issues with these milestones (comma-separated)
|
||||
- title_pattern: Only trigger if title matches this pattern (supports wildcards, comma-separated)
|
||||
- body_contains: Only trigger if body contains these keywords (comma-separated)
|
||||
"""
|
||||
# Get the event payload
|
||||
payload = request.get_json()
|
||||
if not payload:
|
||||
raise ValueError("No payload received")
|
||||
|
||||
# Get the action type
|
||||
action = payload.get("action", "")
|
||||
|
||||
# Apply event filter
|
||||
event = parameters.get("event", [])
|
||||
if event and action not in event:
|
||||
raise TriggerIgnoreEventError(f"Action '{action}' not in filter list: {event}")
|
||||
|
||||
return Event(
|
||||
variables={
|
||||
"action": action,
|
||||
# TODO: add more variables depends on the trigger configuration
|
||||
}
|
||||
)
|
||||
@@ -1,484 +0,0 @@
|
||||
identity:
|
||||
name: issues
|
||||
author: langgenius
|
||||
label:
|
||||
en_US: Issues
|
||||
zh_Hans: 议题
|
||||
ja_JP: イシュー
|
||||
|
||||
description:
|
||||
human:
|
||||
en_US: Triggers on issue events (opened, closed, reopened, edited, assigned, labeled, etc.)
|
||||
zh_Hans: 在议题事件时触发(打开、关闭、重新打开、编辑、分配、标记等)
|
||||
ja_JP: イシューイベント(作成、クローズ、再オープン、編集、担当者割り当て、ラベル付与など)でトリガーされます
|
||||
llm:
|
||||
en_US: This trigger activates on various GitHub issue events, providing comprehensive information about the issue, repository, and involved users.
|
||||
zh_Hans: 此触发器在各种 GitHub 议题事件时激活,提供有关议题、仓库和相关用户的综合信息。
|
||||
ja_JP: このトリガーは様々なGitHubイシューイベントで発動し、イシュー、リポジトリ、関係ユーザーの包括的な情報を提供します。
|
||||
|
||||
parameters:
|
||||
- name: event
|
||||
label:
|
||||
en_US: Event
|
||||
zh_Hans: 事件
|
||||
ja_JP: イベント
|
||||
type: checkbox
|
||||
required: false
|
||||
options:
|
||||
- value: opened
|
||||
label:
|
||||
en_US: Opened
|
||||
zh_Hans: 新建议题
|
||||
ja_JP: 作成
|
||||
- value: closed
|
||||
label:
|
||||
en_US: Closed
|
||||
zh_Hans: 议题关闭
|
||||
ja_JP: クローズ
|
||||
- value: reopened
|
||||
label:
|
||||
en_US: Reopened
|
||||
zh_Hans: 关闭后再次开启
|
||||
ja_JP: 再オープン
|
||||
- value: edited
|
||||
label:
|
||||
en_US: Edited
|
||||
zh_Hans: 议题内容被修改
|
||||
ja_JP: 編集
|
||||
- value: assigned
|
||||
label:
|
||||
en_US: Assigned
|
||||
zh_Hans: 指定负责人
|
||||
ja_JP: 担当者割り当て
|
||||
- value: unassigned
|
||||
label:
|
||||
en_US: Unassigned
|
||||
zh_Hans: 移除负责人
|
||||
ja_JP: 担当者解除
|
||||
- value: labeled
|
||||
label:
|
||||
en_US: Labeled
|
||||
zh_Hans: 议题被打标签
|
||||
ja_JP: ラベル付与
|
||||
- value: unlabeled
|
||||
label:
|
||||
en_US: Unlabeled
|
||||
zh_Hans: 议题标签被移除
|
||||
ja_JP: ラベル削除
|
||||
- value: milestoned
|
||||
label:
|
||||
en_US: Milestoned
|
||||
zh_Hans: 设置目标里程碑
|
||||
ja_JP: マイルストーン追加
|
||||
- value: demilestoned
|
||||
label:
|
||||
en_US: Demilestoned
|
||||
zh_Hans: 取消目标里程碑
|
||||
ja_JP: マイルストーン削除
|
||||
- value: pinned
|
||||
label:
|
||||
en_US: Pinned
|
||||
zh_Hans: 议题被置顶
|
||||
ja_JP: ピン留め
|
||||
- value: unpinned
|
||||
label:
|
||||
en_US: Unpinned
|
||||
zh_Hans: 议题取消置顶
|
||||
ja_JP: ピン留め解除
|
||||
- value: locked
|
||||
label:
|
||||
en_US: Locked
|
||||
zh_Hans: 议题被锁定,无法评论
|
||||
ja_JP: ロック
|
||||
- value: unlocked
|
||||
label:
|
||||
en_US: Unlocked
|
||||
zh_Hans: 议题解锁,允许评论
|
||||
ja_JP: ロック解除
|
||||
- value: transferred
|
||||
label:
|
||||
en_US: Transferred
|
||||
zh_Hans: 议题转移到其他仓库
|
||||
ja_JP: 転送
|
||||
multiple: true
|
||||
help:
|
||||
en_US: "Select which issue actions to trigger on (leave empty for all)"
|
||||
zh_Hans: "选择触发的议题操作(留空表示所有)"
|
||||
ja_JP: "どのイシューアクションでトリガーするか選択してください(空欄ですべて)"
|
||||
|
||||
- name: labels
|
||||
label:
|
||||
en_US: Required Labels
|
||||
zh_Hans: 必需标签
|
||||
ja_JP: 必須ラベル
|
||||
type: string
|
||||
required: false
|
||||
placeholder:
|
||||
en_US: "e.g., bug, enhancement, urgent (comma-separated)"
|
||||
zh_Hans: "例如:bug, enhancement, urgent(逗号分隔)"
|
||||
ja_JP: "例: bug, enhancement, urgent(カンマ区切り)"
|
||||
help:
|
||||
en_US: "Only trigger if issue has these labels"
|
||||
zh_Hans: "仅当议题有这些标签时触发"
|
||||
ja_JP: "イシューがこれらのラベルを持つ場合のみトリガー"
|
||||
|
||||
- name: exclude_labels
|
||||
label:
|
||||
en_US: Exclude Labels
|
||||
zh_Hans: 排除标签
|
||||
ja_JP: 除外ラベル
|
||||
type: string
|
||||
required: false
|
||||
placeholder:
|
||||
en_US: "e.g., wontfix, duplicate (comma-separated)"
|
||||
zh_Hans: "例如:wontfix, duplicate(逗号分隔)"
|
||||
ja_JP: "例: wontfix, duplicate(カンマ区切り)"
|
||||
help:
|
||||
en_US: "Don't trigger if issue has these labels"
|
||||
zh_Hans: "如果议题有这些标签则不触发"
|
||||
ja_JP: "イシューがこれらのラベルを持つ場合はトリガーしない"
|
||||
|
||||
- name: assignee
|
||||
label:
|
||||
en_US: Assignee Filter
|
||||
zh_Hans: 受理人过滤
|
||||
ja_JP: 担当者フィルター
|
||||
type: string
|
||||
required: false
|
||||
placeholder:
|
||||
en_US: "e.g., username1, username2 (comma-separated)"
|
||||
zh_Hans: "例如:username1, username2(逗号分隔)"
|
||||
ja_JP: "例: username1, username2(カンマ区切り)"
|
||||
help:
|
||||
en_US: "Only trigger if assigned to these users"
|
||||
zh_Hans: "仅当分配给这些用户时触发"
|
||||
ja_JP: "これらのユーザーに割り当てられた場合のみトリガー"
|
||||
|
||||
- name: authors
|
||||
label:
|
||||
en_US: Authors
|
||||
zh_Hans: 作者
|
||||
ja_JP: 作成者
|
||||
type: string
|
||||
required: false
|
||||
placeholder:
|
||||
en_US: "e.g., user1, user2 (comma-separated)"
|
||||
zh_Hans: "例如:user1, user2(逗号分隔)"
|
||||
ja_JP: "例: user1, user2(カンマ区切り)"
|
||||
help:
|
||||
en_US: "Only trigger for issues from these authors"
|
||||
zh_Hans: "仅对这些作者的议题触发"
|
||||
ja_JP: "これらの作成者のイシューのみトリガー"
|
||||
|
||||
- name: exclude_authors
|
||||
label:
|
||||
en_US: Exclude Authors
|
||||
zh_Hans: 排除作者
|
||||
ja_JP: 除外作成者
|
||||
type: string
|
||||
required: false
|
||||
placeholder:
|
||||
en_US: "e.g., bot1, bot2 (comma-separated)"
|
||||
zh_Hans: "例如:bot1, bot2(逗号分隔)"
|
||||
ja_JP: "例: bot1, bot2(カンマ区切り)"
|
||||
help:
|
||||
en_US: "Don't trigger for issues from these authors"
|
||||
zh_Hans: "不对这些作者的议题触发"
|
||||
ja_JP: "これらの作成者のイシューはトリガーしない"
|
||||
|
||||
- name: milestone
|
||||
label:
|
||||
en_US: Milestone
|
||||
zh_Hans: 里程碑
|
||||
ja_JP: マイルストーン
|
||||
type: string
|
||||
required: false
|
||||
placeholder:
|
||||
en_US: "e.g., v1.0, v2.0 (comma-separated) (default: all)"
|
||||
zh_Hans: "例如:v1.0, v2.0(逗号分隔)(默认所有)"
|
||||
ja_JP: "例: v1.0, v2.0(カンマ区切り)(デフォルト: 全て)"
|
||||
help:
|
||||
en_US: "Only trigger for issues with these milestones"
|
||||
zh_Hans: "仅对具有这些里程碑的议题触发"
|
||||
ja_JP: "これらのマイルストーンのイシューのみトリガー"
|
||||
|
||||
- name: title_pattern
|
||||
label:
|
||||
en_US: Title Pattern
|
||||
zh_Hans: 标题模式
|
||||
ja_JP: タイトルパターン
|
||||
type: string
|
||||
required: false
|
||||
placeholder:
|
||||
en_US: "e.g., [BUG]*, [FEATURE]* (supports wildcards)"
|
||||
zh_Hans: "例如:[BUG]*, [FEATURE]*(支持通配符)"
|
||||
ja_JP: "例: [BUG]*, [FEATURE]*(ワイルドカード対応)"
|
||||
help:
|
||||
en_US: "Only trigger if title matches this pattern"
|
||||
zh_Hans: "仅当标题匹配此模式时触发"
|
||||
ja_JP: "タイトルがこのパターンに一致する場合のみトリガー"
|
||||
|
||||
- name: body_contains
|
||||
label:
|
||||
en_US: Body Contains
|
||||
zh_Hans: 正文包含
|
||||
ja_JP: 本文に含む
|
||||
type: string
|
||||
required: false
|
||||
placeholder:
|
||||
en_US: "e.g., regression, critical (comma-separated keywords)"
|
||||
zh_Hans: "例如:regression, critical(逗号分隔的关键词)"
|
||||
ja_JP: "例: regression, critical(カンマ区切りキーワード)"
|
||||
help:
|
||||
en_US: "Only trigger if body contains these keywords"
|
||||
zh_Hans: "仅当正文包含这些关键词时触发"
|
||||
ja_JP: "本文にこれらのキーワードが含まれる場合のみトリガー"
|
||||
|
||||
output_schema:
|
||||
type: object
|
||||
properties:
|
||||
action:
|
||||
type: string
|
||||
description: The action that was performed on the issue (opened, edited, deleted, pinned, unpinned, closed, reopened, assigned, unassigned, labeled, unlabeled, locked, unlocked, transferred, milestoned, demilestoned)
|
||||
issue:
|
||||
type: object
|
||||
description: The issue itself
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
description: Unique identifier of the issue
|
||||
number:
|
||||
type: integer
|
||||
description: Number uniquely identifying the issue within its repository
|
||||
title:
|
||||
type: string
|
||||
description: Title of the issue
|
||||
body:
|
||||
type: string
|
||||
description: Contents of the issue
|
||||
state:
|
||||
type: string
|
||||
description: State of the issue (open or closed)
|
||||
state_reason:
|
||||
type: string
|
||||
description: The reason for the current state (completed, reopened, not_planned)
|
||||
created_at:
|
||||
type: string
|
||||
description: When the issue was created (ISO 8601 format)
|
||||
updated_at:
|
||||
type: string
|
||||
description: When the issue was last updated (ISO 8601 format)
|
||||
closed_at:
|
||||
type: string
|
||||
description: When the issue was closed (ISO 8601 format), null if open
|
||||
user:
|
||||
type: object
|
||||
description: The user who created the issue
|
||||
properties:
|
||||
login:
|
||||
type: string
|
||||
description: GitHub username
|
||||
id:
|
||||
type: integer
|
||||
description: User ID
|
||||
avatar_url:
|
||||
type: string
|
||||
description: Avatar URL
|
||||
type:
|
||||
type: string
|
||||
description: User type (User, Bot, Organization)
|
||||
assignees:
|
||||
type: array
|
||||
description: Users assigned to this issue
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
login:
|
||||
type: string
|
||||
description: GitHub username
|
||||
id:
|
||||
type: integer
|
||||
description: User ID
|
||||
labels:
|
||||
type: array
|
||||
description: Labels associated with the issue
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
description: Label ID
|
||||
name:
|
||||
type: string
|
||||
description: The name of the label
|
||||
color:
|
||||
type: string
|
||||
description: 6-character hex code, without the leading #
|
||||
description:
|
||||
type: string
|
||||
description: Description of the label
|
||||
milestone:
|
||||
type: object
|
||||
description: Milestone associated with the issue
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
description: Milestone ID
|
||||
number:
|
||||
type: integer
|
||||
description: Milestone number
|
||||
title:
|
||||
type: string
|
||||
description: The title of the milestone
|
||||
description:
|
||||
type: string
|
||||
description: Description of the milestone
|
||||
state:
|
||||
type: string
|
||||
description: State of the milestone (open or closed)
|
||||
due_on:
|
||||
type: string
|
||||
description: When the milestone is due (ISO 8601 format)
|
||||
created_at:
|
||||
type: string
|
||||
description: When the milestone was created
|
||||
updated_at:
|
||||
type: string
|
||||
description: When the milestone was last updated
|
||||
closed_at:
|
||||
type: string
|
||||
description: When the milestone was closed
|
||||
locked:
|
||||
type: boolean
|
||||
description: Whether the issue is locked
|
||||
comments:
|
||||
type: integer
|
||||
description: Number of comments on the issue
|
||||
html_url:
|
||||
type: string
|
||||
description: URL to the issue on GitHub
|
||||
url:
|
||||
type: string
|
||||
description: API URL for the issue
|
||||
repository:
|
||||
type: object
|
||||
description: The repository where the issue was created
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
description: Repository ID
|
||||
name:
|
||||
type: string
|
||||
description: The name of the repository
|
||||
full_name:
|
||||
type: string
|
||||
description: The full name of the repository (owner/name)
|
||||
private:
|
||||
type: boolean
|
||||
description: Whether the repository is private
|
||||
owner:
|
||||
type: object
|
||||
description: Repository owner
|
||||
properties:
|
||||
login:
|
||||
type: string
|
||||
description: Owner username
|
||||
id:
|
||||
type: integer
|
||||
description: Owner ID
|
||||
type:
|
||||
type: string
|
||||
description: Owner type (User or Organization)
|
||||
html_url:
|
||||
type: string
|
||||
description: URL to the repository on GitHub
|
||||
description:
|
||||
type: string
|
||||
description: Repository description
|
||||
fork:
|
||||
type: boolean
|
||||
description: Whether the repository is a fork
|
||||
created_at:
|
||||
type: string
|
||||
description: When the repository was created
|
||||
updated_at:
|
||||
type: string
|
||||
description: When the repository was last updated
|
||||
pushed_at:
|
||||
type: string
|
||||
description: When the repository was last pushed to
|
||||
language:
|
||||
type: string
|
||||
description: Primary language of the repository
|
||||
default_branch:
|
||||
type: string
|
||||
description: Default branch of the repository
|
||||
sender:
|
||||
type: object
|
||||
description: The user who triggered the event
|
||||
properties:
|
||||
login:
|
||||
type: string
|
||||
description: GitHub username
|
||||
id:
|
||||
type: integer
|
||||
description: User ID
|
||||
avatar_url:
|
||||
type: string
|
||||
description: Avatar URL
|
||||
type:
|
||||
type: string
|
||||
description: User type (User, Bot, Organization)
|
||||
assignee:
|
||||
type: object
|
||||
description: The assignee added or removed (only for assigned/unassigned events)
|
||||
properties:
|
||||
login:
|
||||
type: string
|
||||
description: GitHub username
|
||||
id:
|
||||
type: integer
|
||||
description: User ID
|
||||
label:
|
||||
type: object
|
||||
description: The label added or removed (only for labeled/unlabeled events)
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
description: Label ID
|
||||
name:
|
||||
type: string
|
||||
description: The name of the label
|
||||
color:
|
||||
type: string
|
||||
description: 6-character hex code, without the leading #
|
||||
description:
|
||||
type: string
|
||||
description: Description of the label
|
||||
changes:
|
||||
type: object
|
||||
description: Changes made in an edit (only for edited events)
|
||||
properties:
|
||||
title:
|
||||
type: object
|
||||
properties:
|
||||
from:
|
||||
type: string
|
||||
description: Previous title
|
||||
body:
|
||||
type: object
|
||||
properties:
|
||||
from:
|
||||
type: string
|
||||
description: Previous body content
|
||||
installation:
|
||||
type: object
|
||||
description: GitHub App installation (when triggered by a GitHub App)
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
description: Installation ID
|
||||
|
||||
extra:
|
||||
python:
|
||||
source: triggers/issues.py
|
||||
@@ -0,0 +1,129 @@
|
||||
from collections.abc import Mapping
|
||||
import re
|
||||
from typing import Any
|
||||
|
||||
from dify_plugin.errors.trigger import TriggerIgnoreEventError
|
||||
from werkzeug import Request
|
||||
|
||||
from dify_plugin.entities.trigger import Event
|
||||
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 _check_title_pattern(self, issue: dict, pattern: str) -> None:
|
||||
"""Check if issue title matches the pattern"""
|
||||
if not pattern:
|
||||
return
|
||||
|
||||
title = issue.get("title", "")
|
||||
if not re.match(pattern, title):
|
||||
raise TriggerIgnoreEventError()
|
||||
|
||||
def _check_labels(self, issue: dict, labels_param: str) -> None:
|
||||
"""Check if issue has required labels"""
|
||||
if not labels_param:
|
||||
return
|
||||
|
||||
required_labels = [label.strip() for label in labels_param.split(",") if label.strip()]
|
||||
if not required_labels:
|
||||
return
|
||||
|
||||
issue_labels = [label.get("name") for label in issue.get("labels", [])]
|
||||
if not any(label in issue_labels for label in required_labels):
|
||||
raise TriggerIgnoreEventError()
|
||||
|
||||
def _check_assignee(self, issue: dict, assignee_param: str) -> None:
|
||||
"""Check if issue is assigned to allowed users"""
|
||||
if not assignee_param:
|
||||
return
|
||||
|
||||
allowed_assignees = [assignee.strip() for assignee in assignee_param.split(",") if assignee.strip()]
|
||||
if not allowed_assignees:
|
||||
return
|
||||
|
||||
issue_assignees = []
|
||||
|
||||
# Collect assignee usernames
|
||||
single_assignee = issue.get("assignee")
|
||||
if single_assignee and single_assignee.get("login"):
|
||||
issue_assignees.append(single_assignee["login"])
|
||||
|
||||
for assignee in issue.get("assignees", []):
|
||||
login = assignee.get("login")
|
||||
if login:
|
||||
issue_assignees.append(login)
|
||||
|
||||
if not any(assignee in issue_assignees for assignee in allowed_assignees):
|
||||
raise TriggerIgnoreEventError()
|
||||
|
||||
def _check_authors(self, issue: dict, authors_param: str) -> None:
|
||||
"""Check if issue author is in allowed list"""
|
||||
if not authors_param:
|
||||
return
|
||||
|
||||
allowed_authors = [author.strip() for author in authors_param.split(",") if author.strip()]
|
||||
if not allowed_authors:
|
||||
return
|
||||
|
||||
issue_author = issue.get("user", {}).get("login")
|
||||
if issue_author not in allowed_authors:
|
||||
raise TriggerIgnoreEventError()
|
||||
|
||||
def _check_milestone(self, issue: dict, milestone_param: str) -> None:
|
||||
"""Check if issue milestone matches allowed milestones"""
|
||||
if not milestone_param:
|
||||
return
|
||||
|
||||
allowed_milestones = [milestone.strip() for milestone in milestone_param.split(",") if milestone.strip()]
|
||||
if not allowed_milestones:
|
||||
return
|
||||
|
||||
milestone = issue.get("milestone")
|
||||
if not milestone:
|
||||
raise TriggerIgnoreEventError()
|
||||
|
||||
milestone_title = milestone.get("title")
|
||||
if not milestone_title or milestone_title not in allowed_milestones:
|
||||
raise TriggerIgnoreEventError()
|
||||
|
||||
def _check_body_contains(self, issue: dict, body_contains_param: str) -> None:
|
||||
"""Check if issue body contains required keywords"""
|
||||
if not body_contains_param:
|
||||
return
|
||||
|
||||
keywords = [keyword.strip().lower() for keyword in body_contains_param.split(",") if keyword.strip()]
|
||||
if not keywords:
|
||||
return
|
||||
|
||||
issue_body = (issue.get("body") or "").lower()
|
||||
if not any(keyword in issue_body for keyword in keywords):
|
||||
raise TriggerIgnoreEventError()
|
||||
|
||||
def _trigger(self, request: Request, parameters: Mapping[str, Any]) -> Event:
|
||||
"""
|
||||
Handle GitHub issue opened event trigger
|
||||
"""
|
||||
payload = request.get_json()
|
||||
if not payload:
|
||||
raise ValueError("No payload received")
|
||||
|
||||
issue = payload.get("issue")
|
||||
if not issue:
|
||||
raise ValueError("No issue data in payload")
|
||||
|
||||
# Apply all filters
|
||||
self._check_title_pattern(issue, parameters.get("title_pattern"))
|
||||
self._check_labels(issue, parameters.get("labels"))
|
||||
self._check_assignee(issue, parameters.get("assignee"))
|
||||
self._check_authors(issue, parameters.get("authors"))
|
||||
self._check_milestone(issue, parameters.get("milestone"))
|
||||
self._check_body_contains(issue, parameters.get("body_contains"))
|
||||
|
||||
return Event(variables={**payload})
|
||||
@@ -0,0 +1,604 @@
|
||||
identity:
|
||||
name: issue_opened
|
||||
author: langgenius
|
||||
label:
|
||||
en_US: Issue Opened
|
||||
zh_Hans: Issue 打开
|
||||
pt_BR: Issue Aberta
|
||||
|
||||
description:
|
||||
human:
|
||||
en_US: Triggers when a new issue is opened
|
||||
zh_Hans: 当新 issue 打开时触发
|
||||
pt_BR: Dispara quando uma nova issue é aberta
|
||||
llm:
|
||||
en_US: This trigger activates when a new issue is opened on a GitHub repository, providing information about the issue, repository, and user who opened it.
|
||||
zh_Hans: 当在 GitHub 仓库中打开新 issue 时,此触发器会被激活,提供有关 issue、仓库和打开它的用户的信息。
|
||||
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: labels
|
||||
label:
|
||||
en_US: Required Labels
|
||||
zh_Hans: 必需标签
|
||||
ja_JP: 必須ラベル
|
||||
type: string
|
||||
required: false
|
||||
description:
|
||||
en_US: "Only trigger if issue has these labels (e.g., bug, enhancement, urgent, comma-separated)"
|
||||
zh_Hans: "仅当议题有这些标签时触发(例如:bug, enhancement, urgent,逗号分隔)"
|
||||
ja_JP: "イシューがこれらのラベルを持つ場合のみトリガー(例: bug, enhancement, urgent,カンマ区切り)"
|
||||
|
||||
- name: assignee
|
||||
label:
|
||||
en_US: Assignee Filter
|
||||
zh_Hans: 受理人过滤
|
||||
ja_JP: 担当者フィルター
|
||||
type: string
|
||||
required: false
|
||||
description:
|
||||
en_US: "Only trigger if assigned to these users (e.g., username1, username2, comma-separated)"
|
||||
zh_Hans: "仅当分配给这些用户时触发(例如:username1, username2,逗号分隔)"
|
||||
ja_JP: "これらのユーザーに割り当てられた場合のみトリガー(例: username1, username2,カンマ区切り)"
|
||||
|
||||
- name: authors
|
||||
label:
|
||||
en_US: Authors
|
||||
zh_Hans: 作者
|
||||
ja_JP: 作成者
|
||||
type: string
|
||||
required: false
|
||||
description:
|
||||
en_US: "Only trigger for issues from these authors (e.g., user1, user2, comma-separated)"
|
||||
zh_Hans: "仅对这些作者的议题触发(例如:user1, user2,逗号分隔)"
|
||||
ja_JP: "これらの作成者のイシューのみトリガー(例: user1, user2,カンマ区切り)"
|
||||
|
||||
- name: milestone
|
||||
label:
|
||||
en_US: Milestone
|
||||
zh_Hans: 里程碑
|
||||
ja_JP: マイルストーン
|
||||
type: string
|
||||
required: false
|
||||
description:
|
||||
en_US: "Only trigger for issues with these milestones (e.g., v1.0, v2.0, comma-separated, default: all)"
|
||||
zh_Hans: "仅对具有这些里程碑的议题触发(例如:v1.0, v2.0,逗号分隔,默认所有)"
|
||||
ja_JP: "これらのマイルストーンのイシューのみトリガー(例: v1.0, v2.0,カンマ区切り,デフォルト: 全て)"
|
||||
|
||||
- name: title_pattern
|
||||
label:
|
||||
en_US: Title Pattern
|
||||
zh_Hans: 标题模式
|
||||
ja_JP: タイトルパターン
|
||||
type: string
|
||||
required: false
|
||||
description:
|
||||
en_US: "Only trigger if title matches this pattern (e.g., [BUG]*, [FEATURE]*, supports wildcards)"
|
||||
zh_Hans: "仅当标题匹配此模式时触发(例如:[BUG]*, [FEATURE]*,支持通配符)"
|
||||
ja_JP: "タイトルがこのパターンに一致する場合のみトリガー(例: [BUG]*, [FEATURE]*,ワイルドカード対応)"
|
||||
|
||||
- name: body_contains
|
||||
label:
|
||||
en_US: Body Contains
|
||||
zh_Hans: 正文包含
|
||||
ja_JP: 本文に含む
|
||||
type: string
|
||||
required: false
|
||||
description:
|
||||
en_US: "Only trigger if body contains these keywords (e.g., regression, critical, comma-separated)"
|
||||
zh_Hans: "仅当正文包含这些关键词时触发(例如:regression, critical,逗号分隔)"
|
||||
ja_JP: "本文にこれらのキーワードが含まれる場合のみトリガー(例: regression, critical,カンマ区切り)"
|
||||
|
||||
output_schema:
|
||||
type: object
|
||||
properties:
|
||||
issue:
|
||||
type: object
|
||||
description: The issue itself
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
description: Unique identifier of the issue
|
||||
node_id:
|
||||
type: string
|
||||
description: Node ID of the issue
|
||||
number:
|
||||
type: integer
|
||||
description: Issue number
|
||||
title:
|
||||
type: string
|
||||
description: Title of the issue
|
||||
body:
|
||||
type:
|
||||
- string
|
||||
|
||||
description: Contents of the issue
|
||||
state:
|
||||
type: string
|
||||
enum:
|
||||
- open
|
||||
- closed
|
||||
description: State of the issue
|
||||
state_reason:
|
||||
type:
|
||||
- string
|
||||
|
||||
locked:
|
||||
type: boolean
|
||||
description: Whether the issue is locked
|
||||
active_lock_reason:
|
||||
type:
|
||||
- string
|
||||
|
||||
enum:
|
||||
- resolved
|
||||
- off-topic
|
||||
- too heated
|
||||
- spam
|
||||
- null
|
||||
comments:
|
||||
type: integer
|
||||
description: Number of comments
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
updated_at:
|
||||
type: string
|
||||
format: date-time
|
||||
closed_at:
|
||||
type:
|
||||
- string
|
||||
|
||||
format: date-time
|
||||
author_association:
|
||||
type: string
|
||||
enum:
|
||||
- COLLABORATOR
|
||||
- CONTRIBUTOR
|
||||
- FIRST_TIMER
|
||||
- FIRST_TIME_CONTRIBUTOR
|
||||
- MANNEQUIN
|
||||
- MEMBER
|
||||
- NONE
|
||||
- OWNER
|
||||
description: How the author is associated with the repository
|
||||
|
||||
user:
|
||||
type:
|
||||
- object
|
||||
|
||||
description: User who created the issue
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
login:
|
||||
type: string
|
||||
node_id:
|
||||
type: string
|
||||
avatar_url:
|
||||
type: string
|
||||
format: uri
|
||||
html_url:
|
||||
type: string
|
||||
format: uri
|
||||
type:
|
||||
type: string
|
||||
enum:
|
||||
- Bot
|
||||
- User
|
||||
- Organization
|
||||
site_admin:
|
||||
type: boolean
|
||||
name:
|
||||
type: string
|
||||
email:
|
||||
type:
|
||||
- string
|
||||
|
||||
required:
|
||||
- id
|
||||
- login
|
||||
|
||||
assignee:
|
||||
type:
|
||||
- object
|
||||
|
||||
description: User assigned to the issue
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
login:
|
||||
type: string
|
||||
avatar_url:
|
||||
type: string
|
||||
format: uri
|
||||
html_url:
|
||||
type: string
|
||||
format: uri
|
||||
type:
|
||||
type: string
|
||||
enum:
|
||||
- Bot
|
||||
- User
|
||||
- Organization
|
||||
required:
|
||||
- id
|
||||
- login
|
||||
|
||||
assignees:
|
||||
type: array
|
||||
description: Users assigned to the issue
|
||||
items:
|
||||
type:
|
||||
- object
|
||||
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
login:
|
||||
type: string
|
||||
avatar_url:
|
||||
type: string
|
||||
format: uri
|
||||
html_url:
|
||||
type: string
|
||||
format: uri
|
||||
type:
|
||||
type: string
|
||||
enum:
|
||||
- Bot
|
||||
- User
|
||||
- Organization
|
||||
required:
|
||||
- id
|
||||
- login
|
||||
|
||||
labels:
|
||||
type: array
|
||||
description: Labels on the issue
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
node_id:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
description: The name of the label
|
||||
color:
|
||||
type: string
|
||||
description: 6-character hex code, without the leading #
|
||||
default:
|
||||
type: boolean
|
||||
description:
|
||||
type:
|
||||
- string
|
||||
|
||||
url:
|
||||
type: string
|
||||
format: uri
|
||||
required:
|
||||
- id
|
||||
- name
|
||||
- color
|
||||
|
||||
milestone:
|
||||
type:
|
||||
- object
|
||||
|
||||
description: A collection of related issues and pull requests
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
node_id:
|
||||
type: string
|
||||
number:
|
||||
type: integer
|
||||
description: The number of the milestone
|
||||
title:
|
||||
type: string
|
||||
description: The title of the milestone
|
||||
description:
|
||||
type:
|
||||
- string
|
||||
|
||||
state:
|
||||
type: string
|
||||
enum:
|
||||
- open
|
||||
- closed
|
||||
description: The state of the milestone
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
updated_at:
|
||||
type: string
|
||||
format: date-time
|
||||
due_on:
|
||||
type:
|
||||
- string
|
||||
|
||||
format: date-time
|
||||
closed_at:
|
||||
type:
|
||||
- string
|
||||
|
||||
format: date-time
|
||||
open_issues:
|
||||
type: integer
|
||||
closed_issues:
|
||||
type: integer
|
||||
html_url:
|
||||
type: string
|
||||
format: uri
|
||||
required:
|
||||
- id
|
||||
- number
|
||||
- title
|
||||
- state
|
||||
|
||||
html_url:
|
||||
type: string
|
||||
format: uri
|
||||
description: URL to view the issue on GitHub
|
||||
url:
|
||||
type: string
|
||||
format: uri
|
||||
description: API URL for the issue
|
||||
repository_url:
|
||||
type: string
|
||||
format: uri
|
||||
labels_url:
|
||||
type: string
|
||||
format: uri-template
|
||||
comments_url:
|
||||
type: string
|
||||
format: uri
|
||||
events_url:
|
||||
type: string
|
||||
format: uri
|
||||
timeline_url:
|
||||
type: string
|
||||
format: uri
|
||||
|
||||
reactions:
|
||||
type: object
|
||||
properties:
|
||||
url:
|
||||
type: string
|
||||
format: uri
|
||||
total_count:
|
||||
type: integer
|
||||
"+1":
|
||||
type: integer
|
||||
"-1":
|
||||
type: integer
|
||||
laugh:
|
||||
type: integer
|
||||
confused:
|
||||
type: integer
|
||||
heart:
|
||||
type: integer
|
||||
hooray:
|
||||
type: integer
|
||||
eyes:
|
||||
type: integer
|
||||
rocket:
|
||||
type: integer
|
||||
required:
|
||||
- total_count
|
||||
required:
|
||||
- id
|
||||
- node_id
|
||||
- number
|
||||
- title
|
||||
- state
|
||||
- created_at
|
||||
- updated_at
|
||||
- user
|
||||
- html_url
|
||||
- url
|
||||
- repository_url
|
||||
- labels_url
|
||||
- comments_url
|
||||
- events_url
|
||||
- comments
|
||||
- locked
|
||||
- author_association
|
||||
- reactions
|
||||
|
||||
repository:
|
||||
type: object
|
||||
description: The repository where the issue was opened
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
description: Unique identifier of the repository
|
||||
node_id:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
description: The name of the repository
|
||||
full_name:
|
||||
type: string
|
||||
description: Full name including owner
|
||||
private:
|
||||
type: boolean
|
||||
description: Whether the repository is private
|
||||
owner:
|
||||
type:
|
||||
- object
|
||||
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
login:
|
||||
type: string
|
||||
node_id:
|
||||
type: string
|
||||
avatar_url:
|
||||
type: string
|
||||
format: uri
|
||||
html_url:
|
||||
type: string
|
||||
format: uri
|
||||
type:
|
||||
type: string
|
||||
enum:
|
||||
- Bot
|
||||
- User
|
||||
- Organization
|
||||
site_admin:
|
||||
type: boolean
|
||||
required:
|
||||
- id
|
||||
- login
|
||||
html_url:
|
||||
type: string
|
||||
format: uri
|
||||
description:
|
||||
type:
|
||||
- string
|
||||
|
||||
fork:
|
||||
type: boolean
|
||||
url:
|
||||
type: string
|
||||
format: uri
|
||||
created_at:
|
||||
oneOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
format: date-time
|
||||
updated_at:
|
||||
type: string
|
||||
format: date-time
|
||||
pushed_at:
|
||||
oneOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
format: date-time
|
||||
homepage:
|
||||
type:
|
||||
- string
|
||||
|
||||
size:
|
||||
type: integer
|
||||
stargazers_count:
|
||||
type: integer
|
||||
watchers_count:
|
||||
type: integer
|
||||
language:
|
||||
type:
|
||||
- string
|
||||
|
||||
forks_count:
|
||||
type: integer
|
||||
open_issues_count:
|
||||
type: integer
|
||||
default_branch:
|
||||
type: string
|
||||
description: The default branch of the repository
|
||||
topics:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
visibility:
|
||||
type: string
|
||||
enum:
|
||||
- public
|
||||
- private
|
||||
- internal
|
||||
required:
|
||||
- id
|
||||
- node_id
|
||||
- name
|
||||
- full_name
|
||||
- private
|
||||
- owner
|
||||
- html_url
|
||||
- url
|
||||
- created_at
|
||||
- updated_at
|
||||
- fork
|
||||
- default_branch
|
||||
- visibility
|
||||
|
||||
sender:
|
||||
type: object
|
||||
description: The user who triggered the event
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
login:
|
||||
type: string
|
||||
node_id:
|
||||
type: string
|
||||
avatar_url:
|
||||
type: string
|
||||
format: uri
|
||||
html_url:
|
||||
type: string
|
||||
format: uri
|
||||
type:
|
||||
type: string
|
||||
enum:
|
||||
- Bot
|
||||
- User
|
||||
- Organization
|
||||
site_admin:
|
||||
type: boolean
|
||||
required:
|
||||
- id
|
||||
- login
|
||||
- type
|
||||
|
||||
organization:
|
||||
type: object
|
||||
description: The organization that owns the repository (if applicable)
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
login:
|
||||
type: string
|
||||
node_id:
|
||||
type: string
|
||||
url:
|
||||
type: string
|
||||
format: uri
|
||||
avatar_url:
|
||||
type: string
|
||||
format: uri
|
||||
description:
|
||||
type:
|
||||
- string
|
||||
required:
|
||||
- id
|
||||
- login
|
||||
- node_id
|
||||
- url
|
||||
|
||||
installation:
|
||||
type: object
|
||||
description: The GitHub App installation (if applicable)
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
node_id:
|
||||
type: string
|
||||
required:
|
||||
- id
|
||||
- node_id
|
||||
|
||||
required:
|
||||
- issue
|
||||
- repository
|
||||
- sender
|
||||
|
||||
extra:
|
||||
python:
|
||||
source: triggers/issues/issue_opened.py
|
||||
Reference in New Issue
Block a user