mirror of
https://github.com/Zippland/Bubbles.git
synced 2026-01-19 01:21:15 +08:00
新增对引用图片的处理逻辑,包括提取引用图片信息、下载图片并调用 ChatGPT 进行分析,同时优化了 XML 处理器以支持引用图片的识别和处理。
This commit is contained in:
@@ -580,6 +580,82 @@ def handle_chitchat(ctx: 'MessageContext', match: Optional[Match]) -> bool:
|
||||
ctx.send_text("抱歉,我现在无法进行对话。")
|
||||
return False
|
||||
|
||||
# ---- 处理引用图片情况 ----
|
||||
if getattr(ctx, 'is_quoted_image', False):
|
||||
ctx.logger.info("检测到引用图片消息,尝试处理图片内容...")
|
||||
|
||||
import os
|
||||
from ai_providers.ai_chatgpt import ChatGPT
|
||||
|
||||
# 确保是 ChatGPT 类型且支持图片处理
|
||||
support_vision = False
|
||||
if isinstance(chat_model, ChatGPT):
|
||||
if hasattr(chat_model, 'support_vision') and chat_model.support_vision:
|
||||
support_vision = True
|
||||
else:
|
||||
# 检查模型名称判断是否支持视觉
|
||||
if hasattr(chat_model, 'model'):
|
||||
model_name = getattr(chat_model, 'model', '')
|
||||
support_vision = model_name == "gpt-4.1-mini" or model_name == "gpt-4o" or "-vision" in model_name
|
||||
|
||||
if not support_vision:
|
||||
ctx.send_text("抱歉,当前 AI 模型不支持处理图片。请联系管理员配置支持视觉的模型 (如 gpt-4-vision-preview、gpt-4o 等)。")
|
||||
return True
|
||||
|
||||
# 下载图片并处理
|
||||
try:
|
||||
# 创建临时目录
|
||||
temp_dir = "temp/image_cache"
|
||||
os.makedirs(temp_dir, exist_ok=True)
|
||||
|
||||
# 下载图片
|
||||
ctx.logger.info(f"正在下载引用图片: msg_id={ctx.quoted_msg_id}")
|
||||
image_path = ctx.wcf.download_image(
|
||||
id=ctx.quoted_msg_id,
|
||||
extra=ctx.quoted_image_extra,
|
||||
dir=temp_dir,
|
||||
timeout=30
|
||||
)
|
||||
|
||||
if not image_path or not os.path.exists(image_path):
|
||||
ctx.logger.error(f"图片下载失败: {image_path}")
|
||||
ctx.send_text("抱歉,无法下载图片进行分析。")
|
||||
return True
|
||||
|
||||
ctx.logger.info(f"图片下载成功: {image_path},准备分析...")
|
||||
|
||||
# 调用 ChatGPT 分析图片
|
||||
try:
|
||||
# 根据用户的提问构建 prompt
|
||||
prompt = ctx.text
|
||||
if not prompt or prompt.strip() == "":
|
||||
prompt = "请详细描述这张图片中的内容"
|
||||
|
||||
# 调用图片分析函数
|
||||
response = chat_model.get_image_description(image_path, prompt)
|
||||
ctx.send_text(response)
|
||||
|
||||
ctx.logger.info("图片分析完成并已发送回复")
|
||||
except Exception as e:
|
||||
ctx.logger.error(f"分析图片时出错: {e}")
|
||||
ctx.send_text(f"分析图片时出错: {str(e)}")
|
||||
|
||||
# 清理临时图片
|
||||
try:
|
||||
if os.path.exists(image_path):
|
||||
os.remove(image_path)
|
||||
ctx.logger.info(f"临时图片已删除: {image_path}")
|
||||
except Exception as e:
|
||||
ctx.logger.error(f"删除临时图片出错: {e}")
|
||||
|
||||
return True # 已处理,不执行后续的普通文本处理流程
|
||||
|
||||
except Exception as e:
|
||||
ctx.logger.error(f"处理引用图片过程中出错: {e}")
|
||||
ctx.send_text(f"处理图片时发生错误: {str(e)}")
|
||||
return True # 已处理,即使出错也不执行后续普通文本处理
|
||||
# ---- 引用图片处理结束 ----
|
||||
|
||||
# 获取消息内容
|
||||
content = ctx.text
|
||||
sender_name = ctx.sender_name
|
||||
@@ -587,7 +663,6 @@ def handle_chitchat(ctx: 'MessageContext', match: Optional[Match]) -> bool:
|
||||
# 使用XML处理器格式化消息
|
||||
if ctx.robot and hasattr(ctx.robot, "xml_processor"):
|
||||
# 创建格式化的聊天内容(带有引用消息等)
|
||||
# 原始代码中是从xml_processor获取的
|
||||
if ctx.is_group:
|
||||
# 处理群聊消息
|
||||
msg_data = ctx.robot.xml_processor.extract_quoted_message(ctx.msg)
|
||||
|
||||
@@ -127,11 +127,47 @@ class XmlProcessor:
|
||||
# 提取refermsg内容
|
||||
refer_data = self.extract_refermsg(msg.content)
|
||||
result["quoted_sender"] = refer_data.get("sender", "")
|
||||
result["quoted_content"] = refer_data.get("content", "")
|
||||
|
||||
# 新增代码开始
|
||||
is_quoted_image = False
|
||||
quoted_msg_id = None
|
||||
quoted_image_extra = None
|
||||
|
||||
# 尝试从原始消息内容中解析 refermsg 结构,获取引用类型和svrid
|
||||
refermsg_match = re.search(r'<refermsg>(.*?)</refermsg>', msg.content, re.DOTALL)
|
||||
if refermsg_match:
|
||||
refermsg_inner_xml = refermsg_match.group(1)
|
||||
refer_type_match = re.search(r'<type>(\d+)</type>', refermsg_inner_xml)
|
||||
refer_svrid_match = re.search(r'<svrid>(\d+)</svrid>', refermsg_inner_xml)
|
||||
|
||||
if refer_type_match and refer_type_match.group(1) == '3' and refer_svrid_match:
|
||||
# 确认是引用图片 (type=3)
|
||||
is_quoted_image = True
|
||||
try:
|
||||
quoted_msg_id = int(refer_svrid_match.group(1))
|
||||
# refer_data["raw_content"] 应该就是解码后的 <msg><img...> XML
|
||||
quoted_image_extra = refer_data.get("raw_content", "")
|
||||
self.logger.info(f"识别到引用图片消息,原消息ID: {quoted_msg_id}")
|
||||
except ValueError:
|
||||
self.logger.error(f"无法将svrid '{refer_svrid_match.group(1)}' 转换为整数")
|
||||
except Exception as e:
|
||||
self.logger.error(f"提取引用图片信息时出错: {e}")
|
||||
|
||||
if is_quoted_image and quoted_msg_id is not None and quoted_image_extra:
|
||||
# 如果是引用图片,更新 result 字典
|
||||
result["media_type"] = "引用图片" # 更新媒体类型
|
||||
result["quoted_msg_id"] = quoted_msg_id # 存储原图片消息 ID
|
||||
result["quoted_image_extra"] = quoted_image_extra # 存储原图片消息 XML (用于下载)
|
||||
result["quoted_content"] = "[引用的图片]" # 使用占位符文本
|
||||
result["quoted_is_card"] = False # 明确不是卡片
|
||||
else:
|
||||
# 原有的代码继续
|
||||
result["quoted_content"] = refer_data.get("content", "")
|
||||
# 新增代码结束
|
||||
|
||||
# 从raw_content尝试解析被引用内容的卡片信息
|
||||
raw_content = refer_data.get("raw_content", "")
|
||||
if raw_content and "<appmsg" in raw_content:
|
||||
if raw_content and "<appmsg" in raw_content and not is_quoted_image: # 添加了 not is_quoted_image 条件
|
||||
quoted_card_details = self.extract_card_details(raw_content)
|
||||
|
||||
# 将引用的卡片详情存储到quoted_前缀的字段
|
||||
@@ -150,7 +186,7 @@ class XmlProcessor:
|
||||
self.logger.info(f"成功从引用内容中提取卡片信息: {quoted_card_details['card_type']}")
|
||||
else:
|
||||
# 如果未发现卡片特征,尝试fallback方法
|
||||
if not result["quoted_content"]:
|
||||
if not result["quoted_content"] and not is_quoted_image: # 添加了 not is_quoted_image 条件
|
||||
fallback_content = self.extract_quoted_fallback(msg.content)
|
||||
if fallback_content:
|
||||
if fallback_content.startswith("引用内容:") or fallback_content.startswith("相关内容:"):
|
||||
@@ -285,11 +321,47 @@ class XmlProcessor:
|
||||
# 提取refermsg内容
|
||||
refer_data = self.extract_private_refermsg(msg.content)
|
||||
result["quoted_sender"] = refer_data.get("sender", "")
|
||||
result["quoted_content"] = refer_data.get("content", "")
|
||||
|
||||
# 新增代码开始
|
||||
is_quoted_image = False
|
||||
quoted_msg_id = None
|
||||
quoted_image_extra = None
|
||||
|
||||
# 尝试从原始消息内容中解析 refermsg 结构,获取引用类型和svrid
|
||||
refermsg_match = re.search(r'<refermsg>(.*?)</refermsg>', msg.content, re.DOTALL)
|
||||
if refermsg_match:
|
||||
refermsg_inner_xml = refermsg_match.group(1)
|
||||
refer_type_match = re.search(r'<type>(\d+)</type>', refermsg_inner_xml)
|
||||
refer_svrid_match = re.search(r'<svrid>(\d+)</svrid>', refermsg_inner_xml)
|
||||
|
||||
if refer_type_match and refer_type_match.group(1) == '3' and refer_svrid_match:
|
||||
# 确认是引用图片 (type=3)
|
||||
is_quoted_image = True
|
||||
try:
|
||||
quoted_msg_id = int(refer_svrid_match.group(1))
|
||||
# refer_data["raw_content"] 应该就是解码后的 <msg><img...> XML
|
||||
quoted_image_extra = refer_data.get("raw_content", "")
|
||||
self.logger.info(f"识别到引用图片消息,原消息ID: {quoted_msg_id}")
|
||||
except ValueError:
|
||||
self.logger.error(f"无法将svrid '{refer_svrid_match.group(1)}' 转换为整数")
|
||||
except Exception as e:
|
||||
self.logger.error(f"提取引用图片信息时出错: {e}")
|
||||
|
||||
if is_quoted_image and quoted_msg_id is not None and quoted_image_extra:
|
||||
# 如果是引用图片,更新 result 字典
|
||||
result["media_type"] = "引用图片" # 更新媒体类型
|
||||
result["quoted_msg_id"] = quoted_msg_id # 存储原图片消息 ID
|
||||
result["quoted_image_extra"] = quoted_image_extra # 存储原图片消息 XML (用于下载)
|
||||
result["quoted_content"] = "[引用的图片]" # 使用占位符文本
|
||||
result["quoted_is_card"] = False # 明确不是卡片
|
||||
else:
|
||||
# 原有的代码继续
|
||||
result["quoted_content"] = refer_data.get("content", "")
|
||||
# 新增代码结束
|
||||
|
||||
# 从raw_content尝试解析被引用内容的卡片信息
|
||||
raw_content = refer_data.get("raw_content", "")
|
||||
if raw_content and "<appmsg" in raw_content:
|
||||
if raw_content and "<appmsg" in raw_content and not is_quoted_image: # 添加了 not is_quoted_image 条件
|
||||
quoted_card_details = self.extract_card_details(raw_content)
|
||||
|
||||
# 将引用的卡片详情存储到quoted_前缀的字段
|
||||
@@ -308,7 +380,7 @@ class XmlProcessor:
|
||||
self.logger.info(f"成功从引用内容中提取卡片信息: {quoted_card_details['card_type']}")
|
||||
else:
|
||||
# 如果未发现卡片特征,尝试fallback方法
|
||||
if not result["quoted_content"]:
|
||||
if not result["quoted_content"] and not is_quoted_image: # 添加了 not is_quoted_image 条件
|
||||
fallback_content = self.extract_quoted_fallback(msg.content)
|
||||
if fallback_content:
|
||||
if fallback_content.startswith("引用内容:") or fallback_content.startswith("相关内容:"):
|
||||
|
||||
22
robot.py
22
robot.py
@@ -541,6 +541,11 @@ class Robot(Job):
|
||||
is_at_bot = False
|
||||
pure_text = msg.content # 默认使用原始内容
|
||||
|
||||
# 初始化引用图片相关属性
|
||||
is_quoted_image = False
|
||||
quoted_msg_id = None
|
||||
quoted_image_extra = None
|
||||
|
||||
# 处理引用消息等特殊情况
|
||||
if msg.type == 49 and ("<title>" in msg.content or "<appmsg" in msg.content):
|
||||
# 尝试提取引用消息中的文本
|
||||
@@ -564,6 +569,15 @@ class Robot(Job):
|
||||
if is_group and pure_text.startswith(f"@{self.allContacts.get(self.wxid, '')}"):
|
||||
is_at_bot = True
|
||||
pure_text = re.sub(r"^@.*?[\u2005|\s]", "", pure_text).strip()
|
||||
|
||||
# 检查并提取图片引用信息
|
||||
if msg_data and msg_data.get("media_type") == "引用图片" and \
|
||||
msg_data.get("quoted_msg_id") and \
|
||||
msg_data.get("quoted_image_extra"):
|
||||
is_quoted_image = True
|
||||
quoted_msg_id = msg_data["quoted_msg_id"]
|
||||
quoted_image_extra = msg_data["quoted_image_extra"]
|
||||
self.LOG.info(f"预处理已提取引用图片信息: msg_id={quoted_msg_id}")
|
||||
|
||||
# 处理文本消息
|
||||
elif msg.type == 1: # 文本消息
|
||||
@@ -589,9 +603,15 @@ class Robot(Job):
|
||||
is_at_bot=is_at_bot or (is_group and msg.is_at(self.wxid)), # 确保is_at_bot正确
|
||||
)
|
||||
|
||||
# 将图片引用信息添加到 ctx
|
||||
setattr(ctx, 'is_quoted_image', is_quoted_image)
|
||||
if is_quoted_image:
|
||||
setattr(ctx, 'quoted_msg_id', quoted_msg_id)
|
||||
setattr(ctx, 'quoted_image_extra', quoted_image_extra)
|
||||
|
||||
# 获取发送者昵称
|
||||
ctx.sender_name = ctx.get_sender_alias_or_name()
|
||||
|
||||
self.LOG.debug(f"预处理消息: text='{ctx.text}', is_group={ctx.is_group}, is_at_bot={ctx.is_at_bot}, sender='{ctx.sender_name}'")
|
||||
self.LOG.debug(f"预处理消息: text='{ctx.text}', is_group={ctx.is_group}, is_at_bot={ctx.is_at_bot}, sender='{ctx.sender_name}', is_quoted_image={is_quoted_image}")
|
||||
return ctx
|
||||
|
||||
|
||||
574
wcf_doc.txt
Normal file
574
wcf_doc.txt
Normal file
@@ -0,0 +1,574 @@
|
||||
wcferry.client
|
||||
==============
|
||||
|
||||
.. py:module:: wcferry.client
|
||||
|
||||
|
||||
Classes
|
||||
-------
|
||||
|
||||
.. autoapisummary::
|
||||
|
||||
wcferry.client.Wcf
|
||||
|
||||
|
||||
Module Contents
|
||||
---------------
|
||||
|
||||
.. py:class:: Wcf(host: str = None, port: int = 10086, debug: bool = True, block: bool = True)
|
||||
|
||||
WeChatFerry, 一个玩微信的工具。
|
||||
|
||||
:param host: `wcferry` RPC 服务器地址,默认本地启动;也可以指定地址连接远程服务
|
||||
:type host: str
|
||||
:param port: `wcferry` RPC 服务器端口,默认为 10086,接收消息会占用 `port+1` 端口
|
||||
:type port: int
|
||||
:param debug: 是否开启调试模式(仅本地启动有效)
|
||||
:type debug: bool
|
||||
:param block: 是否阻塞等待微信登录,不阻塞的话可以手动获取登录二维码主动登录
|
||||
:type block: bool
|
||||
|
||||
.. attribute:: contacts
|
||||
|
||||
联系人缓存,调用 `get_contacts` 后更新
|
||||
|
||||
:type: list
|
||||
|
||||
|
||||
.. py:method:: accept_new_friend(v3: str, v4: str, scene: int = 30) -> int
|
||||
|
||||
通过好友申请
|
||||
|
||||
:param v3: 加密用户名 (好友申请消息里 v3 开头的字符串)
|
||||
:type v3: str
|
||||
:param v4: Ticket (好友申请消息里 v4 开头的字符串)
|
||||
:type v4: str
|
||||
:param scene: 申请方式 (好友申请消息里的 scene); 为了兼容旧接口,默认为扫码添加 (30)
|
||||
|
||||
:returns: 1 为成功,其他失败
|
||||
:rtype: int
|
||||
|
||||
|
||||
|
||||
.. py:method:: add_chatroom_members(roomid: str, wxids: str) -> int
|
||||
|
||||
添加群成员
|
||||
|
||||
:param roomid: 待加群的 id
|
||||
:type roomid: str
|
||||
:param wxids: 要加到群里的 wxid,多个用逗号分隔
|
||||
:type wxids: str
|
||||
|
||||
:returns: 1 为成功,其他失败
|
||||
:rtype: int
|
||||
|
||||
|
||||
|
||||
.. py:method:: cleanup() -> None
|
||||
|
||||
关闭连接,回收资源
|
||||
|
||||
|
||||
|
||||
.. py:method:: decrypt_image(src: str, dir: str) -> str
|
||||
|
||||
解密图片。这方法别直接调用,下载图片使用 `download_image`。
|
||||
|
||||
:param src: 加密的图片路径
|
||||
:type src: str
|
||||
:param dir: 保存图片的目录
|
||||
:type dir: str
|
||||
|
||||
:returns: 解密图片的保存路径
|
||||
:rtype: str
|
||||
|
||||
|
||||
|
||||
.. py:method:: del_chatroom_members(roomid: str, wxids: str) -> int
|
||||
|
||||
删除群成员
|
||||
|
||||
:param roomid: 群的 id
|
||||
:type roomid: str
|
||||
:param wxids: 要删除成员的 wxid,多个用逗号分隔
|
||||
:type wxids: str
|
||||
|
||||
:returns: 1 为成功,其他失败
|
||||
:rtype: int
|
||||
|
||||
|
||||
|
||||
.. py:method:: disable_recv_msg() -> int
|
||||
|
||||
停止接收消息
|
||||
|
||||
|
||||
|
||||
.. py:method:: download_attach(id: int, thumb: str, extra: str) -> int
|
||||
|
||||
下载附件(图片、视频、文件)。这方法别直接调用,下载图片使用 `download_image`。
|
||||
|
||||
:param id: 消息中 id
|
||||
:type id: int
|
||||
:param thumb: 消息中的 thumb
|
||||
:type thumb: str
|
||||
:param extra: 消息中的 extra
|
||||
:type extra: str
|
||||
|
||||
:returns: 0 为成功, 其他失败。
|
||||
:rtype: int
|
||||
|
||||
|
||||
|
||||
.. py:method:: download_image(id: int, extra: str, dir: str, timeout: int = 30) -> str
|
||||
|
||||
下载图片
|
||||
|
||||
:param id: 消息中 id
|
||||
:type id: int
|
||||
:param extra: 消息中的 extra
|
||||
:type extra: str
|
||||
:param dir: 存放图片的目录(目录不存在会出错)
|
||||
:type dir: str
|
||||
:param timeout: 超时时间(秒)
|
||||
:type timeout: int
|
||||
|
||||
:returns: 成功返回存储路径;空字符串为失败,原因见日志。
|
||||
:rtype: str
|
||||
|
||||
|
||||
|
||||
.. py:method:: download_video(id: int, thumb: str, dir: str, timeout: int = 30) -> str
|
||||
|
||||
下载视频
|
||||
|
||||
:param id: 消息中 id
|
||||
:type id: int
|
||||
:param thumb: 消息中的 thumb(即视频的封面图)
|
||||
:type thumb: str
|
||||
:param dir: 存放视频的目录(目录不存在会出错)
|
||||
:type dir: str
|
||||
:param timeout: 超时时间(秒)
|
||||
:type timeout: int
|
||||
|
||||
:returns: 成功返回存储路径;空字符串为失败,原因见日志。
|
||||
:rtype: str
|
||||
|
||||
|
||||
|
||||
.. py:method:: enable_receiving_msg(pyq=False) -> bool
|
||||
|
||||
允许接收消息,成功后通过 `get_msg` 读取消息
|
||||
|
||||
|
||||
|
||||
.. py:method:: enable_recv_msg(callback: Callable[[wcferry.wxmsg.WxMsg], None] = None) -> bool
|
||||
|
||||
(不建议使用)设置接收消息回调,消息量大时可能会丢失消息
|
||||
|
||||
.. deprecated:: 3.7.0.30.13
|
||||
|
||||
|
||||
|
||||
.. py:method:: forward_msg(id: int, receiver: str) -> int
|
||||
|
||||
转发消息。可以转发文本、图片、表情、甚至各种 XML;
|
||||
语音也行,不过效果嘛,自己验证吧。
|
||||
|
||||
:param id: 待转发消息的 id
|
||||
:type id: str
|
||||
:param receiver: 消息接收者,wxid 或者 roomid
|
||||
:type receiver: str
|
||||
|
||||
:returns: 1 为成功,其他失败
|
||||
:rtype: int
|
||||
|
||||
|
||||
|
||||
.. py:method:: get_alias_in_chatroom(wxid: str, roomid: str) -> str
|
||||
|
||||
获取群名片
|
||||
|
||||
:param wxid: wxid
|
||||
:type wxid: str
|
||||
:param roomid: 群的 id
|
||||
:type roomid: str
|
||||
|
||||
:returns: 群名片
|
||||
:rtype: str
|
||||
|
||||
|
||||
|
||||
.. py:method:: get_audio_msg(id: int, dir: str, timeout: int = 3) -> str
|
||||
|
||||
获取语音消息并转成 MP3
|
||||
:param id: 语音消息 id
|
||||
:type id: int
|
||||
:param dir: MP3 保存目录(目录不存在会出错)
|
||||
:type dir: str
|
||||
:param timeout: 超时时间(秒)
|
||||
:type timeout: int
|
||||
|
||||
:returns: 成功返回存储路径;空字符串为失败,原因见日志。
|
||||
:rtype: str
|
||||
|
||||
|
||||
|
||||
.. py:method:: get_chatroom_members(roomid: str) -> Dict
|
||||
|
||||
获取群成员
|
||||
|
||||
:param roomid: 群的 id
|
||||
:type roomid: str
|
||||
|
||||
:returns: 群成员列表: {wxid1: 昵称1, wxid2: 昵称2, ...}
|
||||
:rtype: Dict
|
||||
|
||||
|
||||
|
||||
.. py:method:: get_contacts() -> List[Dict]
|
||||
|
||||
获取完整通讯录
|
||||
|
||||
|
||||
|
||||
.. py:method:: get_dbs() -> List[str]
|
||||
|
||||
获取所有数据库
|
||||
|
||||
|
||||
|
||||
.. py:method:: get_friends() -> List[Dict]
|
||||
|
||||
获取好友列表
|
||||
|
||||
|
||||
|
||||
.. py:method:: get_info_by_wxid(wxid: str) -> dict
|
||||
|
||||
通过 wxid 查询微信号昵称等信息
|
||||
|
||||
:param wxid: 联系人 wxid
|
||||
:type wxid: str
|
||||
|
||||
:returns: {wxid, code, name, gender}
|
||||
:rtype: dict
|
||||
|
||||
|
||||
|
||||
.. py:method:: get_msg(block=True) -> wcferry.wxmsg.WxMsg
|
||||
|
||||
从消息队列中获取消息
|
||||
|
||||
:param block: 是否阻塞,默认阻塞
|
||||
:type block: bool
|
||||
|
||||
:returns: 微信消息
|
||||
:rtype: WxMsg
|
||||
|
||||
:raises Empty: 如果阻塞并且超时,抛出空异常,需要用户自行捕获
|
||||
|
||||
|
||||
|
||||
.. py:method:: get_msg_types() -> Dict
|
||||
|
||||
获取所有消息类型
|
||||
|
||||
|
||||
|
||||
.. py:method:: get_ocr_result(extra: str, timeout: int = 2) -> str
|
||||
|
||||
获取 OCR 结果。鸡肋,需要图片能自动下载;通过下载接口下载的图片无法识别。
|
||||
|
||||
:param extra: 待识别的图片路径,消息里的 extra
|
||||
:type extra: str
|
||||
|
||||
:returns: OCR 结果
|
||||
:rtype: str
|
||||
|
||||
|
||||
|
||||
.. py:method:: get_qrcode() -> str
|
||||
|
||||
获取登录二维码,已经登录则返回空字符串
|
||||
|
||||
|
||||
|
||||
.. py:method:: get_self_wxid() -> str
|
||||
|
||||
获取登录账户的 wxid
|
||||
|
||||
|
||||
|
||||
.. py:method:: get_tables(db: str) -> List[Dict]
|
||||
|
||||
获取 db 中所有表
|
||||
|
||||
:param db: 数据库名(可通过 `get_dbs` 查询)
|
||||
:type db: str
|
||||
|
||||
:returns: `db` 下的所有表名及对应建表语句
|
||||
:rtype: List[Dict]
|
||||
|
||||
|
||||
|
||||
.. py:method:: get_user_info() -> Dict
|
||||
|
||||
获取登录账号个人信息
|
||||
|
||||
|
||||
|
||||
.. py:method:: invite_chatroom_members(roomid: str, wxids: str) -> int
|
||||
|
||||
邀请群成员
|
||||
|
||||
:param roomid: 群的 id
|
||||
:type roomid: str
|
||||
:param wxids: 要邀请成员的 wxid, 多个用逗号`,`分隔
|
||||
:type wxids: str
|
||||
|
||||
:returns: 1 为成功,其他失败
|
||||
:rtype: int
|
||||
|
||||
|
||||
|
||||
.. py:method:: is_login() -> bool
|
||||
|
||||
是否已经登录
|
||||
|
||||
|
||||
|
||||
.. py:method:: is_receiving_msg() -> bool
|
||||
|
||||
是否已启动接收消息功能
|
||||
|
||||
|
||||
|
||||
.. py:method:: keep_running()
|
||||
|
||||
阻塞进程,让 RPC 一直维持连接
|
||||
|
||||
|
||||
|
||||
.. py:method:: query_sql(db: str, sql: str) -> List[Dict]
|
||||
|
||||
执行 SQL,如果数据量大注意分页,以免 OOM
|
||||
|
||||
:param db: 要查询的数据库
|
||||
:type db: str
|
||||
:param sql: 要执行的 SQL
|
||||
:type sql: str
|
||||
|
||||
:returns: 查询结果
|
||||
:rtype: List[Dict]
|
||||
|
||||
|
||||
|
||||
.. py:method:: receive_transfer(wxid: str, transferid: str, transactionid: str) -> int
|
||||
|
||||
接收转账
|
||||
|
||||
:param wxid: 转账消息里的发送人 wxid
|
||||
:type wxid: str
|
||||
:param transferid: 转账消息里的 transferid
|
||||
:type transferid: str
|
||||
:param transactionid: 转账消息里的 transactionid
|
||||
:type transactionid: str
|
||||
|
||||
:returns: 1 为成功,其他失败
|
||||
:rtype: int
|
||||
|
||||
|
||||
|
||||
.. py:method:: refresh_pyq(id: int = 0) -> int
|
||||
|
||||
刷新朋友圈
|
||||
|
||||
:param id: 开始 id,0 为最新页
|
||||
:type id: int
|
||||
|
||||
:returns: 1 为成功,其他失败
|
||||
:rtype: int
|
||||
|
||||
|
||||
|
||||
.. py:method:: revoke_msg(id: int = 0) -> int
|
||||
|
||||
撤回消息
|
||||
|
||||
:param id: 待撤回消息的 id
|
||||
:type id: int
|
||||
|
||||
:returns: 1 为成功,其他失败
|
||||
:rtype: int
|
||||
|
||||
|
||||
|
||||
.. py:method:: send_emotion(path: str, receiver: str) -> int
|
||||
|
||||
发送表情
|
||||
|
||||
:param path: 本地表情路径,如:`C:/Projs/WeChatRobot/emo.gif`
|
||||
:type path: str
|
||||
:param receiver: 消息接收人,wxid 或者 roomid
|
||||
:type receiver: str
|
||||
|
||||
:returns: 0 为成功,其他失败
|
||||
:rtype: int
|
||||
|
||||
|
||||
|
||||
.. py:method:: send_file(path: str, receiver: str) -> int
|
||||
|
||||
发送文件,非线程安全
|
||||
|
||||
:param path: 本地文件路径,如:`C:/Projs/WeChatRobot/README.MD` 或 `https://raw.githubusercontent.com/lich0821/WeChatFerry/master/README.MD`
|
||||
:type path: str
|
||||
:param receiver: 消息接收人,wxid 或者 roomid
|
||||
:type receiver: str
|
||||
|
||||
:returns: 0 为成功,其他失败
|
||||
:rtype: int
|
||||
|
||||
|
||||
|
||||
.. py:method:: send_image(path: str, receiver: str) -> int
|
||||
|
||||
发送图片,非线程安全
|
||||
|
||||
:param path: 图片路径,如:`C:/Projs/WeChatRobot/TEQuant.jpeg` 或 `https://raw.githubusercontent.com/lich0821/WeChatFerry/master/assets/TEQuant.jpg`
|
||||
:type path: str
|
||||
:param receiver: 消息接收人,wxid 或者 roomid
|
||||
:type receiver: str
|
||||
|
||||
:returns: 0 为成功,其他失败
|
||||
:rtype: int
|
||||
|
||||
|
||||
|
||||
.. py:method:: send_pat_msg(roomid: str, wxid: str) -> int
|
||||
|
||||
拍一拍群友
|
||||
|
||||
:param roomid: 群 id
|
||||
:type roomid: str
|
||||
:param wxid: 要拍的群友的 wxid
|
||||
:type wxid: str
|
||||
|
||||
:returns: 1 为成功,其他失败
|
||||
:rtype: int
|
||||
|
||||
|
||||
|
||||
.. py:method:: send_rich_text(name: str, account: str, title: str, digest: str, url: str, thumburl: str, receiver: str) -> int
|
||||
|
||||
发送富文本消息
|
||||
卡片样式:
|
||||
|-------------------------------------|
|
||||
|title, 最长两行
|
||||
|(长标题, 标题短的话这行没有)
|
||||
|digest, 最多三行,会占位 |--------|
|
||||
|digest, 最多三行,会占位 |thumburl|
|
||||
|digest, 最多三行,会占位 |--------|
|
||||
|(account logo) name
|
||||
|-------------------------------------|
|
||||
:param name: 左下显示的名字
|
||||
:type name: str
|
||||
:param account: 填公众号 id 可以显示对应的头像(gh_ 开头的)
|
||||
:type account: str
|
||||
:param title: 标题,最多两行
|
||||
:type title: str
|
||||
:param digest: 摘要,三行
|
||||
:type digest: str
|
||||
:param url: 点击后跳转的链接
|
||||
:type url: str
|
||||
:param thumburl: 缩略图的链接
|
||||
:type thumburl: str
|
||||
:param receiver: 接收人, wxid 或者 roomid
|
||||
:type receiver: str
|
||||
|
||||
:returns: 0 为成功,其他失败
|
||||
:rtype: int
|
||||
|
||||
|
||||
|
||||
.. py:method:: send_text(msg: str, receiver: str, aters: Optional[str] = '') -> int
|
||||
|
||||
发送文本消息
|
||||
|
||||
:param msg: 要发送的消息,换行使用 `\\n` (单杠);如果 @ 人的话,需要带上跟 `aters` 里数量相同的 @
|
||||
:type msg: str
|
||||
:param receiver: 消息接收人,wxid 或者 roomid
|
||||
:type receiver: str
|
||||
:param aters: 要 @ 的 wxid,多个用逗号分隔;`@所有人` 只需要 `notify@all`
|
||||
:type aters: str
|
||||
|
||||
:returns: 0 为成功,其他失败
|
||||
:rtype: int
|
||||
|
||||
|
||||
|
||||
.. py:method:: send_xml(receiver: str, xml: str, type: int, path: str = None) -> int
|
||||
|
||||
发送 XML
|
||||
|
||||
:param receiver: 消息接收人,wxid 或者 roomid
|
||||
:type receiver: str
|
||||
:param xml: xml 内容
|
||||
:type xml: str
|
||||
:param type: xml 类型,如:0x21 为小程序
|
||||
:type type: int
|
||||
:param path: 封面图片路径
|
||||
:type path: str
|
||||
|
||||
:returns: 0 为成功,其他失败
|
||||
:rtype: int
|
||||
|
||||
|
||||
|
||||
.. py:attribute:: LOG
|
||||
|
||||
|
||||
.. py:attribute:: cmd_socket
|
||||
|
||||
|
||||
.. py:attribute:: cmd_url
|
||||
:value: 'tcp://None:10086'
|
||||
|
||||
|
||||
|
||||
.. py:attribute:: contacts
|
||||
:value: []
|
||||
|
||||
|
||||
|
||||
.. py:attribute:: host
|
||||
:value: None
|
||||
|
||||
|
||||
|
||||
.. py:attribute:: msgQ
|
||||
|
||||
|
||||
.. py:attribute:: msg_socket
|
||||
|
||||
|
||||
.. py:attribute:: msg_url
|
||||
:value: ''
|
||||
|
||||
|
||||
|
||||
.. py:attribute:: port
|
||||
:value: 10086
|
||||
|
||||
|
||||
|
||||
.. py:attribute:: sdk
|
||||
:value: None
|
||||
|
||||
|
||||
|
||||
.. py:attribute:: self_wxid
|
||||
:value: ''
|
||||
|
||||
|
||||
Reference in New Issue
Block a user