更新 README 文件,增加项目背景介绍,修改部分标题格式;删除成语相关命令及其处理逻辑,移除成语数据文件和相关功能代码。

This commit is contained in:
Zylan
2025-04-23 14:22:35 +08:00
parent 6196146825
commit 745081a35b
7 changed files with 90 additions and 31118 deletions

View File

@@ -6,13 +6,21 @@
![Python](https://img.shields.io/badge/Python-3.8+-green) ![Python](https://img.shields.io/badge/Python-3.8+-green)
![License](https://img.shields.io/badge/License-Apache2.0-yellow) ![License](https://img.shields.io/badge/License-Apache2.0-yellow)
## 🔗 写在前面
我一直在尝试做一个全面的的生态助手(个人助理),能够连接我使用的任何工具、日程表、数据库、资料库。并基于数据资料,实时地和我交流,以及帮我安排日程、提醒、规划时间和出行,安排我的任务计划。
之前做了 [LifeSync-AI](https://github.com/Zippland/LifeSync-AI)基于Github Action、Notion、Zapier进行app互联帮我进行每天的任务规划。但定时任务是被动的而且缺少一个统一的数据处理中心能够通过与用户交流进行实时的任务调度。
这就是这个项目的初衷。
## 📝 项目简介 ## 📝 项目简介
Bubbles 是一个功能丰富的微信机器人框架,基于 [wcferry](https://github.com/lich0821/wcferry) 开发支持接入多种大型语言模型LLM提供丰富的交互功能和定时任务。该项目旨在将微信客户端转变为一个智能的个人助手可以执行多种实用功能带来便捷的用户体验。 Bubbles 是一个功能丰富的微信机器人框架,基于 [wcferry](https://github.com/lich0821/wcferry) 和 [WechatRobot](https://github.com/lich0821/wechatrobot) 开发支持接入多种大型语言模型LLM提供丰富的交互功能和定时任务。该项目旨在将微信客户端转变为一个智能的个人助手可以执行多种实用功能带来便捷的用户体验。
## ✨ 核心特性 ## ✨ 核心特性
### 🤖 灵活的模型配置 #### 🤖 灵活的模型配置
- 支持为不同的群聊和私聊设置不同的 AI 模型和 system prompt - 支持为不同的群聊和私聊设置不同的 AI 模型和 system prompt
- OpenAI (ChatGPT) - OpenAI (ChatGPT)
- Google Gemini - Google Gemini
@@ -24,36 +32,37 @@ Bubbles 是一个功能丰富的微信机器人框架,基于 [wcferry](https:/
- Perplexity - Perplexity
- Ollama (本地部署的模型) - Ollama (本地部署的模型)
### 🛠️ 丰富的命令系统 #### 🛠️ 丰富的命令系统
- 强大的命令路由系统,让功能新增无比简单 - 强大的命令路由系统,让功能新增无比简单
- 支持自定义命令及参数 - 支持自定义命令及参数
- 预设 [多种实用和娱乐命令](#可用命令) - 预设 [多种实用和娱乐命令](#可用命令)
### 🎨 AI 图像生成 #### 🎨 AI 图像生成
- 支持调用多种 AI 绘图模型生成图片 - 支持调用多种 AI 绘图模型生成图片
### ⏰ A定时任务与提醒功能 #### ⏰ 定时任务与提醒功能
- 每日天气预报推送 - 每日天气预报推送
- 每日新闻资讯推送 - 每日新闻资讯推送
- 工作日报/周报/月报提醒 - 工作日报/周报/月报提醒
- 个人自定义提醒系统(通过自然语言设置定时提醒) - 个人自定义提醒系统(通过自然语言设置定时提醒)
### 📊 对话管理 #### 📊 对话管理
- 智能消息总结功能 - 智能消息总结功能
- 处理各类微信消息(文本、图片、小程序、链接等) - 处理各类微信消息(文本、图片、小程序、链接等)
### 🔧 实用工具 #### 🔧 实用工具
- 自动接受好友请求并打招呼 - 自动接受好友请求并打招呼
- 自动响应群聊和私聊消息 - 自动响应群聊和私聊消息
## 🛠️ 安装指南 ## 🛠️ 安装指南
### 系统要求 #### 系统要求
- Python 3.8 或更高版本 - Python 3.8 或更高版本
- Windows 操作系统wcferry 要求) - Windows 操作系统wcferry 要求)
- 微信 PC 版客户端 - 微信 PC 版客户端
- 云配置要求如需2vCPU 2GiB (经济型)
### 安装步骤 #### 安装步骤
1. **克隆仓库** 1. **克隆仓库**
```bash ```bash
@@ -85,7 +94,7 @@ Bubbles 是一个功能丰富的微信机器人框架,基于 [wcferry](https:/
配置文件 `config.yaml` 包含以下主要部分: 配置文件 `config.yaml` 包含以下主要部分:
### AI 模型配置 #### AI 模型配置
每个 AI 模型都有自己的配置部分,例如: 每个 AI 模型都有自己的配置部分,例如:
@@ -101,7 +110,7 @@ CHATGPT:
proxy: "http://127.0.0.1:7890" # 可选:如需代理请填写 proxy: "http://127.0.0.1:7890" # 可选:如需代理请填写
``` ```
### 群组/私聊模型映射 #### 群组/私聊模型映射
您可以为不同的群聊或私聊指定不同的 AI 模型: 您可以为不同的群聊或私聊指定不同的 AI 模型:
@@ -122,7 +131,7 @@ GROUP_MODELS:
model: 8 # 8 代表 Deepseek model: 8 # 8 代表 Deepseek
``` ```
### 功能开关 #### 功能开关
您可以启用或禁用各种功能: 您可以启用或禁用各种功能:
@@ -138,34 +147,39 @@ GROUP_MODELS:
## 🚀 使用方法 ## 🚀 使用方法
### 启动机器人 #### 启动机器人
```bash ```bash
python main.py python main.py
``` ```
### 可用命令 #### 可用命令
机器人支持多种命令,按功能分类如下: 机器人支持多种命令,按功能分类如下:
#### 基础系统命令 ##### 提醒功能
- `提醒xxxxx` - 用自然语言设置一个提醒
- `查看提醒`、`我的提醒`、`提醒列表` - 查看您设置的所有提醒
- `删除提醒 ID:xxxx`、`取消提醒 all` - 删除指定的(或所有)提醒
##### 基础系统命令
- `info`、`帮助`、`指令` - 显示机器人的帮助信息 - `info`、`帮助`、`指令` - 显示机器人的帮助信息
- `骂一下 @用户名` - 让机器人骂指定用户(仅群聊) - `骂一下 @用户名` - 让机器人骂指定用户(仅群聊)
- `reset`、`重置` - 重置机器人缓存的上下文历史 - `reset`、`重置` - 重置机器人缓存的上下文历史
#### Perplexity AI 命令 ##### Perplexity AI 命令
- `ask 问题内容` - 使用 Perplexity AI 进行深度查询(需@机器人) - `ask 问题内容` - 使用 Perplexity AI 进行深度查询(需@机器人)
#### 消息管理命令 ##### 消息管理命令
- `summary`、`/总结` - 总结群聊最近的消息(仅群聊) - `summary`、`/总结` - 总结群聊最近的消息(仅群聊)
- `clearmessages`、`/清除历史` - 从数据库中清除群聊的历史消息记录(仅群聊) - `clearmessages`、`/清除历史` - 从数据库中清除群聊的历史消息记录(仅群聊)
#### 天气和新闻工具 ##### 天气和新闻工具
- `天气预报 城市名`、`预报 城市名` - 查询指定城市未来几天的天气预报 - `天气预报 城市名`、`预报 城市名` - 查询指定城市未来几天的天气预报
- `天气 城市名`、`温度 城市名` - 查询指定城市的当前天气 - `天气 城市名`、`温度 城市名` - 查询指定城市的当前天气
- `新闻` - 获取最新新闻 - `新闻` - 获取最新新闻
#### 决斗系统命令 ##### 决斗系统命令
- `决斗 @用户名` - 发起决斗(仅群聊) - `决斗 @用户名` - 发起决斗(仅群聊)
- `偷袭 @用户名`、`偷分 @用户名` - 偷袭其他玩家(仅群聊) - `偷袭 @用户名`、`偷分 @用户名` - 偷袭其他玩家(仅群聊)
- `决斗排行`、`决斗排名`、`排行榜` - 查看决斗排行榜(仅群聊) - `决斗排行`、`决斗排名`、`排行榜` - 查看决斗排行榜(仅群聊)
@@ -173,17 +187,9 @@ python main.py
- `我的装备`、`查看装备` - 查看自己的装备(仅群聊) - `我的装备`、`查看装备` - 查看自己的装备(仅群聊)
- `改名 旧名称 新名称` - 更改昵称(仅群聊) - `改名 旧名称 新名称` - 更改昵称(仅群聊)
#### 成语系统命令
- `#成语` 或 `?成语` 或 `?成语` - 成语接龙与查询
#### 提醒功能
- `提醒xxxxx` - 用自然语言设置一个提醒
- `查看提醒`、`我的提醒`、`提醒列表` - 查看您设置的所有提醒
- `删除提醒 ID:xxxx`、`取消提醒 all` - 删除指定的(或所有)提醒
## 🎮 游戏功能详解 ## 🎮 游戏功能详解
### 决斗系统 #### 决斗系统
Bubbles 内置了一个有趣的决斗游戏系统,用户可以在群聊中挑战其他成员: Bubbles 内置了一个有趣的决斗游戏系统,用户可以在群聊中挑战其他成员:
@@ -194,11 +200,7 @@ Bubbles 内置了一个有趣的决斗游戏系统,用户可以在群聊中挑
- **查看装备**:使用 `我的装备` 查看自己当前的装备 - **查看装备**:使用 `我的装备` 查看自己当前的装备
- **更改名称**:使用 `改名 旧名称 新名称` 更改自己在决斗系统中的显示名称 - **更改名称**:使用 `改名 旧名称 新名称` 更改自己在决斗系统中的显示名称
### 成语接龙 #### 古灵阁妖精馈赠
使用 `#成语` 来查询成语或参与成语接龙游戏。还可以使用 `?成语` 查询成语的详细释义。
### 古灵阁妖精馈赠
这是一个随机事件系统,机器人会在聊天中随机触发"古灵阁妖精馈赠"事件,为用户提供惊喜奖励。 这是一个随机事件系统,机器人会在聊天中随机触发"古灵阁妖精馈赠"事件,为用户提供惊喜奖励。
@@ -210,7 +212,6 @@ Bubbles-WechatAI/
├── commands/ # 命令系统实现 ├── commands/ # 命令系统实现
├── data/ # 数据文件 ├── data/ # 数据文件
├── function/ # 功能模块 ├── function/ # 功能模块
│ ├── func_chengyu.py # 成语功能
│ ├── func_duel.py # 决斗功能 │ ├── func_duel.py # 决斗功能
│ ├── func_news.py # 新闻功能 │ ├── func_news.py # 新闻功能
│ ├── func_weather.py # 天气功能 │ ├── func_weather.py # 天气功能

View File

@@ -45,10 +45,6 @@ def handle_help(ctx: 'MessageContext', match: Optional[Match]) -> bool:
"- 查看提醒/我的提醒/提醒列表", "- 查看提醒/我的提醒/提醒列表",
"- 删除提醒 [ID]/all", "- 删除提醒 [ID]/all",
"", "",
"【成语】",
"- #成语:接龙",
"- ?成语:查询成语释义",
"",
"【群聊工具】", "【群聊工具】",
"- summary/总结", "- summary/总结",
"- clearmessages/清除历史", "- clearmessages/清除历史",
@@ -567,48 +563,6 @@ def handle_rename(ctx: 'MessageContext', match: Optional[Match]) -> bool:
ctx.send_text("⚠️ 改名失败") ctx.send_text("⚠️ 改名失败")
return False return False
def handle_chengyu(ctx: 'MessageContext', match: Optional[Match]) -> bool:
"""
处理 "成语" 命令
匹配: #成语 或 ?成语
"""
if not match:
return False
flag = match.group(1) # '#' 或 '?'
text = match.group(2) # 成语文本
try:
from function.func_chengyu import cy
if flag == "#": # 接龙
if cy.isChengyu(text):
rsp = cy.getNext(text)
if rsp:
ctx.send_text(rsp)
# 尝试触发馈赠
if ctx.is_group and hasattr(ctx.robot, "goblin_gift_manager"):
ctx.robot.goblin_gift_manager.try_trigger(ctx.msg)
return True
elif flag in ["?", ""]: # 查词
if cy.isChengyu(text):
rsp = cy.getMeaning(text)
if rsp:
ctx.send_text(rsp)
# 尝试触发馈赠
if ctx.is_group and hasattr(ctx.robot, "goblin_gift_manager"):
ctx.robot.goblin_gift_manager.try_trigger(ctx.msg)
return True
except Exception as e:
if ctx.logger:
ctx.logger.error(f"处理成语出错: {e}")
return False
def handle_chitchat(ctx: 'MessageContext', match: Optional[Match]) -> bool: def handle_chitchat(ctx: 'MessageContext', match: Optional[Match]) -> bool:
""" """

View File

@@ -4,7 +4,7 @@ from .handlers import (
handle_help, handle_duel, handle_sneak_attack, handle_duel_rank, handle_help, handle_duel, handle_sneak_attack, handle_duel_rank,
handle_duel_stats, handle_check_equipment, handle_reset_memory, handle_duel_stats, handle_check_equipment, handle_reset_memory,
handle_summary, handle_clear_messages, handle_news_request, handle_summary, handle_clear_messages, handle_news_request,
handle_rename, handle_chengyu, handle_chitchat, handle_insult, handle_rename, handle_chitchat, handle_insult,
handle_perplexity_ask, handle_reminder, handle_list_reminders, handle_delete_reminder, handle_perplexity_ask, handle_reminder, handle_list_reminders, handle_delete_reminder,
handle_weather, handle_weather_forecast handle_weather, handle_weather_forecast
) )
@@ -168,17 +168,6 @@ COMMANDS = [
description="更改昵称" description="更改昵称"
), ),
# ======== 成语系统命令 ========
Command(
name="chengyu",
pattern=re.compile(r"^([#?])(.+)$"),
scope="both", # 群聊和私聊都支持
need_at=False, # 不需要@机器人
priority=60, # 优先级较低
handler=handle_chengyu,
description="成语接龙与查询"
),
# ======== 提醒功能 ======== # ======== 提醒功能 ========
Command( Command(
name="reminder", name="reminder",

File diff suppressed because it is too large Load Diff

View File

@@ -1,89 +0,0 @@
# -*- coding: utf-8 -*-
import os
import random
import logging
import pandas as pd
# 获取模块级 logger
logger = logging.getLogger(__name__)
class Chengyu(object):
def __init__(self) -> None:
root = os.path.dirname(os.path.abspath(__file__))
self.df = pd.read_csv(f"{root}/chengyu.csv", delimiter="\t")
self.cys, self.zis, self.yins = self._build_data()
def _build_data(self):
df = self.df.copy()
df["shouzi"] = df["chengyu"].apply(lambda x: x[0])
df["mozi"] = df["chengyu"].apply(lambda x: x[-1])
df["shouyin"] = df["pingyin"].apply(lambda x: x.split(" ")[0])
df["moyin"] = df["pingyin"].apply(lambda x: x.split(" ")[-1])
cys = dict(zip(df["chengyu"], df["moyin"]))
zis = df.groupby("shouzi").agg({"chengyu": set})["chengyu"].to_dict()
yins = df.groupby("shouyin").agg({"chengyu": set})["chengyu"].to_dict()
return cys, zis, yins
def isChengyu(self, cy: str) -> bool:
return self.cys.get(cy, None) is not None
def getNext(self, cy: str, tongyin: bool = True) -> str:
"""获取下一个成语
cy: 当前成语
tongyin: 是否允许同音字
"""
zi = cy[-1]
ansers = list(self.zis.get(zi, {}))
try:
ansers.remove(cy) # 移除当前成语
except Exception as e:
pass # Just ignore...
if ansers:
return random.choice(ansers)
# 如果找不到同字,允许同音
if tongyin:
yin = self.cys.get(cy)
ansers = list(self.yins.get(yin, {}))
try:
ansers.remove(cy) # 移除当前成语
except Exception as e:
pass # Just ignore...
if ansers:
return random.choice(ansers)
return None
def getMeaning(self, cy: str) -> str:
ress = self.df[self.df["chengyu"] == cy].to_dict(orient="records")
if ress:
res = ress[0]
rsp = res["chengyu"] + "\n" + res["pingyin"] + "\n" + res["jieshi"]
if res["chuchu"] and res["chuchu"] != "":
rsp += "\n出处:" + res["chuchu"]
if res["lizi"] and res["lizi"] != "":
rsp += "\n例子:" + res["lizi"]
return rsp
return None
cy = Chengyu()
if __name__ == "__main__":
# 设置测试用的日志配置
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(name)s - %(message)s'
)
answer = cy.getNext("便宜行事")
logger.info(answer)

View File

@@ -8,6 +8,7 @@ from collections import deque
import sqlite3 # 添加sqlite3模块 import sqlite3 # 添加sqlite3模块
import os # 用于处理文件路径 import os # 用于处理文件路径
from function.func_xml_process import XmlProcessor # 导入XmlProcessor from function.func_xml_process import XmlProcessor # 导入XmlProcessor
from commands.registry import COMMANDS # 导入命令列表
class MessageSummary: class MessageSummary:
"""消息总结功能类 (使用SQLite持久化) """消息总结功能类 (使用SQLite持久化)
@@ -302,6 +303,7 @@ class MessageSummary:
def process_message_from_wxmsg(self, msg, wcf, all_contacts, bot_wxid=None): def process_message_from_wxmsg(self, msg, wcf, all_contacts, bot_wxid=None):
"""从微信消息对象中处理并记录与总结相关的文本消息 """从微信消息对象中处理并记录与总结相关的文本消息
使用 XmlProcessor 提取用户实际输入的新内容或卡片标题。 使用 XmlProcessor 提取用户实际输入的新内容或卡片标题。
会自动跳过所有匹配 commands.registry 中定义的命令的消息。
Args: Args:
msg: 微信消息对象(WxMsg) msg: 微信消息对象(WxMsg)
@@ -318,42 +320,59 @@ class MessageSummary:
return return
chat_id = msg.roomid chat_id = msg.roomid
# 原始消息内容用于命令和@匹配
original_content = msg.content.strip()
# 2. 检查是否 @机器人 (如果提供了 bot_wxid) # 2. 预先判断消息是否 @机器人 (如果提供了 bot_wxid)
original_content = msg.content # 获取原始content用于检测@和后续处理 is_at_message = False
bot_name_in_group = "" # 初始化为空字符串
if bot_wxid: if bot_wxid:
# 获取机器人在群里的昵称
bot_name_in_group = wcf.get_alias_in_chatroom(bot_wxid, chat_id) bot_name_in_group = wcf.get_alias_in_chatroom(bot_wxid, chat_id)
if not bot_name_in_group: if not bot_name_in_group:
# 如果获取不到群昵称,使用通讯录中的名称或默认名 bot_name_in_group = all_contacts.get(bot_wxid, "泡泡") # 使用通讯录或默认名
bot_name_in_group = all_contacts.get(bot_wxid, "泡泡") # 默认使用"泡泡"
# 优化@检查:检查原始文本中是否包含 "@机器人昵称" (考虑特殊空格)
# 检查消息中任意位置是否@机器人(含特殊空格\u2005 mention_pattern_exact = f"@{re.escape(bot_name_in_group)}"
mention_pattern = f"@{bot_name_in_group}" mention_pattern_space = rf"@{re.escape(bot_name_in_group)}(\u2005|\s|$)"
if mention_pattern in original_content: if mention_pattern_exact in original_content or re.search(mention_pattern_space, original_content):
# 消息提及了机器人,不记录 is_at_message = True
self.LOG.debug(f"跳过包含@机器人的消息: {original_content[:30]}...")
return
# 使用正则表达式匹配更复杂的情况(考虑特殊空格)
if re.search(rf"@{re.escape(bot_name_in_group)}(\u2005|\s|$)", original_content):
self.LOG.debug(f"通过正则跳过包含@机器人的消息: {original_content[:30]}...")
return
# 3. 使用 XmlProcessor 提取消息详情 # 3. 检查消息是否匹配任何已定义的命令
for command in COMMANDS:
# 只关心在群聊生效的命令
if command.scope in ["group", "both"]:
match = command.pattern.search(original_content)
if match:
# 如果命令需要@,但消息实际上没有@机器人,则这不是一个有效的命令调用,继续检查下一个命令
if command.need_at and not is_at_message:
continue
# 如果命令不需要@,或者需要@且消息确实@了机器人,那么这就是一个命令调用,跳过记录
self.LOG.debug(f"跳过匹配命令 '{command.name}' 的消息: {original_content[:30]}...")
return # 直接返回,不记录此消息
# 4. 如果消息没有匹配任何命令,但确实@了机器人,也跳过记录
# (防止记录类似 "你好 @机器人" 这样的非命令交互)
if is_at_message:
self.LOG.debug(f"跳过非命令但包含@机器人的消息: {original_content[:30]}...")
return
# 5. 使用 XmlProcessor 提取消息详情 (如果消息不是命令且没有@机器人)
try: try:
extracted_data = self.xml_processor.extract_quoted_message(msg) # 传入原始 msg 对象
extracted_data = self.xml_processor.extract_quoted_message(msg)
except Exception as e: except Exception as e:
self.LOG.error(f"使用XmlProcessor提取消息内容时出错 (msg.id={msg.id}): {e}") self.LOG.error(f"使用XmlProcessor提取消息内容时出错 (msg.id={msg.id}): {e}")
return # 出错时,保守起见,不记录 return # 出错时,保守起见,不记录
# 4. 确定要记录的内容 (content_to_record) # 6. 确定要记录的内容 (content_to_record)
content_to_record = "" content_to_record = ""
source_info = "未知来源" source_info = "未知来源"
# 优先使用提取到的新内容 (来自回复或普通文本或<title>) # 优先使用提取到的新内容 (来自回复或普通文本或<title>)
if extracted_data.get("new_content", "").strip(): temp_new_content = extracted_data.get("new_content", "").strip()
content_to_record = extracted_data["new_content"].strip() if temp_new_content:
content_to_record = temp_new_content
source_info = "来自 new_content (回复/文本/标题)" source_info = "来自 new_content (回复/文本/标题)"
# 如果是引用类型消息,添加引用标记和引用内容的简略信息 # 如果是引用类型消息,添加引用标记和引用内容的简略信息
@@ -396,6 +415,7 @@ class MessageSummary:
else: else:
# 仅添加引用内容,将新内容放在前面,引用内容放在后面 # 仅添加引用内容,将新内容放在前面,引用内容放在后面
content_to_record = f"{content_to_record} 【回复:{quoted_content}" content_to_record = f"{content_to_record} 【回复:{quoted_content}"
# 其次,如果新内容为空,但这是一个卡片且有标题,则使用卡片标题 # 其次,如果新内容为空,但这是一个卡片且有标题,则使用卡片标题
elif extracted_data.get("is_card") and extracted_data.get("card_title", "").strip(): elif extracted_data.get("is_card") and extracted_data.get("card_title", "").strip():
# 卡片消息使用固定格式,包含标题和描述 # 卡片消息使用固定格式,包含标题和描述
@@ -438,17 +458,20 @@ class MessageSummary:
content_to_record = f"{card_content}" content_to_record = f"{card_content}"
source_info = "来自 卡片(标题+描述)" source_info = "来自 卡片(标题+描述)"
# 普通文本消息的保底处理
elif msg.type == 0x01 and not ("<" in original_content and ">" in original_content): # 普通文本消息的保底处理 (已在前面排除了命令和@消息)
content_to_record = original_content.strip() elif msg.type == 0x01 and not ("<" in msg.content and ">" in msg.content): # 再次确认是纯文本
source_info = "来自 纯文本消息" content_to_record = msg.content.strip() # 使用原始纯文本
source_info = "来自 纯文本消息"
# 5. 如果最终没有提取到有效内容,则不记录
# 7. 如果最终没有提取到有效内容,则不记录
if not content_to_record: if not content_to_record:
self.LOG.debug(f"XmlProcessor未能提取到有效文本内容跳过记录 (msg.id={msg.id}) - Quote: {extracted_data.get('has_quote', False)}, IsCard: {extracted_data.get('is_card', False)}") # Debug日志级别调整为更详细说明为何没有内容
self.LOG.debug(f"未能提取到有效文本内容用于记录,跳过 (msg.id={msg.id}) - IsCard: {extracted_data.get('is_card', False)}, HasQuote: {extracted_data.get('has_quote', False)}")
return return
# 6. 获取发送者昵称 # 8. 获取发送者昵称
sender_name = wcf.get_alias_in_chatroom(msg.sender, msg.roomid) sender_name = wcf.get_alias_in_chatroom(msg.sender, msg.roomid)
if not sender_name: # 如果没有群昵称,尝试获取微信昵称 if not sender_name: # 如果没有群昵称,尝试获取微信昵称
sender_data = all_contacts.get(msg.sender) sender_data = all_contacts.get(msg.sender)
@@ -457,6 +480,6 @@ class MessageSummary:
# 获取当前时间(只用于记录,不再打印) # 获取当前时间(只用于记录,不再打印)
current_time_str = time.strftime("%H:%M", time.localtime()) current_time_str = time.strftime("%H:%M", time.localtime())
# 8. 记录提取到的有效内容 # 9. 记录提取到的有效内容
self.LOG.debug(f"记录消息 (来源: {source_info}): '[{current_time_str}]{sender_name}: {content_to_record}' (来自 msg.id={msg.id})") self.LOG.debug(f"记录消息 (来源: {source_info}): '[{current_time_str}]{sender_name}: {content_to_record}' (来自 msg.id={msg.id})")
self.record_message(chat_id, sender_name, content_to_record, current_time_str) self.record_message(chat_id, sender_name, content_to_record, current_time_str)

View File

@@ -21,7 +21,6 @@ from ai_providers.ai_ollama import Ollama
from ai_providers.ai_chatgpt import ChatGPT from ai_providers.ai_chatgpt import ChatGPT
from ai_providers.ai_deepseek import DeepSeek from ai_providers.ai_deepseek import DeepSeek
from ai_providers.ai_perplexity import Perplexity from ai_providers.ai_perplexity import Perplexity
from function.func_chengyu import cy
from function.func_weather import Weather from function.func_weather import Weather
from function.func_news import News from function.func_news import News
from ai_providers.ai_tigerbot import TigerBot from ai_providers.ai_tigerbot import TigerBot
@@ -250,8 +249,6 @@ class Robot(Job):
# 调用handle_chitchat函数处理闲聊 # 调用handle_chitchat函数处理闲聊
handle_chitchat(ctx, None) handle_chitchat(ctx, None)
else: else:
# 处理成语等不需要@的功能
# 成语功能已经通过命令路由器处理,这里不需要再处理
pass pass
# 5.4 私聊消息,未被命令处理,进行闲聊 # 5.4 私聊消息,未被命令处理,进行闲聊