feature:1.点歌功能,2.签到功能

This commit is contained in:
liuwei
2025-03-05 09:01:08 +08:00
parent 5ed4c94094
commit 9937115ad3
14 changed files with 524 additions and 200 deletions

View File

@@ -47,37 +47,6 @@ class News(object):
return f"{fmt_time} {self.week[weekday_news]}\n{fmt_news}" return f"{fmt_time} {self.week[weekday_news]}\n{fmt_news}"
def get_36kr_news(self):
url = "https://orz.ai/dailynews/?platform=36kr"
# 获取当前日期和英文星期名
now = datetime.now()
current_date = now.strftime("%Y年%m月%d")
english_weekdays = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
chinese_weekdays = ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"]
# 将英文星期名映射为中文
current_weekday_index = now.weekday() # 获取当前是星期几0代表星期一6代表星期日
current_weekday_chinese = chinese_weekdays[current_weekday_index]
# 初始化一个空字符串来存储结果
output = f"当前日期:{current_date} {current_weekday_chinese}\n\n"
response = requests.get(url)
if response.status_code == 200:
post = response.json()
str = post['data']
# 遍历列表并格式化每个字典的title, url然后添加到output字符串中
for index, article in enumerate(str, start=1):
title = article['title']
url = article['url']
# 使用f-string格式化字符串并添加到output中
output += f"{index}. 标题: {title}\n URL: {url}\n"
# 输出最终的字符串(这里只是为了展示,实际上你可以根据需要处理这个字符串)
return output
def get_baidu_news(self): def get_baidu_news(self):
url = "https://top.baidu.com/api/board?platform=wise&tab=realtime" url = "https://top.baidu.com/api/board?platform=wise&tab=realtime"
# 获取当前日期和英文星期名 # 获取当前日期和英文星期名

View File

@@ -18,16 +18,16 @@ class ReportReminder:
today = datetime.datetime.now().date() today = datetime.datetime.now().date()
# 如果是非工作日 # 如果是非工作日
if not is_workday(today): if not is_workday(today):
robot.sendTextMsg("休息日快乐", receiver) robot.send_text_msg("休息日快乐", receiver)
# 如果是工作日 # 如果是工作日
if is_workday(today): if is_workday(today):
robot.sendTextMsg("该发日报啦", receiver) robot.send_text_msg("该发日报啦", receiver)
# 如果是本周最后一个工作日 # 如果是本周最后一个工作日
if ReportReminder.last_work_day_of_week(today) == today: if ReportReminder.last_work_day_of_week(today) == today:
robot.sendTextMsg("该发周报啦", receiver) robot.send_text_msg("该发周报啦", receiver)
# 如果本日是本月最后一整周的最后一个工作日: # 如果本日是本月最后一整周的最后一个工作日:
if ReportReminder.last_work_friday_of_month(today) == today: if ReportReminder.last_work_friday_of_month(today) == today:
robot.sendTextMsg("该发月报啦", receiver) robot.send_text_msg("该发月报啦", receiver)
# 计算本月最后一个周的最后一个工作日 # 计算本月最后一个周的最后一个工作日
@staticmethod @staticmethod

View File

@@ -120,3 +120,24 @@ doubao:
- 问题评价:分析问题的提出角度,如(财经、彩票、房产、股票、家居、教育、科技、社会、时尚、时政、体育、星座、游戏、娱乐)等 - 问题评价:分析问题的提出角度,如(财经、彩票、房产、股票、家居、教育、科技、社会、时尚、时政、体育、星座、游戏、娱乐)等
- 总结经过300个字以内的优化返回返回内容请进行一定程度的结构化方便快速阅读' # 根据需要对角色进行设定 - 总结经过300个字以内的优化返回返回内容请进行一定程度的结构化方便快速阅读' # 根据需要对角色进行设定
# config.yaml
db_config:
pool_name: "wechat_boot_pool"
pool_size: 10
host: "192.168.2.32"
user: "root"
password: "lw123456"
database: "message_archive"
charset: "utf8mb4"
use_unicode: true
get_warnings: true
pool_reset_session: true
redis_config:
host: "192.168.2.32"
port: 6379
db: 0
decode_responses: true

View File

@@ -40,3 +40,7 @@ class Config(object):
self.CLAUDE = yconfig.get("claude", {}) self.CLAUDE = yconfig.get("claude", {})
self.DEEPSEEK = yconfig.get("deepseek", {}) self.DEEPSEEK = yconfig.get("deepseek", {})
self.DOUBAO = yconfig.get("doubao", {}) self.DOUBAO = yconfig.get("doubao", {})
# DB config
self.mariadb = yconfig.get("db_config", {})
self.redis = yconfig.get("redis_config", {})

View File

@@ -4,15 +4,18 @@ import xml.etree.ElementTree as ET
from wcferry import Wcf from wcferry import Wcf
class GroupMemberChange: class GroupMemberChange:
def __init__(self, wcf: Wcf): def __init__(self, wcf: Wcf, redis_pool: redis.ConnectionPool):
self.wcf = wcf # 假设 wcf 对象在此类中初始化 self.wcf = wcf # 假设 wcf 对象在此类中初始化
self.r = redis.Redis(host='192.168.2.32', port=6379, db=0, decode_responses=True) self.redis_pool = redis_pool
# 初始化本地缓存字典,使用 group_id 作为键 # 初始化本地缓存字典,使用 group_id 作为键
self.local_membercounts = {} self.local_membercounts = {}
self.local_members = {} self.local_members = {}
def _get_redis_connection(self):
"""从连接池获取 Redis 连接"""
return redis.Redis(connection_pool=self.redis_pool)
def get_current_members(self, group_id): def get_current_members(self, group_id):
""" 获取当前群成员信息 """ """ 获取当前群成员信息 """
print(f"Fetching current members for group_id: {group_id}") print(f"Fetching current members for group_id: {group_id}")
@@ -27,8 +30,8 @@ class GroupMemberChange:
# 读取 Redis 中的数据 # 读取 Redis 中的数据
print(f"Fetching previous data from Redis for group_id: {group_id}") print(f"Fetching previous data from Redis for group_id: {group_id}")
membercount_previous = self.r.get(membercount_key) membercount_previous = self._get_redis_connection().get(membercount_key)
members_previous = self.r.hgetall(members_key) # 获取上次的成员信息 members_previous = self._get_redis_connection().hgetall(members_key) # 获取上次的成员信息
print(f"Previous membercount: {membercount_previous}, Previous members: {members_previous}") print(f"Previous membercount: {membercount_previous}, Previous members: {members_previous}")
return membercount_previous, members_previous return membercount_previous, members_previous
@@ -48,9 +51,10 @@ class GroupMemberChange:
if membercount_previous is None or not members_previous: if membercount_previous is None or not members_previous:
print("First time processing, saving current data to Redis") print("First time processing, saving current data to Redis")
members_current = self.get_current_members(group_id) members_current = self.get_current_members(group_id)
self.r.set(f"group:group_member_count:{group_id}", membercount_current) self._get_redis_connection().set(f"group:group_member_count:{group_id}", membercount_current)
self.r.delete(f"group:group_members:{group_id}") self._get_redis_connection().delete(f"group:group_members:{group_id}")
self.r.hset(f"group:group_members:{group_id}", mapping=members_current) # 存储当前成员信息 self._get_redis_connection().hset(f"group:group_members:{group_id}",
mapping=members_current) # 存储当前成员信息
# 更新本地缓存 # 更新本地缓存
self.local_membercounts[group_id] = membercount_current self.local_membercounts[group_id] = membercount_current
@@ -99,11 +103,11 @@ class GroupMemberChange:
# 更新 Redis 数据 # 更新 Redis 数据
print(f"Updating Redis with current membercount and members") print(f"Updating Redis with current membercount and members")
self.r.set(f"group:group_member_count:{group_id}", membercount_current) self._get_redis_connection.set(f"group:group_member_count:{group_id}", membercount_current)
self.r.delete(f"group:group_members:{group_id}") self._get_redis_connection.delete(f"group:group_members:{group_id}")
# 更新 Redis 中的成员信息,确保在成员变化时也更新 # 更新 Redis 中的成员信息,确保在成员变化时也更新
self.r.hset(f"group:group_members:{group_id}", mapping=members_current) self._get_redis_connection.hset(f"group:group_members:{group_id}", mapping=members_current)
else: else:
result.append("$NO_CHANGE$") result.append("$NO_CHANGE$")

14
main.py
View File

@@ -25,25 +25,25 @@ def main(chat_type: int):
robot.LOG.info(f"WeChatRobot【{__version__}】成功启动···") robot.LOG.info(f"WeChatRobot【{__version__}】成功启动···")
# 机器人启动发送测试消息 # 机器人启动发送测试消息
robot.sendTextMsg("机器人启动成功!", "filehelper") robot.send_text_msg("机器人启动成功!", "filehelper")
# 接收消息 # 接收消息
# robot.enableRecvMsg() # 可能会丢消息? # robot.enableRecvMsg() # 可能会丢消息?
robot.enableReceivingMsg() # 加队列 robot.enableReceivingMsg() # 加队列
# 每天 8:30 发送新闻 # 每天 8:30 发送新闻
robot.onEveryTime("08:30", robot.newsBaiduReportAuto) robot.onEveryTime("08:30", robot.news_baidu_report_auto)
# epic # epic
robot.onEveryTime("10:30", robot.sendEpicFreeGames) robot.onEveryTime("10:30", robot.send_epic_free_games)
# message report 1:数据自动从redis 转到sqllite # message report 1:数据自动从redis 转到sqllite
robot.onEveryTime("00:30", robot.messageCountToDB) robot.onEveryTime("00:30", robot.message_count_to_db)
# 从db中提取并发送给相关群 # 从db中提取并发送给相关群
robot.onEveryTime("09:30", robot.generateAndSendRanking) robot.onEveryTime("09:30", robot.generate_and_send_ranking)
# sehuatang # sehuatang
robot.onEveryTime("15:00", robot.generateSehuatangPdf) robot.onEveryTime("15:00", robot.generate_sehuatang_pdf)
# 游戏的定时任务每小时执行 # 游戏的定时任务每小时执行
robot.onEveryTime("18:00", robot.game_auto_tasks) robot.onEveryTime("18:00", robot.game_auto_tasks)
@@ -55,7 +55,7 @@ def main(chat_type: int):
robot.onEveryTime("17:30", robot.xiu_ren_pdf_send) robot.onEveryTime("17:30", robot.xiu_ren_pdf_send)
# 让机器人一直跑 # 让机器人一直跑
robot.keepRunningAndBlockProcess() robot.keep_running_and_block_process()
if __name__ == "__main__": if __name__ == "__main__":

7
message_sign/config.toml Normal file
View File

@@ -0,0 +1,7 @@
[SignIn]
enable = true
command = ["签到", "每日签到", "qd", "Qd", "QD"]
min-point = 3
max-point = 20
streak-cycle = 5 # 每签到?天后额外积分奖励加1点
max-streak-point = 10 # 额外积分奖励上限

233
message_sign/main.py Normal file
View File

@@ -0,0 +1,233 @@
import datetime
import logging
import mysql.connector.pooling
import tomllib
import pytz
import redis
from typing import Optional, Tuple
from wcferry import Wcf, WxMsg
from robot_cmd.robot_command import GroupBotManager, Feature, PermissionStatus
# 创建表的SQL语句
CREATE_TABLE_SQL = """
CREATE TABLE IF NOT EXISTS t_sign_record (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
wx_id VARCHAR(100) NOT NULL,
group_id VARCHAR(100) NOT NULL,
wx_nick_name VARCHAR(100) NOT NULL,
points INT DEFAULT 0,
sign_stat DATETIME,
signin_streak INT DEFAULT 0,
create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY unique_sign (wx_id, group_id)
)
"""
class SignInSystem:
def __init__(self, wcf: Wcf, gbm: GroupBotManager, all_contacts: dict,
db_pool: mysql.connector.pooling.MySQLConnectionPool, redis_pool: redis.ConnectionPool):
# 读取配置文件
with open('message_sign/config.toml', 'rb') as f:
self.config = tomllib.load(f)['SignIn']
self.LOG = logging.getLogger(__name__)
if not self.config['enable']:
raise Exception("签到功能未启用")
self.wcf = wcf
self.gbm = gbm
self.all_contacts = all_contacts
self.db_pool = db_pool
self.redis_pool = redis_pool
self.command = self.config['command']
self.min_point = self.config['min-point']
self.max_point = self.config['max-point']
self.streak_cycle = self.config['streak-cycle']
self.max_streak_point = self.config['max-streak-point']
# 时区设置
self.timezone = 'Asia/Shanghai'
# 从 Redis 初始化签到数据
self.today_signin_count = self._load_signin_count_from_redis()
with self._get_redis_connection() as redis_client:
last_reset_date_str = redis_client.get('group:sign_in:last_reset_date')
if last_reset_date_str:
self.last_reset_date = datetime.datetime.strptime(last_reset_date_str, '%Y-%m-%d').date()
else:
self.last_reset_date = datetime.datetime.now(tz=pytz.timezone(self.timezone)).date()
self._save_last_reset_date_to_redis()
self.LOG.info(f"[签到] 组件初始化完成 {self.command_format}")
def _get_db_connection(self):
"""从连接池获取数据库连接"""
return self.db_pool.get_connection()
def _get_redis_connection(self):
"""从连接池获取 Redis 连接"""
return redis.Redis(connection_pool=self.redis_pool)
def _load_signin_count_from_redis(self) -> dict:
"""从 Redis 加载签到人数数据"""
signin_count = {}
with self._get_redis_connection() as redis_client:
keys = redis_client.keys('group:sign_in:*')
for key in keys:
if key == 'group:sign_in:last_reset_date':
continue
group_id = key.replace('group:sign_in:', '')
count = redis_client.get(key)
if count is not None:
signin_count[group_id] = int(count)
return signin_count
def _save_signin_count_to_redis(self, group_id: str, count: int):
"""保存签到人数到 Redis"""
with self._get_redis_connection() as redis_client:
redis_client.set(f'group:sign_in:{group_id}', count)
def _save_last_reset_date_to_redis(self):
"""保存最后重置日期到 Redis"""
with self._get_redis_connection() as redis_client:
redis_client.set('group:sign_in:last_reset_date', self.last_reset_date.strftime('%Y-%m-%d'))
@property
def command_format(self):
return ','.join(self.command)
@property
def enable(self):
return self.config['enable']
def initialize_table(self):
"""初始化数据库表"""
with self._get_db_connection() as conn:
with conn.cursor(dictionary=True) as cursor: # 使用 dictionary=True 返回字典格式
cursor.execute(CREATE_TABLE_SQL)
conn.commit()
def reset_today_count_if_needed(self):
"""检查并重置每日签到计数"""
current_date = datetime.datetime.now(tz=pytz.timezone(self.timezone)).date()
if current_date != self.last_reset_date:
self.today_signin_count.clear()
with self._get_redis_connection() as redis_client:
keys = redis_client.keys('group:sign_in:*')
for key in keys:
if key != 'group:sign_in:last_reset_date':
redis_client.delete(key)
self.last_reset_date = current_date
self._save_last_reset_date_to_redis()
self.LOG.info(f"[签到] 已重置每日签到计数,日期更新为 {current_date}")
def get_today_signin_count(self, group_id: str) -> int:
"""获取群内今日签到人数(使用缓存)"""
self.reset_today_count_if_needed()
return self.today_signin_count.get(group_id, 0)
def get_user_record(self, wx_id: str, group_id: str) -> Optional[dict]:
"""获取用户签到记录"""
with self._get_db_connection() as conn:
with conn.cursor(dictionary=True) as cursor:
query = """
SELECT wx_id, group_id, wx_nick_name, points, sign_stat, signin_streak
FROM t_sign_record
WHERE wx_id = %s AND group_id = %s
"""
cursor.execute(query, (wx_id, group_id))
return cursor.fetchone()
def calculate_points(self, streak: int) -> int:
"""根据连续签到天数计算积分"""
base_points = self.min_point
extra_points = min(streak // self.streak_cycle, self.max_streak_point)
total_points = base_points + extra_points
return min(total_points, self.max_point)
def member_sign_in(self, message: WxMsg):
"""会员签到功能"""
if not self.enable:
return
content = str(message.content).strip()
command = content.split(" ")
if not len(command) or command[0] not in self.command:
return
if self.gbm.get_group_permission(message.roomid, Feature.TASK_GAME) == PermissionStatus.DISABLED:
return
current_time = datetime.datetime.now(tz=pytz.timezone(self.timezone))
today_start = current_time.replace(hour=0, minute=0, second=0, microsecond=0)
yesterday = today_start - datetime.timedelta(days=1)
user_record = self.get_user_record(message.sender, message.roomid)
wx_nick_name = self.all_contacts.get(message.sender, message.sender)
if user_record and user_record['sign_stat'] and user_record['sign_stat'] >= today_start:
self.wcf.send_text(
f"@{wx_nick_name} 您今天已经签到过了!当前积分:{user_record['points']}",
message.sender
)
return
streak = 0
if user_record and user_record['sign_stat']:
last_sign_date = user_record['sign_stat'].replace(hour=0, minute=0, second=0, microsecond=0)
if last_sign_date == yesterday:
streak = user_record['signin_streak'] + 1
else:
streak = 1
else:
streak = 1
today_signin_rank = self.get_today_signin_count(message.roomid) + 1
self.today_signin_count[message.roomid] = today_signin_rank
self._save_signin_count_to_redis(message.roomid, today_signin_rank)
points_to_add = self.calculate_points(streak)
with self._get_db_connection() as conn:
with conn.cursor(dictionary=True) as cursor:
if user_record:
update_sql = """
UPDATE t_sign_record
SET wx_nick_name = %s, points = points + %s,
sign_stat = %s, signin_streak = %s,
update_time = %s
WHERE wx_id = %s AND group_id = %s
"""
cursor.execute(update_sql, (
wx_nick_name, points_to_add, current_time, streak,
current_time, message.sender, message.roomid
))
else:
insert_sql = """
INSERT INTO t_sign_record
(wx_id, group_id, wx_nick_name, points, sign_stat, signin_streak)
VALUES (%s, %s, %s, %s, %s, %s)
"""
cursor.execute(insert_sql, (
message.sender, message.roomid, wx_nick_name, points_to_add, current_time, streak
))
conn.commit()
msg = (
f"@{wx_nick_name} 签到成功!\n"
f"您是今日群内第{today_signin_rank}个签到的\n"
f"连续签到{streak}天,本次获得{points_to_add}积分"
)
self.wcf.send_text(
msg,
(message.roomid if message.from_group() else message.sender),
message.sender
)
def __del__(self):
"""连接池由外部管理,不需要手动关闭"""
pass

View File

@@ -4,120 +4,109 @@ import redis
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
from message_summary.message_summary_4o import message_summary from message_summary.message_summary_4o import message_summary
# 配置数据库连接 import mysql.connector.pooling
db_config = {
'host': '192.168.2.32', # 替换为你的MariaDB服务器地址
'user': 'root', # 替换为你的MariaDB用户名
'password': 'lw123456', # 替换为你的MariaDB密码
'database': 'message_archive'
}
# 连接到Redis
r = redis.Redis(host='192.168.2.32', port=6379, db=0)
def archive_message(group_id, timestamp_str, sender, content, message_type, attachment_url=None): class MessageStorage:
# 连接到数据库
connection = pymysql.connect(**db_config)
try: def __init__(self, db_pool: mysql.connector.pooling.MySQLConnectionPool, redis_pool: redis.ConnectionPool):
with connection.cursor() as cursor: self.redis_pool = redis_pool
# 插入消息信息 self.db_pool = db_pool
sql = """ # 初始化本地缓存字典,使用 group_id 作为键
INSERT INTO messages (group_id,timestamp, sender, content, message_type, attachment_url) self.local_membercounts = {}
VALUES (%s, %s, %s, %s, %s, %s) self.local_members = {}
"""
cursor.execute(sql, (group_id, timestamp_str, sender, content, message_type, attachment_url))
# 提交事务 def _get_redis_connection(self):
connection.commit() """从连接池获取 Redis 连接"""
print(f"Archived{timestamp_str}:{group_id}:{sender}: {content}") return redis.Redis(connection_pool=self.redis_pool)
except Exception as e: def archive_message(self, group_id, timestamp_str, sender, content, message_type, attachment_url=None):
print(f"Error archiving message: {e}") # 连接到数据库
connection.rollback() connection = self.db_pool.get_connection()
finally: try:
# 关闭连接 with connection.cursor() as cursor:
connection.close() # 插入消息信息
sql = """
INSERT INTO messages (group_id,timestamp, sender, content, message_type, attachment_url)
VALUES (%s, %s, %s, %s, %s, %s)
"""
cursor.execute(sql, (group_id, timestamp_str, sender, content, message_type, attachment_url))
# 提交事务
connection.commit()
print(f"Archived{timestamp_str}:{group_id}:{sender}: {content}")
def get_messages(group_id, all_contacts: dict): except Exception as e:
# 连接到数据库 print(f"Error archiving message: {e}")
with pymysql.connect(**db_config) as connection: connection.rollback()
# 获取 redis 中的上次总结时间,本次从上次开始算,若没有,则从 8 小时之前开始计算
key = f"{group_id}:summary_time"
last_summary_time = r.get(key)
# 如果 Redis 返回值为字节类型,转换为字符串 finally:
if last_summary_time: # 关闭连接
last_summary_time = last_summary_time.decode('utf-8') connection.close()
current_time = datetime.now() def get_messages(self, group_id, all_contacts: dict):
current_date = current_time.strftime('%Y-%m-%d %H:%M:%S') # 连接到数据库
with self.db_pool.get_connection() as connection:
# 获取 redis 中的上次总结时间,本次从上次开始算,若没有,则从 8 小时之前开始计算
key = f"{group_id}:summary_time"
last_summary_time = self._get_redis_connection().get(key)
if not last_summary_time: # 如果 Redis 返回值为字节类型,转换为字符串
# 获取当前时间并计算 8 小时前的时间 if last_summary_time:
eight_hours_ago = current_time - timedelta(hours=8) last_summary_time = last_summary_time.decode('utf-8')
last_summary_time = eight_hours_ago.strftime('%Y-%m-%d %H:%M:%S')
else:
# 检查 redis 中的时间与当前时间差是否小于 3 小时
last_summary_time_obj = datetime.strptime(last_summary_time, '%Y-%m-%d %H:%M:%S')
time_diff = current_time - last_summary_time_obj
if time_diff < timedelta(hours=3): current_time = datetime.now()
# 如果小于 3 小时,取当天的内容 current_date = current_time.strftime('%Y-%m-%d %H:%M:%S')
last_summary_time = current_time.replace(hour=0, minute=0, second=0, microsecond=0).strftime(
'%Y-%m-%d %H:%M:%S')
elif time_diff > timedelta(days=1):
# 如果超过 24 小时,将时间设置为当天 0 点
last_summary_time = current_time.replace(hour=0, minute=0, second=0, microsecond=0).strftime(
'%Y-%m-%d %H:%M:%S')
# 更新 Redis 存储的当前时间 if not last_summary_time:
# r.set(key, current_date) # 获取当前时间并计算 8 小时前的时间
eight_hours_ago = current_time - timedelta(hours=8)
last_summary_time = eight_hours_ago.strftime('%Y-%m-%d %H:%M:%S')
else:
# 检查 redis 中的时间与当前时间差是否小于 3 小时
last_summary_time_obj = datetime.strptime(last_summary_time, '%Y-%m-%d %H:%M:%S')
time_diff = current_time - last_summary_time_obj
with connection.cursor() as cursor: if time_diff < timedelta(hours=3):
# 执行查询,获取最近 8 小时的消息 # 如果小于 3 小时,取当天的内容
query = """ last_summary_time = current_time.replace(hour=0, minute=0, second=0, microsecond=0).strftime(
SELECT timestamp, sender, content,message_type '%Y-%m-%d %H:%M:%S')
FROM messages elif time_diff > timedelta(days=1):
WHERE timestamp >= %s AND message_type in(1,49) AND group_id = %s # 如果超过 24 小时,将时间设置为当天 0 点
""" last_summary_time = current_time.replace(hour=0, minute=0, second=0, microsecond=0).strftime(
cursor.execute(query, (last_summary_time, group_id)) '%Y-%m-%d %H:%M:%S')
# 构建最终的结果字符串 # 更新 Redis 存储的当前时间
# message_type 需要加入49类型因为49是引用之后的发言。但是49是xml 需要将content进行xml解析 # r.set(key, current_date)
result = [] with connection.cursor() as cursor:
for row in cursor.fetchall(): # 执行查询,获取最近 8 小时的消息
timestamp, sender, content, message_type = row query = """
try: SELECT timestamp, sender, content,message_type
if message_type == "49": FROM messages
# 解析 XML 字符串 WHERE timestamp >= %s AND message_type in(1,49) AND group_id = %s
root = ET.fromstring(content) """
# 提取 title 内容 cursor.execute(query, (last_summary_time, group_id))
content = root.find('.//title').text
except Exception as e: # 构建最终的结果字符串
print(f"message_type 49 error: {e}") # message_type 需要加入49类型因为49是引用之后的发言。但是49是xml 需要将content进行xml解析
sender_name = all_contacts.get(sender, sender) # 获取发送者的名字,若找不到则使用原 ID
result.append(f"{timestamp},{sender_name},{content}")
result_str = "\n".join(result) # 将结果拼接为最终字符串 result = []
print(result_str) for row in cursor.fetchall():
return result_str timestamp, sender, content, message_type = row
try:
if message_type == "49":
# 解析 XML 字符串
root = ET.fromstring(content)
# 提取 title 内容
content = root.find('.//title').text
except Exception as e:
print(f"message_type 49 error: {e}")
sender_name = all_contacts.get(sender, sender) # 获取发送者的名字,若找不到则使用原 ID
result.append(f"{timestamp},{sender_name},{content}")
# 示例用法 result_str = "\n".join(result) # 将结果拼接为最终字符串
if __name__ == "__main__": print(result_str)
# group_id = 'XXX@123123' return result_str
# timestamp_str = "2025-02-06 11:15:28"
# sender = "XXX"
# content = "This is a test message with a string timestamp."
# message_type = "text"
# attachment_url = "http://example.com/attachment.pdf" # 可以为None如果没有附件
#
# archive_message(group_id, timestamp_str, sender, content, message_type, attachment_url)
# get_messages("45317011307@chatroom", {})
message_summary(get_messages("45317011307@chatroom", {}))

63
music/bot_music.py Normal file
View File

@@ -0,0 +1,63 @@
import logging
import tomllib
import aiohttp
from wcferry import WxMsg, Wcf
from robot_cmd.robot_command import Feature, PermissionStatus, GroupBotManager
class BotMusic:
def __init__(self, wcf: Wcf, gbm: GroupBotManager):
self.LOG = logging.getLogger(__name__)
self.wcf = wcf # 假设 wcf 对象在此类中初始化
self.gbm = gbm # 权限功能
with open("music/config.toml", "rb") as f:
plugin_config = tomllib.load(f)
config = plugin_config["Music"]
self.enable = config["enable"]
self.command = config["command"]
self.command_format = config["command-format"]
self.LOG.info(f"[点歌台] 组件初始化完成,指令: {self.command}")
async def get_music(self, message: WxMsg):
if not self.enable:
return
content = str(message.content).strip()
command = content.split(" ")
if command[0] not in self.command:
return
if len(command) == 1:
self.wcf.send_text(f"-----Bot-----\n❌命令格式错误!{self.command_format}",
(message.roomid if message.from_group() else message.sender), message.sender)
return
# 如果触发了指令,但是没有权限,则返回权限不足
if self.gbm.get_group_permission(message.roomid, Feature.TASK_GAME) == PermissionStatus.DISABLED:
return
song_name = content[len(command[0]):].strip()
async with aiohttp.ClientSession() as session:
async with session.get(
f"https://www.hhlqilongzhu.cn/api/dg_wyymusic.php?gm={song_name}&n=1&br=2&type=json") as resp:
data = await resp.json()
if data["code"] != 200:
self.wcf.send_text(f"-----Bot-----\n❌点歌失败!\n{data}",
(message.roomid if message.from_group() else message.sender), message.sender)
return
title = data["title"]
singer = data["singer"]
url = data["link"]
music_url = data["music_url"].split("?")[0]
cover_url = data["cover"]
lyric = data["lrc"]
xml = f"""<appmsg appid="wx79f2c4418704b4f8" sdkver="0"><title>{title}</title><des>{singer}</des><action>view</action><type>3</type><showtype>0</showtype><content/><url>{url}</url><dataurl>{music_url}</dataurl><lowurl>{url}</lowurl><lowdataurl>{music_url}</lowdataurl><recorditem/><thumburl>{cover_url}</thumburl><messageaction/><laninfo/><extinfo/><sourceusername/><sourcedisplayname/><songlyric>{lyric}</songlyric><commenturl/><appattach><totallen>0</totallen><attachid/><emoticonmd5/><fileext/><aeskey/></appattach><webviewshared><publisherId/><publisherReqId>0</publisherReqId></webviewshared><weappinfo><pagepath/><username/><appid/><appservicetype>0</appservicetype></weappinfo><websearch/><songalbumurl>{cover_url}</songalbumurl></appmsg><fromusername>{bot.wxid}</fromusername><scene>0</scene><appinfo><version>1</version><appname/></appinfo><commenturl/>"""
self.wcf.send_xml(message.sender, xml, 3)

8
music/config.toml Normal file
View File

@@ -0,0 +1,8 @@
[Music]
enable = true
command = ["点歌", "音乐", "音乐点播", "点播音乐", "音乐点歌"]
command-format = """
-----Bot-----
🎵点歌指令:
点歌 歌曲名
"""

View File

@@ -27,3 +27,7 @@ selenium~=4.28.1
webdriver-manager~=4.0.2 webdriver-manager~=4.0.2
reportlab~=4.3.0 reportlab~=4.3.0
PyPDF2~=3.0.1 PyPDF2~=3.0.1
Flask~=3.1.0
aiohttp~=3.11.12
mysql-connector-python~=9.2.0
pytz~=2025.1

119
robot.py
View File

@@ -9,6 +9,8 @@ from threading import Thread
from datetime import datetime, timedelta from datetime import datetime, timedelta
import random import random
import redis
from base.func_doubao import Doubao from base.func_doubao import Doubao
from base.func_epic import is_friday, get_free from base.func_epic import is_friday, get_free
from base.func_zhipu import ZhiPu from base.func_zhipu import ZhiPu
@@ -29,16 +31,19 @@ from game_task.game_task_encyclopedia import game_process_message, setup_schedul
run_random_task_assignment run_random_task_assignment
from group_auto.group_auto_invite import get_first_group_id, process_command from group_auto.group_auto_invite import get_first_group_id, process_command
from group_auto.group_member_change import GroupMemberChange from group_auto.group_member_change import GroupMemberChange
from message_sign.main import SignInSystem
from message_storage.message_to_db import MessageStorage
from music.bot_music import BotMusic
from robot_cmd.robot_command import GroupBotManager from robot_cmd.robot_command import GroupBotManager
from job_mgmt import Job from job_mgmt import Job
from robot_cmd.robot_command import Feature from robot_cmd.robot_command import Feature
from robot_cmd.robot_command import PermissionStatus from robot_cmd.robot_command import PermissionStatus
import mysql.connector.pooling
__version__ = "39.2.4.0" __version__ = "39.2.4.0"
from message_report.process_message import process_message from message_report.process_message import process_message
from message_report.write_db import write_to_db, generate_and_send_ranking from message_report.write_db import write_to_db, generate_and_send_ranking
from message_storage.message_to_db import archive_message, get_messages
from message_summary.message_summary_4o import message_summary from message_summary.message_summary_4o import message_summary
from sehuatang.shehuatang import pdf_file_path from sehuatang.shehuatang import pdf_file_path
from xiuren.meitu_dl import meitu_dowload_pic, meitu_dowload_pub_pic, meitu_dowload_heisi_pic from xiuren.meitu_dl import meitu_dowload_pic, meitu_dowload_pub_pic, meitu_dowload_heisi_pic
@@ -55,11 +60,27 @@ class Robot(Job):
self.config = config self.config = config
self.LOG = logging.getLogger("Robot") self.LOG = logging.getLogger("Robot")
self.wxid = self.wcf.get_self_wxid() self.wxid = self.wcf.get_self_wxid()
self.allContacts = self.getAllContacts() self.allContacts = self.get_all_contacts()
self.LOG.info(f"DB+REDIS 连接池开始初始化")
# db 配置加载
self.db_pool = mysql.connector.pooling.MySQLConnectionPool(self.config.mariadb)
self.LOG.info(f"DB连接池加载完成: {self.config.mariadb}")
self.redis_pool = redis.ConnectionPool(self.config.redis)
self.LOG.info(f"REDIS连接池加载完成: {self.config.redis}")
self.groups = {} # 存储按group_id分组的消息列表每个group_id最多保留10条消息 self.groups = {} # 存储按group_id分组的消息列表每个group_id最多保留10条消息
GroupBotManager.load_local_cache() GroupBotManager.load_local_cache()
# 消息存档模块初始化,自动完成入库动作
self.message_storage = MessageStorage(self.db_pool, self.redis_pool)
# 权限模块加载
self.gbm = GroupBotManager() self.gbm = GroupBotManager()
self.gmc = GroupMemberChange(wcf) # 群成员变更模块加载
self.gmc = GroupMemberChange(wcf, self.redis_pool)
# 点歌模块加载
self.music = BotMusic(wcf, self.gbm)
# 签到模块加载
self.signin = SignInSystem(wcf, self.gbm, self.allContacts, self.db_pool, self.redis_pool)
if ChatType.is_in_chat_types(chat_type): if ChatType.is_in_chat_types(chat_type):
if chat_type == ChatType.TIGER_BOT.value and TigerBot.value_check(self.config.TIGERBOT): if chat_type == ChatType.TIGER_BOT.value and TigerBot.value_check(self.config.TIGERBOT):
self.chat = TigerBot(self.config.TIGERBOT) self.chat = TigerBot(self.config.TIGERBOT)
@@ -132,13 +153,13 @@ class Robot(Job):
if cy.isChengyu(text): if cy.isChengyu(text):
rsp = cy.getNext(text) rsp = cy.getNext(text)
if rsp: if rsp:
self.sendTextMsg(rsp, msg.roomid) self.send_text_msg(rsp, msg.roomid)
status = True status = True
elif flag in ["?", ""]: # 查词 elif flag in ["?", ""]: # 查词
if cy.isChengyu(text): if cy.isChengyu(text):
rsp = cy.getMeaning(text) rsp = cy.getMeaning(text)
if rsp: if rsp:
self.sendTextMsg(rsp, msg.roomid) self.send_text_msg(rsp, msg.roomid)
status = True status = True
return status return status
@@ -172,15 +193,15 @@ class Robot(Job):
player_id = resp["player_id"] player_id = resp["player_id"]
print(f"消息: {message}") print(f"消息: {message}")
print(f"玩家ID: {player_id}") print(f"玩家ID: {player_id}")
self.sendTextMsg(message, msg.roomid, msg.sender) self.send_text_msg(message, msg.roomid, msg.sender)
except Exception as e: except Exception as e:
self.LOG.error(f"game_message_load error{e}") self.LOG.error(f"game_message_load error{e}")
return True return True
if q == "#今日百度新闻": if q == "#今日百度新闻":
self.newsBaiduReport((msg.roomid if msg.from_group() else msg.sender)) self.news_baidu_report((msg.roomid if msg.from_group() else msg.sender))
return True return True
elif q in ["nbc", "cnn", "abc", "fox", "bbc"]: elif q in ["nbc", "cnn", "abc", "fox", "bbc"]:
self.newsEnReport(q, (msg.roomid if msg.from_group() else msg.sender)) self.news_en_report(q, (msg.roomid if msg.from_group() else msg.sender))
return True return True
elif q == '#总结': elif q == '#总结':
self.message_summary_robot((msg.roomid if msg.from_group() else msg.sender)) self.message_summary_robot((msg.roomid if msg.from_group() else msg.sender))
@@ -221,7 +242,7 @@ class Robot(Job):
# 如果是群消息并且群没开启AI则不处理该动作 # 如果是群消息并且群没开启AI则不处理该动作
if msg.from_group() and self.gbm.get_group_permission(msg.roomid, if msg.from_group() and self.gbm.get_group_permission(msg.roomid,
Feature.AI_CAPABILITY) == PermissionStatus.DISABLED: Feature.AI_CAPABILITY) == PermissionStatus.DISABLED:
self.sendTextMsg("群AI功能未开启", msg.roomid, msg.sender) self.send_text_msg("群AI功能未开启", msg.roomid, msg.sender)
return True return True
else: else:
if msg.type == 1: # 只处理类型为1的消息提供的问题引用@不予以对话 if msg.type == 1: # 只处理类型为1的消息提供的问题引用@不予以对话
@@ -230,9 +251,9 @@ class Robot(Job):
return True return True
if rsp: if rsp:
if msg.from_group(): if msg.from_group():
self.sendTextMsg(rsp, msg.roomid, msg.sender) self.send_text_msg(rsp, msg.roomid, msg.sender)
else: else:
self.sendTextMsg(rsp, msg.sender) self.send_text_msg(rsp, msg.sender)
return True return True
else: else:
@@ -259,7 +280,7 @@ class Robot(Job):
# 聊天记录入库动作: # 聊天记录入库动作:
try: try:
now_time = str(datetime.now().strftime("%Y-%m-%d %H:%M:%S")) now_time = str(datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
archive_message(msg.roomid, now_time, msg.sender, msg.content, msg.type, msg.extra) self.message_storage.archive_message(msg.roomid, now_time, msg.sender, msg.content, msg.type, msg.extra)
except Exception as e: except Exception as e:
self.LOG.error(f"archive_message error: {e}") self.LOG.error(f"archive_message error: {e}")
@@ -268,7 +289,7 @@ class Robot(Job):
if msg.from_self(): if msg.from_self():
self.revoke_receive_message(msg) self.revoke_receive_message(msg)
rsp = self.gbm.handle_command(msg.roomid, msg.content) rsp = self.gbm.handle_command(msg.roomid, msg.content)
self.sendTextMsg(rsp, msg.roomid, msg.sender) self.send_text_msg(rsp, msg.roomid, msg.sender)
return return
except Exception as e: except Exception as e:
self.LOG.error(f"revoke_receive_message error: {e}") self.LOG.error(f"revoke_receive_message error: {e}")
@@ -288,7 +309,7 @@ class Robot(Job):
player_id = resp["player_id"] player_id = resp["player_id"]
print(f"消息: {message}") print(f"消息: {message}")
print(f"玩家ID: {player_id}") print(f"玩家ID: {player_id}")
self.sendTextMsg(message, msg.roomid, msg.sender) self.send_text_msg(message, msg.roomid, msg.sender)
return return
except Exception as e: except Exception as e:
self.LOG.error(f"game_message_load error{e}") self.LOG.error(f"game_message_load error{e}")
@@ -298,25 +319,25 @@ class Robot(Job):
# 判断是否没有变化 # 判断是否没有变化
if "$NO_CHANGE$" not in result: if "$NO_CHANGE$" not in result:
self.LOG.info(f"检测到群成员变化,进行相关内容输出:{result}") self.LOG.info(f"检测到群成员变化,进行相关内容输出:{result}")
self.sendTextMsg(result, msg.roomid) self.send_text_msg(result, msg.roomid)
except Exception as e: except Exception as e:
self.LOG.error(f"group_member_change error: {e}") self.LOG.error(f"group_member_change error: {e}")
try:
self.music.get_music(message=msg)
except Exception as e:
self.LOG.error(f"get_music error: {e}")
if msg.is_at(self.wxid): # 被@ if msg.is_at(self.wxid): # 被@
self.toAt(msg) self.toAt(msg)
else: # 其他消息
self.toChengyu(msg)
return # 处理完群聊信息,后面就不需要处理了 return # 处理完群聊信息,后面就不需要处理了
# 非群聊信息,按消息类型进行处理 # 非群聊信息,按消息类型进行处理
if msg.type == 37: # 好友请求 if msg.type == 37: # 好友请求
self.LOG.info(f"收到好友请求:{msg}") self.LOG.info(f"收到好友请求:{msg}")
self.autoAcceptFriendRequest(msg) self.auto_accept_friend_request(msg)
elif msg.type == 10000: # 系统信息 elif msg.type == 10000: # 系统信息
self.sayHiToNewFriend(msg) self.say_hi_to_new_friend(msg)
elif msg.type == 0x01: # 文本消息 elif msg.type == 0x01: # 文本消息
# 让配置加载更灵活,自己可以更新配置。也可以利用定时任务更新。 # 让配置加载更灵活,自己可以更新配置。也可以利用定时任务更新。
@@ -326,15 +347,15 @@ class Robot(Job):
self.gbm.load_local_cache() self.gbm.load_local_cache()
self.LOG.info("已更新") self.LOG.info("已更新")
if msg.content == "今日百度新闻": if msg.content == "今日百度新闻":
self.newsBaiduReport() self.news_baidu_report()
if msg.content == '聊天排行榜': if msg.content == '聊天排行榜':
self.generateAndSendRanking() self.generate_and_send_ranking()
if msg.content == '聊天数据入库': if msg.content == '聊天数据入库':
self.messageCountToDB() self.message_count_to_db()
if msg.content == 'PDF': if msg.content == 'PDF':
self.generateSehuatangPdf() self.generate_sehuatang_pdf()
if msg.content == 'GROUP_LIST': if msg.content == 'GROUP_LIST':
self.sendTextMsg(self.gbm.get_group_list(), msg.sender) self.send_text_msg(self.gbm.get_group_list(), msg.sender)
if msg.content.startswith('#加群配置'): if msg.content.startswith('#加群配置'):
# msg_content = "# 加群配置|add 原生鱼 xxx@room" # msg_content = "# 加群配置|add 原生鱼 xxx@room"
parts = msg.content.split('|') parts = msg.content.split('|')
@@ -344,8 +365,8 @@ class Robot(Job):
resp = process_command(after_pipe) resp = process_command(after_pipe)
else: else:
resp = process_command("help") resp = process_command("help")
self.sendTextMsg(resp, msg.sender) self.send_text_msg(resp, msg.sender)
self.sendTextMsg(f"指令:{msg.content} 已执行", msg.sender) self.send_text_msg(f"指令:{msg.content} 已执行", msg.sender)
else: else:
self.toChitchat(msg) # 闲聊 self.toChitchat(msg) # 闲聊
@@ -376,7 +397,7 @@ class Robot(Job):
self.wcf.enable_receiving_msg() self.wcf.enable_receiving_msg()
Thread(target=innerProcessMsg, name="GetMessage", args=(self.wcf,), daemon=True).start() Thread(target=innerProcessMsg, name="GetMessage", args=(self.wcf,), daemon=True).start()
def sendTextMsg(self, msg: str, receiver: str, at_list: str = "") -> None: def send_text_msg(self, msg: str, receiver: str, at_list: str = "") -> None:
""" 发送消息 """ 发送消息
:param msg: 消息字符串 :param msg: 消息字符串
:param receiver: 接收人wxid或者群id :param receiver: 接收人wxid或者群id
@@ -405,7 +426,7 @@ class Robot(Job):
self.LOG.info(f"To {receiver}: {ats}\r{msg}") self.LOG.info(f"To {receiver}: {ats}\r{msg}")
self.wcf.send_text(f"{ats}\n\n{msg}", receiver, at_list) self.wcf.send_text(f"{ats}\n\n{msg}", receiver, at_list)
def getAllContacts(self) -> dict: def get_all_contacts(self) -> dict:
""" """
获取联系人(包括好友、公众号、服务号、群成员……) 获取联系人(包括好友、公众号、服务号、群成员……)
格式: {"wxid": "NickName"} 格式: {"wxid": "NickName"}
@@ -413,7 +434,7 @@ class Robot(Job):
contacts = self.wcf.query_sql("MicroMsg.db", "SELECT UserName, NickName FROM Contact;") contacts = self.wcf.query_sql("MicroMsg.db", "SELECT UserName, NickName FROM Contact;")
return {contact["UserName"]: contact["NickName"] for contact in contacts} return {contact["UserName"]: contact["NickName"] for contact in contacts}
def keepRunningAndBlockProcess(self) -> None: def keep_running_and_block_process(self) -> None:
""" """
保持机器人运行,不让进程退出 保持机器人运行,不让进程退出
""" """
@@ -421,7 +442,7 @@ class Robot(Job):
self.runPendingJobs() self.runPendingJobs()
time.sleep(1) time.sleep(1)
def autoAcceptFriendRequest(self, msg: WxMsg) -> None: def auto_accept_friend_request(self, msg: WxMsg) -> None:
try: try:
xml = ET.fromstring(msg.content) xml = ET.fromstring(msg.content)
v3 = xml.attrib["encryptusername"] v3 = xml.attrib["encryptusername"]
@@ -432,12 +453,12 @@ class Robot(Job):
except Exception as e: except Exception as e:
self.LOG.error(f"同意好友出错:{e}") self.LOG.error(f"同意好友出错:{e}")
def sayHiToNewFriend(self, msg: WxMsg) -> None: def say_hi_to_new_friend(self, msg: WxMsg) -> None:
nickName = re.findall(r"你已添加了(.*),现在可以开始聊天了。", msg.content) nickName = re.findall(r"你已添加了(.*),现在可以开始聊天了。", msg.content)
if nickName: if nickName:
# 添加了好友,更新好友列表 # 添加了好友,更新好友列表
self.allContacts[msg.sender] = nickName[0] self.allContacts[msg.sender] = nickName[0]
self.sendTextMsg(f"Hi {nickName[0]},我自动通过了你的好友请求。", msg.sender) self.send_text_msg(f"Hi {nickName[0]},我自动通过了你的好友请求。", msg.sender)
def send_group_txt_message(self, msg: str, feature: Feature): def send_group_txt_message(self, msg: str, feature: Feature):
try: try:
@@ -446,7 +467,7 @@ class Robot(Job):
return return
for r in receivers: for r in receivers:
if self.gbm.get_group_permission(r, feature) == PermissionStatus.ENABLED: if self.gbm.get_group_permission(r, feature) == PermissionStatus.ENABLED:
self.sendTextMsg(msg, r) self.send_text_msg(msg, r)
except Exception as e: except Exception as e:
self.LOG.error(f"send_group_txt_message:{feature.description} error{e}") self.LOG.error(f"send_group_txt_message:{feature.description} error{e}")
@@ -497,28 +518,28 @@ class Robot(Job):
# ============================================== 业务内容========================================================== # ============================================== 业务内容==========================================================
def newsBaiduReportAuto(self) -> None: def news_baidu_report_auto(self) -> None:
try: try:
news = News().get_baidu_news() news = News().get_baidu_news()
self.send_group_txt_message(news, Feature.DAILY_NEWS) self.send_group_txt_message(news, Feature.DAILY_NEWS)
except Exception as e: except Exception as e:
self.LOG.error(f"newsBaiduReportAuto error{e}") self.LOG.error(f"newsBaiduReportAuto error{e}")
def newsBaiduReport(self, sender: str = None) -> None: def news_baidu_report(self, sender: str = None) -> None:
try: try:
news = News().get_baidu_news() news = News().get_baidu_news()
self.sendTextMsg(news, sender) self.send_text_msg(news, sender)
except Exception as e: except Exception as e:
self.LOG.error(f"newsBaiduReport error{e}") self.LOG.error(f"newsBaiduReport error{e}")
def newsEnReport(self, website, sender: str = None) -> None: def news_en_report(self, website, sender: str = None) -> None:
try: try:
news = News().get_eng_news(website) news = News().get_eng_news(website)
self.sendTextMsg(news, sender) self.send_text_msg(news, sender)
except Exception as e: except Exception as e:
self.LOG.error(f"newsEnReport error{e}") self.LOG.error(f"newsEnReport error{e}")
def sendEpicFreeGames(self): def send_epic_free_games(self):
try: try:
if is_friday(): if is_friday():
games = get_free() games = get_free()
@@ -526,13 +547,13 @@ class Robot(Job):
except Exception as e: except Exception as e:
self.LOG.error(f"sendEpicFreeGames error{e}") self.LOG.error(f"sendEpicFreeGames error{e}")
def messageCountToDB(self): def message_count_to_db(self):
try: try:
write_to_db() write_to_db()
except Exception as e: except Exception as e:
self.LOG.error(f"write_to_db error{e}") self.LOG.error(f"write_to_db error{e}")
def generateSehuatangPdf(self): def generate_sehuatang_pdf(self):
try: try:
path = pdf_file_path() path = pdf_file_path()
# 暂时只发4K群 # 暂时只发4K群
@@ -540,14 +561,14 @@ class Robot(Job):
except Exception as e: except Exception as e:
self.LOG.error(f"generateSehuatangPdf error{e}") self.LOG.error(f"generateSehuatangPdf error{e}")
def generateAndSendRanking(self): def generate_and_send_ranking(self):
try: try:
receivers = self.gbm.get_group_list() receivers = self.gbm.get_group_list()
if not receivers: if not receivers:
return return
for r in receivers: for r in receivers:
if self.gbm.get_group_permission(r, Feature.DAILY_SUMMARY) == PermissionStatus.ENABLED: if self.gbm.get_group_permission(r, Feature.DAILY_SUMMARY) == PermissionStatus.ENABLED:
self.sendTextMsg(generate_and_send_ranking(r, self.allContacts), r) self.send_text_msg(generate_and_send_ranking(r, self.allContacts), r)
except Exception as e: except Exception as e:
self.LOG.error(f"SendRanking error{e}") self.LOG.error(f"SendRanking error{e}")
@@ -555,11 +576,11 @@ class Robot(Job):
try: try:
if self.gbm.get_group_permission(sender, Feature.SUMMARY_CAPABILITY) == PermissionStatus.ENABLED: if self.gbm.get_group_permission(sender, Feature.SUMMARY_CAPABILITY) == PermissionStatus.ENABLED:
self.LOG.info(f"群: {sender} 消息总结开始执行!") self.LOG.info(f"群: {sender} 消息总结开始执行!")
content = get_messages(sender, self.allContacts) content = self.message_storage.get_messages(sender, self.allContacts)
summary = message_summary(content) summary = message_summary(content)
self.sendTextMsg(summary, sender) self.send_text_msg(summary, sender)
else: else:
self.sendTextMsg("群发言总结功能未开启", sender) self.send_text_msg("群发言总结功能未开启", sender)
except Exception as e: except Exception as e:
self.LOG.error(f"message_summary_robot error{e}") self.LOG.error(f"message_summary_robot error{e}")
@@ -574,7 +595,7 @@ class Robot(Job):
player_id = rep["player_id"] player_id = rep["player_id"]
print(f"消息: {message}") print(f"消息: {message}")
print(f"玩家ID: {player_id}") print(f"玩家ID: {player_id}")
self.sendTextMsg(message, gid, player_id) self.send_text_msg(message, gid, player_id)
except Exception as e: except Exception as e:
self.LOG.error(f"message_summary_robot error{e}") self.LOG.error(f"message_summary_robot error{e}")

View File

@@ -31,6 +31,7 @@ class Feature(Enum):
EPIC = 7, "EPIC自动播报" # 新增的功能 EPIC = 7, "EPIC自动播报" # 新增的功能
PIC = 8, "图来能力" PIC = 8, "图来能力"
TASK_GAME = 9, "百科答题游戏" TASK_GAME = 9, "百科答题游戏"
MUSIC = 10, "点歌功能"
def __new__(cls, value, description): def __new__(cls, value, description):
obj = object.__new__(cls) obj = object.__new__(cls)