Files
yakpanel-core/mod/base/msg/manager.py
2026-04-07 02:04:22 +05:30

362 lines
15 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import time
import traceback
from mod.base.push_mod import SenderConfig
from .weixin_msg import WeiXinMsg
from .mail_msg import MailMsg
from .tg_msg import TgMsg
from .web_hook_msg import WebHookMsg
from .feishu_msg import FeiShuMsg
from .dingding_msg import DingDingMsg
from .sms_msg import SMSMsg
# from .wx_account_msg import WeChatAccountMsg
import json
from mod.base import json_response
from .util import write_file, read_file
import sys,os
sys.path.insert(0, "/www/server/panel/class/")
import public
# 短信会自动添加到 sender 库中的第一个 且通过官方接口更新
# 微信公众号信息通过官网接口更新, 不写入数据库,需要时由文件中读取并序列化
# 其他告警通道本质都类似于web hook 在确认完数据信息无误后,都可以自行添加或启用
class SenderManager:
def __init__(self):
self.custom_parameter_filename = "/www/server/panel/data/mod_push_data/custom_parameter.pl"
self.init_default_sender()
def set_sender_conf(self, get):
args = json.loads(get.sender_data.strip())
try:
sender_id = None
try:
if hasattr(get, "sender_id"):
sender_id = get.sender_id.strip()
if not sender_id:
sender_id = None
sender_type = get.sender_type.strip()
args = json.loads(get.sender_data.strip())
except (json.JSONDecoder, AttributeError, TypeError):
return json_response(status=False, msg=public.lang('The parameter is incorrect'))
sender_config = SenderConfig()
if sender_id is not None:
tmp = sender_config.get_by_id(sender_id)
if tmp is None:
sender_id = None
if sender_type == "weixin":
data = WeiXinMsg.check_args(args)
if isinstance(data, str):
return json_response(status=False, data=data, msg=public.lang('Test send failed'))
elif sender_type == "mail":
_, data = MailMsg.check_args(args)
if isinstance(data, str):
return json_response(status=False, data=data, msg=public.lang('Test send failed'))
elif sender_type == "tg":
_, data = TgMsg.check_args(args)
if isinstance(data, str):
return json_response(status=False, data=data, msg=data)
elif sender_type == "webhook":
custom_parameter = args.get("custom_parameter", {})
if custom_parameter:
try:
public.writeFile(self.custom_parameter_filename, json.dumps(custom_parameter))
except:
pass
data = WebHookMsg.check_args(args)
if isinstance(data, str):
return json_response(status=False, data=data, msg=public.lang('Test send failed'))
# 从文件读取并删除文件
try:
if os.path.exists(self.custom_parameter_filename):
custom_parameter = json.loads(public.readFile(self.custom_parameter_filename))
data['custom_parameter'] = custom_parameter
os.remove(self.custom_parameter_filename)
except:
pass
elif sender_type == "feishu":
data = FeiShuMsg.check_args(args)
if isinstance(data, str):
return json_response(status=False, data=data, msg=public.lang('Test send failed'))
elif sender_type == "dingding":
data = DingDingMsg.check_args(args)
if isinstance(data, str):
return json_response(status=False, data=data, msg=public.lang('Test send failed'))
else:
return json_response(status=False, msg=public.lang('A type that is not supported by the current interface'))
# Check if the sender configuration already exists
existing_sender = any(
conf for conf in sender_config.config
if conf['sender_type'] == sender_type and 'title' in conf['data'] and conf['data']['title'] == data['title'] and conf['id'] != sender_id
)
# for conf in sender_config.config:
# if conf['sender_type'] == sender_type and 'title' in conf['data'] and conf['data']['title'] == data[
# 'title'] and conf['id'] != sender_id:
# public.print_log('000 -{}'.format(conf['sender_type']))
# public.print_log('000 -{}'.format(sender_type))
#
# public.print_log('111 conf -{}'.format(conf['sender_type']))
# public.print_log('111 -{}'.format(sender_type))
#
# public.print_log('222 conf -{}'.format(conf['data']['title']))
# public.print_log('222 data -{}'.format(data['title']))
#
# public.print_log('333 conf -{}'.format(conf['id']))
# public.print_log('333 -{}'.format(sender_id))
if existing_sender:
return json_response(status=False, msg=public.lang('The same send configuration already exists and cannot be added repeatedly'))
now_sender_id = None
if not sender_id:
now_sender_id = sender_config.nwe_id()
sender_config.config.append(
{
"id": now_sender_id,
"sender_type": sender_type,
"data": data,
"used": True,
})
else:
now_sender_id = sender_id
tmp = sender_config.get_by_id(sender_id)
tmp["data"].update(data)
# type_senders = [conf for conf in sender_config.config if conf['sender_type'] == sender_type]
# if len(type_senders) == 1:
# for conf in sender_config.config:
# conf["original"] = (conf['id'] == now_sender_id)
sender_config.save_config()
if sender_type == "webhook":
self.set_default_for_compatible(sender_config.get_by_id(now_sender_id))
return json_response(status=True, msg=public.lang('Saved successfully'))
except:
public.print_log('Error:{}'.format(str(public.get_error_info())))
@staticmethod
def change_sendr_used(get):
try:
sender_id = get.sender_id.strip()
except (AttributeError, TypeError):
return json_response(status=False, msg=public.lang('The parameter is incorrect'))
sender_config = SenderConfig()
tmp = sender_config.get_by_id(sender_id)
if tmp is None:
return json_response(status=False, msg=public.lang('Corresponding sender not found'))
tmp["used"] = not tmp["used"]
sender_config.save_config()
return json_response(status=True, msg=public.lang('Saved successfully'))
@staticmethod
def remove_sender(get):
try:
sender_id = get.sender_id.strip()
except (AttributeError, TypeError):
return json_response(status=False, msg=public.lang('The parameter is incorrect'))
sender_config = SenderConfig()
tmp = sender_config.get_by_id(sender_id)
if tmp is None:
return json_response(status=False, msg=public.lang('Corresponding sender not found'))
sender_config.config.remove(tmp)
sender_config.save_config()
return json_response(status=True, msg=public.lang('Successfully delete'))
@staticmethod
def get_sender_list(get):
# 微信, 飞书, 钉钉, web-hook 邮箱
refresh = False
try:
if hasattr(get, 'refresh'):
refresh = get.refresh.strip()
if refresh in ("1", "true"):
refresh = True
except (AttributeError, TypeError):
return json_response(status=False, msg=public.lang('The parameter is incorrect'))
res = []
# WeChatAccountMsg.refresh_config(force=refresh)
simple = ("weixin", "mail", "webhook", "feishu", "dingding", "tg")
for conf in SenderConfig().config:
if conf["sender_type"] in simple or conf["sender_type"] == "wx_account":
res.append(conf)
# 去掉短信设置
# elif conf["sender_type"] == "sms":
# conf["data"] = SMSMsg(conf).refresh_config(force=refresh)
# res.append(conf)
res.sort(key=lambda x: x["sender_type"])
return json_response(status=True, data=res)
@staticmethod
def test_send_msg(get):
try:
sender_id = get.sender_id.strip()
except (json.JSONDecoder, AttributeError, TypeError):
return json_response(status=False, msg=public.lang('The parameter is incorrect'))
sender_config = SenderConfig()
tmp = sender_config.get_by_id(sender_id)
if tmp is None:
return json_response(status=False, msg=public.lang('Corresponding sender not found'))
sender_type = tmp["sender_type"]
if sender_type == "weixin":
sender_obj = WeiXinMsg(tmp)
elif sender_type == "mail":
sender_obj = MailMsg(tmp)
elif sender_type == "webhook":
sender_obj = WebHookMsg(tmp)
elif sender_type == "feishu":
sender_obj = FeiShuMsg(tmp)
elif sender_type == "dingding":
sender_obj = DingDingMsg(tmp)
elif sender_type == "tg":
sender_obj = TgMsg(tmp)
# elif sender_type == "wx_account":
# sender_obj = WeChatAccountMsg(tmp)
else:
return json_response(status=False, msg=public.lang('A type that is not supported by the current interface'))
res = sender_obj.test_send_msg()
if isinstance(res, str):
return json_response(status=False, data=res, msg=public.lang('Test send failed'))
return json_response(status=True, msg=public.lang('The sending was successful'))
@staticmethod
def set_default_for_compatible(sender_data: dict):
if sender_data["sender_type"] in ("sms", "wx_account"):
return
panel_data = "/www/server/panel/data"
if sender_data["sender_type"] == "weixin":
weixin_file = "{}/weixin.json".format(panel_data)
write_file(weixin_file, json.dumps({
"state": 1,
"weixin_url": sender_data["data"]["url"],
"title": sender_data["data"]["title"],
"list": {
"default": {
"data": sender_data["data"]["url"],
"title": sender_data["data"]["title"],
"status": 1,
"addtime": int(time.time())
}
}
}))
elif sender_data["sender_type"] == "mail":
stmp_mail_file = "{}/stmp_mail.json".format(panel_data)
mail_list_file = "{}/mail_list.json".format(panel_data)
write_file(stmp_mail_file, json.dumps(sender_data["data"]["send"]))
write_file(mail_list_file, json.dumps(sender_data["data"]["receive"]))
elif sender_data["sender_type"] == "feishu":
feishu_file = "{}/feishu.json".format(panel_data)
write_file(feishu_file, json.dumps({
"feishu_url": sender_data["data"]["url"],
"title": sender_data["data"]["title"],
"isAtAll": True,
"user": []
}))
elif sender_data["sender_type"] == "dingding":
dingding_file = "{}/dingding.json".format(panel_data)
write_file(dingding_file, json.dumps({
"dingding_url": sender_data["data"]["url"],
"title": sender_data["data"]["title"],
"isAtAll": True,
"user": []
}))
elif sender_data["sender_type"] == "tg":
tg_file = "{}/tg_bot.json".format(panel_data)
write_file(tg_file, json.dumps({
"my_id": sender_data["data"]["my_id"],
"bot_token": sender_data["data"]["bot_token"],
"title": sender_data["data"]["title"]
}))
elif sender_data["sender_type"] == "webhook":
webhook_file = "{}/hooks_msg.json".format(panel_data)
try:
webhook_data = json.loads(read_file(webhook_file))
except:
webhook_data =[]
target_idx = -1
for idx, i in enumerate(webhook_data):
if i["name"] == sender_data["data"]["title"]:
target_idx = idx
break
else:
sender_data["data"]["name"] = sender_data["data"]["title"]
webhook_data.append(sender_data["data"])
if target_idx != -1:
sender_data["data"]["name"] = sender_data["data"]["title"]
webhook_data[target_idx] = sender_data["data"]
write_file(webhook_file, json.dumps(webhook_data))
def init_default_sender(self):
import os,sys
sys.path.insert(0, "/www/server/panel/mod/project/push")
import msgconfMod
sender_config = SenderConfig()
sender_types = set(conf['sender_type'] for conf in sender_config.config)
all_types = {"feishu", "dingding", "weixin", "mail", "webhook"} # 所有可能的类型
for sender_type in sender_types:
type_senders = [conf for conf in sender_config.config if conf['sender_type'] == sender_type]
# 检查是否已有默认通道
has_default = any(conf.get('original', False) for conf in type_senders)
if has_default:
continue
if len(type_senders) == 1:
# 只有一个通道,设置为默认通道
for conf in type_senders:
get = public.dict_obj()
get['sender_id'] = conf['id']
get['sender_type'] = conf['sender_type']
self.set_default_sender(get)
else:
# 有多个通道,根据添加时间设置默认通道
sorted_senders = sorted(type_senders, key=lambda x: x['data'].get('create_time', ''))
if sorted_senders:
get = public.dict_obj()
get['sender_id'] = sorted_senders[0]['id']
get['sender_type'] = sorted_senders[0]['sender_type']
self.set_default_sender(get)
# 检查没有通道的类型,并删除对应文件
missing_types = all_types - sender_types
for missing_type in missing_types:
file_path = f"/www/server/panel/data/{missing_type}.json"
if os.path.exists(file_path):
os.remove(file_path)