362 lines
15 KiB
Python
362 lines
15 KiB
Python
|
|
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)
|