From 031bf6d469a51899e7bf5aea2aa1e5d47620e517 Mon Sep 17 00:00:00 2001 From: liuwei Date: Tue, 18 Mar 2025 09:28:28 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=B6=88=E6=81=AF=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E5=8C=85=EF=BC=8C=E9=98=B2=E6=AD=A2=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E9=87=8D=E5=A4=8D=EF=BC=8C=E6=96=B9=E4=BE=BF@=20=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- message_sign/main.py | 18 ++++++----- message_util.py | 74 ++++++++++++++++++++++++++++++++++++++++++++ robot.py | 5 ++- 3 files changed, 88 insertions(+), 9 deletions(-) create mode 100644 message_util.py diff --git a/message_sign/main.py b/message_sign/main.py index 6f57bad..e72a093 100644 --- a/message_sign/main.py +++ b/message_sign/main.py @@ -7,6 +7,8 @@ import redis from typing import Optional, Tuple from wcferry import Wcf, WxMsg + +from message_util import MessageUtil from robot_cmd.robot_command import GroupBotManager, Feature, PermissionStatus # 创建表的SQL语句 @@ -28,7 +30,8 @@ CREATE TABLE IF NOT EXISTS t_sign_record ( class SignInSystem: def __init__(self, wcf: Wcf, gbm: GroupBotManager, all_contacts: dict, - db_pool: mysql.connector.pooling.MySQLConnectionPool, redis_pool: redis.ConnectionPool): + db_pool: mysql.connector.pooling.MySQLConnectionPool, redis_pool: redis.ConnectionPool, + message_util: MessageUtil): # 读取配置文件 with open('message_sign/config.toml', 'rb') as f: self.config = tomllib.load(f)['SignIn'] @@ -40,6 +43,7 @@ class SignInSystem: self.wcf = wcf self.gbm = gbm + self.message_util = message_util self.all_contacts = all_contacts self.db_pool = db_pool self.redis_pool = redis_pool @@ -184,9 +188,8 @@ class SignInSystem: # 如果 sign_stat 已经大于或等于今天的零点,则认为用户已经签到过了 if sign_stat >= today_start: - ats = "" - ats += f" @{self.wcf.get_alias_in_chatroom(message.sender, message.roomid)}" - self.wcf.send_text(f"{ats} 您今天已经签到过了!当前积分:{user_record['points']}", message.roomid, message.sender) + self.message_util.send_text_msg(f"您今天已经签到过了!当前积分:{user_record['points']}", message.roomid, + message.sender) return streak = 0 @@ -251,16 +254,15 @@ class SignInSystem: # output += f"你连续签到了 {streak} 天!" # if streak > 1 and not streak_broken: # output += "[爱心]" - output = f"签到成功,加[{points_to_add}]分,第[{today_signin_rank}]个!" if streak_broken and old_streak > 0: # 只有在真的断签且之前有签到记录时才显示 output += f"断开了 {old_streak} 天连签!" elif streak > 1: output += f"连签 {streak} 天!" - ats = "" - ats += f" @{self.wcf.get_alias_in_chatroom(message.sender, message.roomid)}" - self.wcf.send_text(f"{ats} {output}", message.roomid, message.sender) + + self.message_util.send_text_msg(output, message.roomid, + message.sender) def __del__(self): """连接池由外部管理,不需要手动关闭""" diff --git a/message_util.py b/message_util.py new file mode 100644 index 0000000..eb50221 --- /dev/null +++ b/message_util.py @@ -0,0 +1,74 @@ +# -*- coding: utf-8 -*- +import logging +import random +import time +from typing import Optional + +from wcferry import Wcf + + +class MessageUtil: + """ + 消息发送工具类,封装了发送文本和文件的方法 + """ + + def __init__(self, wcf: Wcf, contacts: Optional[dict] = None) -> None: + """ + 初始化消息工具类 + + :param wcf: WCFerry实例 + :param contacts: 联系人字典,格式为 {"wxid": "NickName"} + """ + self.wcf = wcf + self.contacts = contacts or {} + self.LOG = logging.getLogger("MessageUtil") + + def send_text_msg(self, msg: str, receiver: str, at_list: str = "") -> None: + """ + 发送文本消息 + + :param msg: 消息字符串 + :param receiver: 接收人wxid或者群id + :param at_list: 要@的wxid, @所有人的wxid为:notify@all + """ + # 风控处理,随机延迟发送,解决群消息高频发送导致的微信风险 + time.sleep(random.uniform(0.3, 1.0)) + + ats = "" + if at_list: + if at_list == "notify@all": # @所有人 + ats = " @所有人" + else: + wxids = at_list.split(",") + for wxid in wxids: + # 根据 wxid 查找群昵称 + ats += f" @{self.wcf.get_alias_in_chatroom(wxid, receiver)}" + + # {msg}{ats} 表示要发送的消息内容后面紧跟@,例如 北京天气情况为:xxx @张三 + if ats == "": + self.LOG.info(f"To {receiver}: {msg}") + self.wcf.send_text(f"{msg}", receiver, at_list) + else: + self.LOG.info(f"To {receiver}: {ats}\r{msg}") + self.wcf.send_text(f"{ats}\n\n{msg}", receiver, at_list) + + def send_file(self, file_path: str, receiver: str) -> None: + """ + 发送文件消息 + + :param file_path: 文件路径 + :param receiver: 接收人wxid或者群id + """ + # 风控处理,随机延迟发送,解决群消息高频发送导致的微信风险 + time.sleep(random.uniform(0.5, 1.5)) + + self.LOG.info(f"Sending file to {receiver}: {file_path}") + self.wcf.send_file(file_path, receiver) + + def update_contacts(self, contacts: dict) -> None: + """ + 更新联系人字典 + + :param contacts: 联系人字典,格式为 {"wxid": "NickName"} + """ + self.contacts.update(contacts) \ No newline at end of file diff --git a/robot.py b/robot.py index d7ddd2a..b0e67d7 100644 --- a/robot.py +++ b/robot.py @@ -58,6 +58,7 @@ from xiuren.meitu_dl import meitu_dowload_pic, meitu_dowload_pub_pic, meitu_dowl from xiuren.random_pic import get_xiuren_pic, get_xiuren_heisi_pic from xiuren.xiuren_pdf import generate_pdf_from_images +from message_util import MessageUtil class Robot(Job): """个性化自己的机器人 @@ -78,6 +79,8 @@ class Robot(Job): self.redis_pool = redis.ConnectionPool(**self.config.redis) self.LOG.info(f"REDIS连接池加载完成: {self.config.redis}") + # 初始化消息工具类 + self.message_util = MessageUtil(wcf, self.allContacts) self.groups = {} # 存储按group_id分组的消息列表,每个group_id最多保留10条消息 GroupBotManager.load_local_cache() # 消息存档模块初始化,自动完成入库动作 @@ -89,7 +92,7 @@ class Robot(Job): # 点歌模块加载 self.music = BotMusic(wcf, self.gbm) # 签到模块加载 - self.signin = SignInSystem(wcf, self.gbm, self.allContacts, self.db_pool, self.redis_pool) + self.signin = SignInSystem(wcf, self.gbm, self.allContacts, self.db_pool, self.redis_pool,self.message_util ) # 积分赠送功能加载 self.trade = PointTrade(wcf, self.gbm, self.db_pool) # 获取视频模块