Update docstrings and comments
This commit is contained in:
parent
c331ff6443
commit
5a4cb7fb85
@ -1,5 +1,4 @@
|
|||||||
# WeChatFerry Python 客户端
|
# WeChatFerry Python 客户端
|
||||||
⚠️ **只支持 Windows** ⚠️
|
|
||||||
|
|
||||||
🤖示例机器人框架:[WeChatRobot](https://github.com/lich0821/WeChatRobot)。
|
🤖示例机器人框架:[WeChatRobot](https://github.com/lich0821/WeChatRobot)。
|
||||||
|
|
||||||
@ -8,29 +7,6 @@
|
|||||||
pip install --upgrade wcferry
|
pip install --upgrade wcferry
|
||||||
```
|
```
|
||||||
|
|
||||||
### 接口清单
|
|
||||||
* 检查登录状态:`is_login`
|
|
||||||
* 获取登录账号的 wxid:`get_self_wxid`
|
|
||||||
* 获取消息类型:`get_msg_types`
|
|
||||||
* 获取所有联系人:`get_contacts`
|
|
||||||
* 获取所有好友:`get_friends`
|
|
||||||
* 获取数据库:`get_dbs`
|
|
||||||
* 获取某数据库下的表:`get_tables`
|
|
||||||
* 获取用户信息:`get_user_info`
|
|
||||||
* 发送文本消息(可 @):`send_text`
|
|
||||||
* 发送图片:`send_image`
|
|
||||||
* 发送文件:`send_file`
|
|
||||||
* 发送 XML:`send_xml`
|
|
||||||
* 发送表情:`send_emotion`
|
|
||||||
* 允许接收消息:`enable_receiving_msg` 和 `enable_recv_msg(旧接口)`
|
|
||||||
* 停止接收消息:`disable_recv_msg`
|
|
||||||
* 执行 SQL 查询:`query_sql`
|
|
||||||
* 接受好友申请:`accept_new_friend`
|
|
||||||
* 添加群成员:`add_chatroom_members`
|
|
||||||
* 解密图片:`decrypt_image`
|
|
||||||
|
|
||||||
详情查看 [client.py](wcferry/client.py)。
|
|
||||||
|
|
||||||
### Demo:
|
### Demo:
|
||||||
```py
|
```py
|
||||||
#! /usr/bin/env python3
|
#! /usr/bin/env python3
|
||||||
|
@ -47,7 +47,17 @@ def _retry():
|
|||||||
|
|
||||||
|
|
||||||
class Wcf():
|
class Wcf():
|
||||||
"""WeChatFerry, 一个玩微信的工具。"""
|
"""WeChatFerry, 一个玩微信的工具。
|
||||||
|
|
||||||
|
Args:
|
||||||
|
host (str): `wcferry` RPC 服务器地址,默认本地启动;也可以指定地址连接远程服务
|
||||||
|
port (int): `wcferry` RPC 服务器端口,默认为 10086,接收消息会占用 `port+1` 端口
|
||||||
|
debug (bool): 是否开启调试模式(仅本地启动有效)
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
contacts (list): 联系人缓存,调用 `get_contacts` 后更新
|
||||||
|
self_wxid (str): 登录账号 wxid
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, host: str = None, port: int = 10086, debug: bool = True) -> None:
|
def __init__(self, host: str = None, port: int = 10086, debug: bool = True) -> None:
|
||||||
self._local_host = False
|
self._local_host = False
|
||||||
@ -128,6 +138,7 @@ class Wcf():
|
|||||||
return rsp
|
return rsp
|
||||||
|
|
||||||
def is_receiving_msg(self) -> bool:
|
def is_receiving_msg(self) -> bool:
|
||||||
|
"""是否已启动接收消息功能"""
|
||||||
return self._is_receiving_msg
|
return self._is_receiving_msg
|
||||||
|
|
||||||
def is_login(self) -> bool:
|
def is_login(self) -> bool:
|
||||||
@ -191,7 +202,14 @@ class Wcf():
|
|||||||
return dbs
|
return dbs
|
||||||
|
|
||||||
def get_tables(self, db: str) -> List[dict]:
|
def get_tables(self, db: str) -> List[dict]:
|
||||||
"""获取 db 中所有表"""
|
"""获取 db 中所有表
|
||||||
|
|
||||||
|
Args:
|
||||||
|
db (str): 数据库名(可通过 `get_dbs` 查询)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List[dict]: `db` 下的所有表名及对应建表语句
|
||||||
|
"""
|
||||||
req = wcf_pb2.Request()
|
req = wcf_pb2.Request()
|
||||||
req.func = wcf_pb2.FUNC_GET_DB_TABLES # FUNC_GET_DB_TABLES
|
req.func = wcf_pb2.FUNC_GET_DB_TABLES # FUNC_GET_DB_TABLES
|
||||||
req.str = db
|
req.str = db
|
||||||
@ -201,7 +219,7 @@ class Wcf():
|
|||||||
return tables
|
return tables
|
||||||
|
|
||||||
def get_user_info(self) -> dict:
|
def get_user_info(self) -> dict:
|
||||||
"""获取个人信息"""
|
"""获取登录账号个人信息"""
|
||||||
req = wcf_pb2.Request()
|
req = wcf_pb2.Request()
|
||||||
req.func = wcf_pb2.FUNC_GET_USER_INFO # FUNC_GET_USER_INFO
|
req.func = wcf_pb2.FUNC_GET_USER_INFO # FUNC_GET_USER_INFO
|
||||||
rsp = self._send_request(req)
|
rsp = self._send_request(req)
|
||||||
@ -210,7 +228,16 @@ class Wcf():
|
|||||||
return ui
|
return ui
|
||||||
|
|
||||||
def send_text(self, msg: str, receiver: str, aters: Optional[str] = "") -> int:
|
def send_text(self, msg: str, receiver: str, aters: Optional[str] = "") -> int:
|
||||||
"""发送文本消息"""
|
"""发送文本消息
|
||||||
|
|
||||||
|
Args:
|
||||||
|
msg (str): 要发送的消息,换行使用 `\\n`;如果 @ 人的话,需要带上跟 `aters` 里数量相同的 @
|
||||||
|
receiver (str): 消息接收人,wxid 或者 roomid
|
||||||
|
aters (str): 要 @ 的 wxid,多个用逗号分隔;`@所有人` 只需要 `nofity@all`
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
int: 0 为成功,其他失败
|
||||||
|
"""
|
||||||
req = wcf_pb2.Request()
|
req = wcf_pb2.Request()
|
||||||
req.func = wcf_pb2.FUNC_SEND_TXT # FUNC_SEND_TXT
|
req.func = wcf_pb2.FUNC_SEND_TXT # FUNC_SEND_TXT
|
||||||
req.txt.msg = msg
|
req.txt.msg = msg
|
||||||
@ -221,7 +248,15 @@ class Wcf():
|
|||||||
return rsp.status
|
return rsp.status
|
||||||
|
|
||||||
def send_image(self, path: str, receiver: str) -> int:
|
def send_image(self, path: str, receiver: str) -> int:
|
||||||
"""发送图片"""
|
"""发送图片
|
||||||
|
|
||||||
|
Args:
|
||||||
|
path (str): 本地图片路径,如:`C:/Projs/WeChatRobot/TEQuant.jpeg`
|
||||||
|
receiver (str): 消息接收人,wxid 或者 roomid
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
int: 0 为成功,其他失败
|
||||||
|
"""
|
||||||
req = wcf_pb2.Request()
|
req = wcf_pb2.Request()
|
||||||
req.func = wcf_pb2.FUNC_SEND_IMG # FUNC_SEND_IMG
|
req.func = wcf_pb2.FUNC_SEND_IMG # FUNC_SEND_IMG
|
||||||
req.file.path = path
|
req.file.path = path
|
||||||
@ -230,7 +265,15 @@ class Wcf():
|
|||||||
return rsp.status
|
return rsp.status
|
||||||
|
|
||||||
def send_file(self, path: str, receiver: str) -> int:
|
def send_file(self, path: str, receiver: str) -> int:
|
||||||
"""发送文件"""
|
"""发送文件
|
||||||
|
|
||||||
|
Args:
|
||||||
|
path (str): 本地文件路径,如:`C:/Projs/WeChatRobot/README.MD`
|
||||||
|
receiver (str): 消息接收人,wxid 或者 roomid
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
int: 0 为成功,其他失败
|
||||||
|
"""
|
||||||
req = wcf_pb2.Request()
|
req = wcf_pb2.Request()
|
||||||
req.func = wcf_pb2.FUNC_SEND_FILE # FUNC_SEND_FILE
|
req.func = wcf_pb2.FUNC_SEND_FILE # FUNC_SEND_FILE
|
||||||
req.file.path = path
|
req.file.path = path
|
||||||
@ -239,7 +282,17 @@ class Wcf():
|
|||||||
return rsp.status
|
return rsp.status
|
||||||
|
|
||||||
def send_xml(self, receiver: str, xml: str, type: int, path: str = None) -> int:
|
def send_xml(self, receiver: str, xml: str, type: int, path: str = None) -> int:
|
||||||
"""发送文件"""
|
"""发送 XML
|
||||||
|
|
||||||
|
Args:
|
||||||
|
receiver (str): 消息接收人,wxid 或者 roomid
|
||||||
|
xml (str): xml 内容
|
||||||
|
type (int): xml 类型,如:0x21 为小程序
|
||||||
|
path (str): 封面图片路径
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
int: 0 为成功,其他失败
|
||||||
|
"""
|
||||||
req = wcf_pb2.Request()
|
req = wcf_pb2.Request()
|
||||||
req.func = wcf_pb2.FUNC_SEND_XML # FUNC_SEND_XML
|
req.func = wcf_pb2.FUNC_SEND_XML # FUNC_SEND_XML
|
||||||
req.xml.receiver = receiver
|
req.xml.receiver = receiver
|
||||||
@ -251,7 +304,15 @@ class Wcf():
|
|||||||
return rsp.status
|
return rsp.status
|
||||||
|
|
||||||
def send_emotion(self, path: str, receiver: str) -> int:
|
def send_emotion(self, path: str, receiver: str) -> int:
|
||||||
"""发送表情"""
|
"""发送表情
|
||||||
|
|
||||||
|
Args:
|
||||||
|
path (str): 本地表情路径,如:`C:/Projs/WeChatRobot/emo.gif`
|
||||||
|
receiver (str): 消息接收人,wxid 或者 roomid
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
int: 0 为成功,其他失败
|
||||||
|
"""
|
||||||
req = wcf_pb2.Request()
|
req = wcf_pb2.Request()
|
||||||
req.func = wcf_pb2.FUNC_SEND_EMOTION # FUNC_SEND_EMOTION
|
req.func = wcf_pb2.FUNC_SEND_EMOTION # FUNC_SEND_EMOTION
|
||||||
req.file.path = path
|
req.file.path = path
|
||||||
@ -260,10 +321,21 @@ class Wcf():
|
|||||||
return rsp.status
|
return rsp.status
|
||||||
|
|
||||||
def get_msg(self, block=True) -> WxMsg:
|
def get_msg(self, block=True) -> WxMsg:
|
||||||
|
"""从消息队列中获取消息
|
||||||
|
|
||||||
|
Args:
|
||||||
|
block (bool): 是否阻塞,默认阻塞
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
WxMsg: 微信消息
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
Empty: 如果阻塞并且超时,抛出空异常,需要用户自行捕获
|
||||||
|
"""
|
||||||
return self.msgQ.get(block, timeout=1)
|
return self.msgQ.get(block, timeout=1)
|
||||||
|
|
||||||
def enable_receiving_msg(self) -> bool:
|
def enable_receiving_msg(self) -> bool:
|
||||||
"""允许接收消息"""
|
"""允许接收消息,成功后通过 `get_msg` 读取消息"""
|
||||||
def listening_msg():
|
def listening_msg():
|
||||||
rsp = wcf_pb2.Response()
|
rsp = wcf_pb2.Response()
|
||||||
self.msg_socket.dial(self.msg_url, block=True)
|
self.msg_socket.dial(self.msg_url, block=True)
|
||||||
@ -297,7 +369,10 @@ class Wcf():
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def enable_recv_msg(self, callback: Callable[[WxMsg], None] = None) -> bool:
|
def enable_recv_msg(self, callback: Callable[[WxMsg], None] = None) -> bool:
|
||||||
"""设置接收消息回调"""
|
"""(不建议使用)设置接收消息回调,消息量大时可能会丢失消息
|
||||||
|
|
||||||
|
.. deprecated:: 3.7.0.30.13
|
||||||
|
"""
|
||||||
def listening_msg():
|
def listening_msg():
|
||||||
rsp = wcf_pb2.Response()
|
rsp = wcf_pb2.Response()
|
||||||
self.msg_socket.dial(self.msg_url, block=True)
|
self.msg_socket.dial(self.msg_url, block=True)
|
||||||
@ -345,7 +420,15 @@ class Wcf():
|
|||||||
return rsp.status
|
return rsp.status
|
||||||
|
|
||||||
def query_sql(self, db: str, sql: str) -> List[dict]:
|
def query_sql(self, db: str, sql: str) -> List[dict]:
|
||||||
"""执行 SQL"""
|
"""执行 SQL,如果数据量大注意分页,以免 OOM
|
||||||
|
|
||||||
|
Args:
|
||||||
|
db (str): 要查询的数据库
|
||||||
|
sql (str): 要执行的 SQL
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List[dict]: 查询结果
|
||||||
|
"""
|
||||||
result = []
|
result = []
|
||||||
req = wcf_pb2.Request()
|
req = wcf_pb2.Request()
|
||||||
req.func = wcf_pb2.FUNC_EXEC_DB_QUERY # FUNC_EXEC_DB_QUERY
|
req.func = wcf_pb2.FUNC_EXEC_DB_QUERY # FUNC_EXEC_DB_QUERY
|
||||||
@ -363,6 +446,7 @@ class Wcf():
|
|||||||
|
|
||||||
def accept_new_friend(self, v3: str, v4: str, scene: int = 30) -> int:
|
def accept_new_friend(self, v3: str, v4: str, scene: int = 30) -> int:
|
||||||
"""通过好友申请
|
"""通过好友申请
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
v3 (str): 加密用户名 (好友申请消息里 v3 开头的字符串)
|
v3 (str): 加密用户名 (好友申请消息里 v3 开头的字符串)
|
||||||
v4 (str): Ticket (好友申请消息里 v4 开头的字符串)
|
v4 (str): Ticket (好友申请消息里 v4 开头的字符串)
|
||||||
@ -400,7 +484,15 @@ class Wcf():
|
|||||||
return friends
|
return friends
|
||||||
|
|
||||||
def add_chatroom_members(self, roomid: str, wxids: str) -> int:
|
def add_chatroom_members(self, roomid: str, wxids: str) -> int:
|
||||||
"""添加群成员"""
|
"""添加群成员
|
||||||
|
|
||||||
|
Args:
|
||||||
|
roomid (str): 待加群的 id
|
||||||
|
wxids (str): 要加到群里的 wxid,多个用逗号分隔
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
int: 1 为成功,其他失败
|
||||||
|
"""
|
||||||
req = wcf_pb2.Request()
|
req = wcf_pb2.Request()
|
||||||
req.func = wcf_pb2.FUNC_ADD_ROOM_MEMBERS # FUNC_ADD_ROOM_MEMBERS
|
req.func = wcf_pb2.FUNC_ADD_ROOM_MEMBERS # FUNC_ADD_ROOM_MEMBERS
|
||||||
req.m.roomid = roomid
|
req.m.roomid = roomid
|
||||||
@ -410,6 +502,7 @@ class Wcf():
|
|||||||
|
|
||||||
def receive_transfer(self, wxid: str, transferid: str) -> int:
|
def receive_transfer(self, wxid: str, transferid: str) -> int:
|
||||||
"""接收转账
|
"""接收转账
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
wxid (str): 转账消息里的发送人 wxid
|
wxid (str): 转账消息里的发送人 wxid
|
||||||
transferid (str): 转账消息里的 transferid
|
transferid (str): 转账消息里的 transferid
|
||||||
@ -426,6 +519,7 @@ class Wcf():
|
|||||||
|
|
||||||
def decrypt_image(self, src: str, dst: str) -> bool:
|
def decrypt_image(self, src: str, dst: str) -> bool:
|
||||||
"""解密图片:
|
"""解密图片:
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
src (str): 加密的图片路径
|
src (str): 加密的图片路径
|
||||||
dst (str): 解密的图片路径
|
dst (str): 解密的图片路径
|
||||||
|
@ -1,9 +1,23 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
from wcferry import wcf_pb2
|
from wcferry import wcf_pb2
|
||||||
|
|
||||||
|
|
||||||
class WxMsg():
|
class WxMsg():
|
||||||
"""微信消息"""
|
"""微信消息
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
type (int): 消息类型,可通过 `get_msg_types` 获取
|
||||||
|
id (str): 消息 id
|
||||||
|
xml (str): 消息 xml 部分
|
||||||
|
sender (str): 消息发送人
|
||||||
|
roomid (str): (仅群消息有)群 id
|
||||||
|
content (str): 消息内容
|
||||||
|
thumb (str): 视频或图片消息的缩略图路径
|
||||||
|
extra (str): 视频或图片消息的路径
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, msg: wcf_pb2.WxMsg) -> None:
|
def __init__(self, msg: wcf_pb2.WxMsg) -> None:
|
||||||
self._is_self = msg.is_self
|
self._is_self = msg.is_self
|
||||||
|
Loading…
Reference in New Issue
Block a user