feat(plugin): 为插件添加 webhook 支持

This commit is contained in:
xiaoQQya 2025-04-04 17:49:42 +08:00
parent 7760e30c49
commit e7f938769b
3 changed files with 73 additions and 0 deletions

View File

@ -282,6 +282,43 @@ def delete_file():
return jsonify(response)
def get_hook_actions(plugins):
hook_actions = {}
for _, plugin in plugins.items():
for name in dir(plugin):
method = getattr(plugin, name)
if callable(method) and hasattr(method, "__hook_action_name__"):
hook_actions[getattr(method, "__hook_action_name__")] = method
return hook_actions
@app.route("/webhook", methods=["GET", "POST"])
def webhook():
# 验证用户名和密码
data = read_json()
username = data["webui"]["username"]
password = data["webui"]["password"]
if (username != request.args.get("username")) or (
password != request.args.get("password")
):
logging.info(f">>> 用户 {username} webhook 认证失败")
return jsonify({"error": "认证失败"})
try:
action = request.args.get("action")
plugins, _, _ = Config.load_plugins(data.get("plugins", {}))
hook_actions = get_hook_actions(plugins)
if action in hook_actions:
cookies = Config.get_cookies(data["cookie"])
account = Quark(cookies[0], 0) if cookies else None
args = request.args
body = request.get_json() if request.mimetype == "application/json" else {}
hook_actions[action](account=account, **args, **body)
except Exception as e:
logging.error(f">>> webhook 处理报错:{e}")
return Response(status=200)
# 定时任务执行的函数
def run_python(args):
logging.info(f">>> 定时运行任务")

28
decorators.py Normal file
View File

@ -0,0 +1,28 @@
#!/usr/bin/python3
# -*- encoding: utf-8 -*-
"""
@File : decorators.py
@Desc : 定义装饰器
@Version : v1.0
@Time : 2025/04/04
@Author : xiaoQQya
@Contact : xiaoQQya@126.com
"""
import functools
def hook_action(name):
"""回调动作装饰器
Args:
name (str): 动作名称
"""
def decorator(func):
func.__hook_action_name__ = name
@functools.wraps(func)
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
return decorator

View File

@ -29,6 +29,14 @@
* `task` 是一个字典,包含任务信息。如果需要修改任务参数,返回修改后的 `task` 字典;
* 无修改则不返回或返回 `None`
## 插件回调
插件支持配置 webhook 回调事件,使用方式如下:
1. 使用 `@hook_action("xxx_hook")` 装饰器修饰需要接收回调事件的方法,其中装饰器参数为回调事件类型,建议使用 `插件名称_事件类型_hook` 命名,避免不同插件之间类型重复;
2. 在外部通过 `http://host:port/webhook?username=xxx&password=xxx&action=xxx_hook` 触发回调事件,支持 GET 与 POST 方法POST 方法只支持 `application/json` 类型参数;
## 插件示例
参考 [emby.py](emby.py)