mirror of
https://github.com/aaPanel/aaPanel.git
synced 2026-08-21 07:02:26 +02:00
1. Added Mail Marketing Automation trigger tasks 2. Added Mail Marketing Groups Import, Export, Merge 3. Added Mail Marketing Subscribers to support paste import 4. Added Mail Marketing Template Import Export Duplicate 5. Added Mail server add timed automatic reply 6. Added HTTPS Protection function for Website (disables automatic HTTP to HTTPS redirection when enabled) 7. Optimize Website Interface Button Integration 8. Optimize the response speed of WP Toolkit interface
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) |