关于本项目
- 由道无涯i开发的一个基于 Lsposed(Non-Riru) 实现的微信机器人框架
- 我确信,这是目前安卓端上功能最全最完整的一个机器人框架
- 目前并没有对外开放,毕竟机器人框架这种东西比较容易火,容易被黑灰产非法利用
- 接口文档已趋于完善,机器人框架正式开发完毕
如果你想拥有一个这样的机器人,但困于编程知识储备不足,可联系 道无涯 按需定制,具体可移步 软件|源码定制 页
微信交流群
开发这玩意的初衷,除了钻研技术,主要是想整个机器人自动化拉群、管理群、活跃群等,现微信交流群已建立,想进的小伙伴可以添加道无涯的微信(daowuya02
),同意后会自动邀请进群!
请求与响应
目前支持 GET 和 POST 两种请求方式
GET 请求
GET 请求的 URL 由以下部分组成:
http://<host>:<port>/<endpoint>?<params>
链接中的含义如下:
<host>
:IP 地址,例127.0.0.1
<port>
:API 端口,默认为5701
<endpoint>
:API 端点,例send_text_msg
<params>
:GET 请求的参数,例param1=value1¶m2=value2
POST 请求
POST 请求的 URL 由以下部分组成:
http://<host>:<port>/<endpoint>
链接中的含义如下:
<host>
:IP 地址,例127.0.0.1
<port>
:API 端口,默认为5701
<endpoint>
:API 端点,例send_text_msg
- POST请求的Content-type为application/json
{
"wxid": "wxid_aabbccdd",
"text": "你好,道无涯!",
"atWxid": "all"
}
响应
响应格式为 JSON
如果下面的接口是获取值的,那么返回值会放在message
字段里,没有返回值则返回常规提示性的字符串
{
"result": "success", // 状态,success 为成功,error为失败
"message": "文本消息发送成功!", // 返回结果示例
}
事件与消息上报
上报时,插件将作为客户端,对接端作为服务器,插件向对接端发起POST请求进行数据传输
- 上报方式(method):
POST
- 上报链接(url):
http://ip:port/wxBot
,ip和port为对接端的 - 上报体(body):所有上报必定包含字段
post_type
用这个post_type
的值去区分各种事件与消息的上报类型,目前设定的post_type
值有三种:
post_type | 说明 |
---|---|
message | 消息事件 |
emoji | 玩法消息事件(骰子、剪刀石头布) |
private_request | 好友申请事件 |
group_increase | 群成员增加事件 |
message(消息事件)
- post_type为
message
时代表是消息事件 - 消息事件又以字段
message_type
作为区分,值分别有:
message_type | 说明 |
---|---|
official | 公众号消息 |
group | 群消息 |
private | 私聊消息 |
official(公众号消息)
公众号消息字段包含五种:
字段 | 说明 |
---|---|
wxid | 公众号原始微信ID |
official_name | 公众号名称 |
webpageUrl | 文章链接 |
title | 文章标题 |
description | 文章描述 |
thumbUrl | 文章缩略图 |
如果是多篇文章的话,默认只发送第一篇文章的数据
group(群消息)
群消息字段包含三种:
字段 | 说明 |
---|---|
chatroomid | 目标群聊的原始微信ID |
wxid | 发送消息的群成员的原始微信ID |
content | 消息内容 |
private(私聊消息)
私聊消息字段包含两种:
字段 | 说明 |
---|---|
wxid | 发送消息的好友的原始微信ID |
content | 消息内容 |
emoji(玩法消息事件)
- post_type为
emoji
时代表的是骰子与剪刀石头布玩法消息事件 - 玩法消息事件又以字段
message_type
作为区分,值分别有:
message_type | 说明 |
---|---|
group | 群玩法消息 |
private | 私聊玩法消息 |
group(群玩法消息)
群玩法消息字段包含三种:
字段 | 说明 |
---|---|
chatroomid | 目标群聊的原始微信ID |
wxid | 发送玩法的群成员的原始微信ID |
emoji_type | 玩法类型,1代表剪刀石头布,2代表骰子 |
emoji_index | 对应玩法的随机项索引,剪刀石头布(1-3),骰子(1-6) |
private(私聊玩法消息)
私聊玩法消息字段包含三种:
字段 | 说明 |
---|---|
wxid | 发送玩法的群成员的原始微信ID |
emoji_type | 玩法类型,1代表剪刀石头布,2代表骰子 |
emoji_index | 对应玩法的随机项索引,剪刀石头布(1-3),骰子(1-6) |
private_request(好友申请事件)
- post_type为
private_request
时代表是收到了好友添加的申请 - 好友申请事件有三个字段:
字段 | 说明 |
---|---|
wxid | 申请人的微信原始ID |
nickname | 申请人的微信昵称 |
ticket | 验证通过的关键值,接口同意好友申请 需要用到此值 |
group_increase(群成员增加事件)
- post_type为
group_increase
时代表群成员增加了,也就是意味着有新成员加入群聊了 - 群成员增加事件有三个字段:
字段 | 说明 |
---|---|
chatroomid | 被申请的群聊的微信原始ID |
wxid | 申请人的微信原始ID |
nickName | 申请人的微信昵称 |
消息相关接口
发送文本消息
该接口用于发送文本消息。
API 端点(POST
)
/send_text_msg
参数
字段 | 类型 | 必须 | 说明 |
---|---|---|---|
wxid | string |
是 | 微信原始ID |
text | string |
是 | 消息内容 |
atWxid | string |
否 | 要@的人的wxid,要@所有人 则值为all;如果此字段为空或不加则不@ |
发送图片消息
该接口用于发送图片消息。
API 端点(POST
)
/send_image_msg
参数
字段 | 类型 | 必须 | 说明 |
---|---|---|---|
wxid | string |
是 | 微信原始ID |
image | string |
是 | 图片,可以是本地路径或者是url链接,如果是url则默认以jpg格式发送 |
isRaw | boolean |
否 | 是否发送原图,默认false |
发送视频消息
该接口用于发送视频消息。
API 端点(POST
)
/send_video_msg
参数
字段 | 类型 | 必须 | 说明 |
---|---|---|---|
wxid | string |
是 | 微信原始ID |
video | string |
是 | 视频,可以是本地路径或者是url链接,如果是url则默认以mp4格式发送 |
isRaw | boolean |
否 | 是否发送原视频,默认false |
发送动图消息
该接口用于发送GIF动图消息。
API 端点(POST
)
/send_gif_msg
参数
字段 | 类型 | 必须 | 说明 |
---|---|---|---|
wxid | string |
是 | 微信原始ID |
gif | string |
是 | GIF动图,可以是本地路径或者是url链接 |
发送文件消息
该接口用于发送文件消息。
API 端点(POST
)
/send_file_msg
参数
字段 | 类型 | 必须 | 说明 |
---|---|---|---|
wxid | string |
是 | 微信原始ID |
file | string |
是 | 任意类型文件,可以是本地路径或者是url链接 |
ext | string |
否 | 文件后缀,例如.js 与.txt ,当file为本地路径时可以不填 |
发送语音消息
该接口用于发送语音消息。
API 端点(POST
)
/send_voice_msg
参数
字段 | 类型 | 必须 | 说明 |
---|---|---|---|
wxid | string |
是 | 微信原始ID |
voice | string |
是 | 语音文件,可以是本地路径或者是url链接,必须*.amr类型文件,可以通过文本生成语音 接口生成 |
duration | int |
是 | 语音文件的时长(毫秒),用于显示在微信界面语音的长度,可以是虚假的值,大于0即可 |
文本生成语音
该接口用于通过提供文本,生成amr语音文件并返回:生成的语音文件路径和毫秒时长通过==
连接成的字符串,例:/sdcrad/test.amr==7200
API 端点(POST
)
/text_to_voice
参数
字段 | 类型 | 必须 | 说明 |
---|---|---|---|
text | string |
是 | 要生成语音的文本 |
index | int |
是 | 0为使用系统语音引擎,1为使用Google服务(需要代理) |
发送名片消息
该接口用于发送名片消息。
API 端点(POST
)
/send_contact_msg
参数
字段 | 类型 | 必须 | 说明 |
---|---|---|---|
wxid | string |
是 | 微信原始ID |
shareWxid | string |
是 | 被分享的公众号或联系人的微信原始ID |
发送表情包消息
该接口用于发送表情包消息。
API 端点(POST
)
/send_emoji_msg
参数
字段 | 类型 | 必须 | 说明 |
---|---|---|---|
wxid | string |
是 | 微信原始ID |
type | int |
否 | 表情包类型,默认为0,0为收藏表情包,1为剪刀石头布,2为骰子 |
index | int |
否 | 表情包索引,默认为1,从1开始计数,收藏的就代表第index个,剪刀石头布(1-3),骰子(1-6) |
发送链接卡片
该接口用于发送链接卡片消息,比如公众号的文章分享以及其它的网址类分享,以卡片的形式显示
API 端点(POST
)
/send_url_msg
参数
字段 | 类型 | 必须 | 说明 |
---|---|---|---|
wxid | string |
是 | 微信原始ID |
webpageUrl | string |
是 | 分享的链接 |
title | string |
是 | 卡片标题 |
description | string |
否 | 卡片描述文本 |
thumbUrl | string |
否 | 缩略图链接 |
群聊管理相关接口
获取群成员列表
该接口用于获取指定微信群的所有群成员的wxid,返回数组
API 端点(GET
)
/get_group_members
参数
字段 | 类型 | 必须 | 说明 |
---|---|---|---|
chatroomid | string |
是 | 微信群原始ID |
获取群成员数量
该接口用于获取指定微信群的群成员数量
API 端点(GET
)
/get_group_member_count
参数
字段 | 类型 | 必须 | 说明 |
---|---|---|---|
chatroomid | string |
是 | 微信群原始ID |
根据群昵称获取群成员
该接口用于根据群成员昵称获取其wxid,该接口主要用于作图
功能,通过遍历群成员的群昵称和微信昵称进行筛选返回等值的昵称所对应的wxid,筛选的优先级是群昵称->微信昵称
API 端点(GET
)
/get_group_member_by_name
参数
字段 | 类型 | 必须 | 说明 |
---|---|---|---|
chatroomid | string |
是 | 微信群原始ID |
nickname | string |
是 | 群成员昵称 |
发布群公告
该接口用于在指定微信群内发布纯文本群公告
API 端点(GET
)
/publish_group_notice
参数
字段 | 类型 | 必须 | 说明 |
---|---|---|---|
chatroomid | string |
是 | 微信群原始ID |
text | string |
是 | 要发布的内容 |
清空群公告
该接口用于清空指定微信群内的群公告
API 端点(POST
)
/clear_group_notice
参数
字段 | 类型 | 必须 | 说明 |
---|---|---|---|
chatroomid | string |
是 | 微信群原始ID |
邀请进群
该接口用于发送进群邀请链接
API 端点(GET
)
/invite_group_member
参数
字段 | 类型 | 必须 | 说明 |
---|---|---|---|
chatroomid | string |
是 | 微信群原始ID |
wxid | string |
是 | 被邀请成员的wxid |
踢出群聊
该接口用于踢出指定群成员
API 端点(GET
)
/kick_group_member
参数
字段 | 类型 | 必须 | 说明 |
---|---|---|---|
chatroomid | string |
是 | 微信群原始ID |
wxid | string |
是 | 被踢出成员的wxid |
事件相关接口
同意好友申请
该接口用于同意好友申请
API 端点(GET
)
/approve_private_request
参数
字段 | 类型 | 必须 | 说明 |
---|---|---|---|
wxid | string |
是 | 申请人的wxid |
ticket | string |
是 | 申请时生成的ticket值,通过事件private_request 获取 |
通讯录相关接口
获取通讯录标签信息
该接口用于获取通讯录的所有标签信息(标签名+标签ID),无需传递任何参数
API 端点(GET
)
/get_contact_label_info
获取通讯录指定标签好友列表
该接口用于获取通讯录指定标签下的所有好友的wxid
API 端点(GET
)
/get_contact_members_by_labelid
参数
字段 | 类型 | 必须 | 说明 |
---|---|---|---|
labelid | string |
是 | 标签ID,可通过接口获取通讯录标签信息 获取 |
账号等其它相关接口
获取登录信息
该接口用于获取当前账号的登录信息
API 端点(GET
)
/get_login_info
参数
字段 | 类型 | 必须 | 说明 |
---|---|---|---|
index | int |
是 | 2(wxid)、4(昵称)、5(邮箱)、6(手机号)、9(QQ号) |
获取微信头像
该接口用于获取指定wxid的微信头像,返回头像的Base64数据
API 端点(GET
)
/get_avatar
参数
字段 | 类型 | 必须 | 说明 |
---|---|---|---|
wxid | string |
是 | 目标的微信原始ID |
获取微信昵称
该接口用于获取指定wxid的微信昵称
API 端点(GET
)
/get_nickname
参数
字段 | 类型 | 必须 | 说明 |
---|---|---|---|
wxid | string |
是 | 目标的微信原始ID |
清空缓存目录
该接口用于清空发送的缓存目录
至于所谓的缓存目录,对于上面的发图、发视频、发文件、发语音来说,发送的时候都会将要发送的目标先复制到该缓存目录再进行发送,因为如果直接指定路径的话有时候会没权限。那么为什么一个data目录,一个/sdcard/目录,/sdcard/目录是为语音文件作中转的,因为转amr要用python去转,通过扩展存储刚好可以访问到并转换成amr。发送的时候会再将该amr复制到/data下再去真正执行发送
/data/user/0/com.tencent.mm/MicroMsg/hookCache/*
/sdcard/hookCache/*
API 端点(GET
)
/clear_send_cache
结语
- 花了大半个月,从gadx逆向分析、frida反复调试、堆栈打印追踪,逐步写好frida脚本,再到编写接口文档,frida转xposed框架,最后进行客户端对接
- 逆向的成长都是得经过时间和耐心的沉淀,前前后后花了半个月左右,一直是从早上写到晚上睡觉的那种状态
- 写之前其实我并不认为自己能写出来,忍着耐心一直坚持着,最终造出来了
- 再次证明了,在编程的道路上,
只要我想要做的,就一定做得到~