├── .editorconfig
├── .eslintignore
├── .eslintrc.js
├── .gitignore
├── .vscode
└── settings.json
├── CHANGELOG.md
├── README.md
├── define.js
├── demo.js
├── docs
└── index.md
├── helper.js
├── index.js
├── log4js.json
├── package.json
└── scripts
└── docVer.js
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 2
6 | end_of_line = lf
7 | charset = utf-8
8 | trim_trailing_whitespace = true
9 | insert_final_newline = true
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | test
2 | coverage
3 | node_modules
4 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | env : {
4 | node: true,
5 | es6 : true
6 | },
7 | extends: ['eslint-config-egg'],
8 | globals: {
9 | 'document': true
10 | },
11 | rules: {
12 | 'semi': 0,
13 | // 数组和对象键值对最后一个逗号, never参数:不能带末尾的逗号, always参数:必须带末尾的逗号,
14 | // always-multiline:多行模式必须带逗号,单行模式不能带逗号
15 | 'comma-dangle': [1, 'always-multiline'],
16 | // 指定数组的元素之间要以空格隔开(, 后面), never参数:[ 之前和 ] 之后不能带空格,always参数:[ 之前和 ] 之后必须带空格
17 | 'array-bracket-spacing': [2, 'never'],
18 | 'no-unused-vars' : 'off', // 未使用变量
19 | // "generator-star-spacing": ["error", { "before": false, "after": true }],
20 | 'valid-jsdoc': ['error', {
21 | // 取消限制注释中必须使用 @return 标签替代 @returns标签
22 | prefer: {
23 | // returns: 'return',
24 | },
25 | }],
26 | "no-multi-spaces": ["error", {
27 | exceptions: {
28 | "ImportDeclaration" : true,
29 | "VariableDeclarator": true,
30 | "Property" : false,
31 | "ignoreEOLComments" : true
32 | }
33 | }],
34 | //对象字面量中冒号的前后空格
35 | "key-spacing": ["error", {
36 | "beforeColon": true,
37 | "afterColon" : true
38 | }]
39 | },
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | logs/
2 | npm-debug.log
3 | yarn-error.log
4 | node_modules/
5 | package-lock.json
6 | yarn.lock
7 | coverage/
8 | .idea/
9 | run/
10 | .DS_Store
11 | *.sw*
12 | *.un~
13 | *config*.json
14 | qrcode.jpg
15 | exe/
16 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | // 代码风格自动修正
3 | "eslint.autoFixOnSave": true,
4 | // Turns auto fix on save on or off.
5 | "tslint.autoFixOnSave": true,
6 | // 文件保存时自动格式化
7 | "editor.formatOnSave": true,
8 | //Better Align扩展配置
9 | "alignment.beforeSave": true,
10 | "alignment.exclude": [
11 | "json"
12 | ],
13 | "alignment.include": [
14 | "js",
15 | "ts",
16 | "vue",
17 | "css",
18 | "scss"
19 | ],
20 | "alignment.surroundSpace": {
21 | "colon": [
22 | 0,
23 | 1
24 | ],
25 | "assignment": [
26 | 1,
27 | 1
28 | ],
29 | "arrow": [
30 | 1,
31 | 1
32 | ],
33 | "comment": 0
34 | },
35 | "eslint.options": {
36 | "rules": {
37 | "semi": 0,
38 | // 数组和对象键值对最后一个逗号, never参数:不能带末尾的逗号, always参数:必须带末尾的逗号,
39 | // always-multiline:多行模式必须带逗号,单行模式不能带逗号
40 | "comma-dangle": [
41 | 1,
42 | "always-multiline"
43 | ],
44 | // 指定数组的元素之间要以空格隔开(, 后面), never参数:[ 之前和 ] 之后不能带空格,always参数:[ 之前和 ] 之后必须带空格
45 | "array-bracket-spacing": [
46 | 2,
47 | "never"
48 | ],
49 | "no-unused-vars": "off", // 未使用变量
50 | // "generator-star-spacing": ["error", { "before": false, "after": true }],
51 | "valid-jsdoc": [
52 | "error",
53 | {
54 | // 取消限制注释中必须使用 @return 标签替代 @returns标签
55 | "prefer": {
56 | // returns: "return",
57 | },
58 | }
59 | ],
60 | "no-multi-spaces": [
61 | "error",
62 | {
63 | "exceptions": {
64 | "ImportDeclaration": true,
65 | "VariableDeclarator": true,
66 | "Property": false,
67 | "ignoreEOLComments": true
68 | }
69 | }
70 | ],
71 | //对象字面量中冒号的前后空格
72 | "key-spacing": [
73 | "error",
74 | {
75 | "beforeColon": true,
76 | "afterColon": true
77 | }
78 | ]
79 | },
80 | },
81 | }
82 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 |
3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4 |
5 |
6 | ## [0.6.1](https://github.com/binsee/padchat-sdk/compare/v0.5.11...v0.6.1) (2018-11-01)
7 |
8 |
9 | ### Bug Fixes
10 |
11 | * **demo:** 更新demo中断线重连代码 ([fe5b2a6](https://github.com/binsee/padchat-sdk/commit/fe5b2a6))
12 | * 修复断线重连判断错误 ([3abc799](https://github.com/binsee/padchat-sdk/commit/3abc799))
13 |
14 |
15 | ### Features
16 |
17 | * 增加自动重连通知事件 ([cc29f3d](https://github.com/binsee/padchat-sdk/commit/cc29f3d))
18 | * 将推送联系人从push事件中独立出来 ([81d9206](https://github.com/binsee/padchat-sdk/commit/81d9206))
19 | * 更改cmdId为计数器,减少通讯中cmdId的占用尺寸 ([fd83bfd](https://github.com/binsee/padchat-sdk/commit/fd83bfd))
20 | * 更改ws通讯中荷载字段名称为payload ([1635b14](https://github.com/binsee/padchat-sdk/commit/1635b14)), closes [#28](https://github.com/binsee/padchat-sdk/issues/28)
21 | * 更改推送机制方案,以优化性能 ([fe22ae0](https://github.com/binsee/padchat-sdk/commit/fe22ae0))
22 | * 登陆模式的断线重连名称改为 'auto' ([e2461e3](https://github.com/binsee/padchat-sdk/commit/e2461e3)), closes [#29](https://github.com/binsee/padchat-sdk/issues/29)
23 | * **demo:** 可独立开关同步通讯录及消息 ([7d3f0e0](https://github.com/binsee/padchat-sdk/commit/7d3f0e0))
24 |
25 |
26 |
27 |
28 | # [0.6.0](https://github.com/binsee/padchat-sdk/compare/v0.5.11...v0.6.0) (2018-11-01)
29 |
30 |
31 | ### Bug Fixes
32 |
33 | * **demo:** 更新demo中断线重连代码 ([fe5b2a6](https://github.com/binsee/padchat-sdk/commit/fe5b2a6))
34 | * 修复断线重连判断错误 ([3abc799](https://github.com/binsee/padchat-sdk/commit/3abc799))
35 |
36 |
37 | ### Features
38 |
39 | * 增加自动重连通知事件 ([cc29f3d](https://github.com/binsee/padchat-sdk/commit/cc29f3d))
40 | * 将推送联系人从push事件中独立出来 ([81d9206](https://github.com/binsee/padchat-sdk/commit/81d9206))
41 | * 更改cmdId为计数器,减少通讯中cmdId的占用尺寸 ([fd83bfd](https://github.com/binsee/padchat-sdk/commit/fd83bfd))
42 | * 更改ws通讯中荷载字段名称为payload ([1635b14](https://github.com/binsee/padchat-sdk/commit/1635b14)), closes [#28](https://github.com/binsee/padchat-sdk/issues/28)
43 | * 更改推送机制方案,以优化性能 ([fe22ae0](https://github.com/binsee/padchat-sdk/commit/fe22ae0))
44 | * 登陆模式的断线重连名称改为 'auto' ([e2461e3](https://github.com/binsee/padchat-sdk/commit/e2461e3)), closes [#29](https://github.com/binsee/padchat-sdk/issues/29)
45 | * **demo:** 可独立开关同步通讯录及消息 ([7d3f0e0](https://github.com/binsee/padchat-sdk/commit/7d3f0e0))
46 |
47 |
48 |
49 |
50 | ## [0.5.13](https://github.com/binsee/padchat-sdk/compare/v0.5.11...v0.5.13) (2018-09-05)
51 |
52 |
53 |
54 |
55 | ## [0.5.12](https://github.com/binsee/padchat-sdk/compare/v0.5.11...v0.5.12) (2018-08-23)
56 |
57 |
58 |
59 |
60 | ## [0.5.11](https://github.com/binsee/padchat-sdk/compare/v0.5.10...v0.5.11) (2018-08-23)
61 |
62 |
63 | ### Bug Fixes
64 |
65 | * 修复使用设备数据登陆后再获取设备数据会无效的问题 ([042eaf1](https://github.com/binsee/padchat-sdk/commit/042eaf1))
66 |
67 |
68 |
69 |
70 | ## [0.5.10](https://github.com/binsee/padchat-sdk/compare/v0.5.9...v0.5.10) (2018-07-31)
71 |
72 |
73 | ### Bug Fixes
74 |
75 | * 修复群内发送文本消息at成员无效的bug ([27ac206](https://github.com/binsee/padchat-sdk/commit/27ac206))
76 |
77 |
78 |
79 |
80 | ## [0.5.9](https://github.com/binsee/padchat-sdk/compare/v0.5.8...v0.5.9) (2018-07-20)
81 |
82 |
83 |
84 |
85 | ## [0.5.8](https://github.com/binsee/padchat-sdk/compare/v0.5.7...v0.5.8) (2018-07-20)
86 |
87 |
88 | ### Features
89 |
90 | * 增加支持发送小程序 ([95668ad](https://github.com/binsee/padchat-sdk/commit/95668ad))
91 |
92 |
93 |
94 |
95 | ## [0.5.7](https://github.com/binsee/padchat-sdk/compare/v0.5.6...v0.5.7) (2018-07-16)
96 |
97 |
98 | ### Features
99 |
100 | * 增加websocket关闭原因参数 ([ac7b14d](https://github.com/binsee/padchat-sdk/commit/ac7b14d))
101 |
102 |
103 |
104 |
105 | ## [0.5.6](https://github.com/binsee/padchat-sdk/compare/v0.5.5...v0.5.6) (2018-06-13)
106 |
107 |
108 | ### Bug Fixes
109 |
110 | * 修复重连机制可能引发新的异常问题 ([591cb66](https://github.com/binsee/padchat-sdk/commit/591cb66))
111 |
112 |
113 |
114 |
115 | ## [0.5.5](https://github.com/binsee/padchat-sdk/compare/v0.5.4...v0.5.5) (2018-06-13)
116 |
117 |
118 | ### Bug Fixes
119 |
120 | * 修复warn事件没有正确获得服务器提示信息 ([66f1d7d](https://github.com/binsee/padchat-sdk/commit/66f1d7d))
121 |
122 |
123 | ### Features
124 |
125 | * 增加start方法来实现更容易的重连 ([231b476](https://github.com/binsee/padchat-sdk/commit/231b476)), closes [#30](https://github.com/binsee/padchat-sdk/issues/30)
126 |
127 |
128 |
129 |
130 | ## [0.5.4](https://github.com/binsee/padchat-sdk/compare/v0.5.3...v0.5.4) (2018-06-09)
131 |
132 |
133 | ### Bug Fixes
134 |
135 | * 断线重连登陆失败后,不需要重新初始化实例! ([099e54f](https://github.com/binsee/padchat-sdk/commit/099e54f))
136 |
137 |
138 |
139 |
140 | ## [0.5.3](https://github.com/binsee/padchat-sdk/compare/v0.5.2...v0.5.3) (2018-06-08)
141 |
142 |
143 | ### Bug Fixes
144 |
145 | * 修复发送语音显示时间为1秒问题 ([dbb9b24](https://github.com/binsee/padchat-sdk/commit/dbb9b24))
146 |
147 |
148 |
149 |
150 | ## [0.5.2](https://github.com/binsee/padchat-sdk/compare/v0.5.1...v0.5.2) (2018-06-04)
151 |
152 |
153 | ### Features
154 |
155 | * 增加syncMsg接口,用于手动触发同步消息 ([2c0d488](https://github.com/binsee/padchat-sdk/commit/2c0d488))
156 |
157 |
158 |
159 |
160 | ## [0.5.1](https://github.com/binsee/padchat-sdk/compare/v0.5.0...v0.5.1) (2018-06-03)
161 |
162 |
163 | ### Features
164 |
165 | * 增加getMyInfo接口,用于获取当前微信号的wxid和uin ([e67fa16](https://github.com/binsee/padchat-sdk/commit/e67fa16))
166 |
167 |
168 |
169 |
170 | # [0.5.0](https://github.com/binsee/padchat-sdk/compare/v0.4.4...v0.5.0) (2018-05-25)
171 |
172 |
173 | ### Features
174 |
175 | * syncContact增加参数`reset`,明确是否强制同步 ([b298327](https://github.com/binsee/padchat-sdk/commit/b298327))
176 | * **demo:** 登陆成功后不再自动同步通讯录,根据需要调用syncContact来同步通讯录 ([a28f684](https://github.com/binsee/padchat-sdk/commit/a28f684))
177 |
178 |
179 |
180 |
181 | ## [0.4.4](https://github.com/binsee/padchat-sdk/compare/v0.4.3...v0.4.4) (2018-05-24)
182 |
183 |
184 |
185 |
186 | ## [0.4.3](https://github.com/binsee/padchat-sdk/compare/v0.4.2...v0.4.3) (2018-05-08)
187 |
188 |
189 | ### Bug Fixes
190 |
191 | * 修复接口名称错误 ([98245fa](https://github.com/binsee/padchat-sdk/commit/98245fa))
192 |
193 |
194 |
195 |
196 | ## [0.4.2](https://github.com/binsee/padchat-sdk/compare/v0.4.0...v0.4.2) (2018-04-28)
197 |
198 |
199 | ### Bug Fixes
200 |
201 | * 增加解析push联系人事件中的群成员列表 ([8547c97](https://github.com/binsee/padchat-sdk/commit/8547c97))
202 |
203 |
204 |
205 |
206 | # [0.4.0](https://github.com/binsee/padchat-sdk/compare/v0.3.0...v0.4.0) (2018-04-11)
207 |
208 |
209 | ### Features
210 |
211 | * **demo:** 增加终端中直接生成二维码的示例 ([1681760](https://github.com/binsee/padchat-sdk/commit/1681760)), closes [#6](https://github.com/binsee/padchat-sdk/issues/6)
212 |
213 |
214 |
215 |
216 | # [0.3.0](https://github.com/binsee/padchat-sdk/compare/v0.2.0...v0.3.0) (2018-04-08)
217 |
218 |
219 | ### Bug Fixes
220 |
221 | * 修复demo中输出服务器地址 ([536fe6c](https://github.com/binsee/padchat-sdk/commit/536fe6c))
222 | * **修复部分需要传递rawMsgData的接口调用失败问题;修复demo中保存设备参数错误:** 1. 增加部分接口返回数据样例 | 2.demo中增加接收转账及红包的示例 ([8d894b9](https://github.com/binsee/padchat-sdk/commit/8d894b9))
223 |
224 |
225 | ### Features
226 |
227 | * **demo:** 增加通过文本指令执行指定接口的功能 ([45dafd4](https://github.com/binsee/padchat-sdk/commit/45dafd4))
228 |
229 |
230 |
231 |
232 | # [0.2.0](https://github.com/binsee/padchat-sdk/compare/v0.1.2...v0.2.0) (2018-04-03)
233 |
234 |
235 | ### Features
236 |
237 | * 新增多个接口(配合协议服务v1.4及以上版本);修复部分bug ([602d88b](https://github.com/binsee/padchat-sdk/commit/602d88b))
238 |
239 |
240 |
241 |
242 | ## [0.1.2](https://github.com/binsee/padchat-sdk/compare/v0.1.1...v0.1.2) (2018-03-27)
243 |
244 |
245 |
246 |
247 | ## [0.1.1](https://github.com/binsee/padchat-sdk/compare/v0.1.0...v0.1.1) (2018-03-26)
248 |
249 |
250 | ### Bug Fixes
251 |
252 | * 修复demo保存设备参数名称错误 ([64f5604](https://github.com/binsee/padchat-sdk/commit/64f5604))
253 |
254 |
255 |
256 |
257 | # [0.1.0](https://github.com/binsee/padchat-sdk/compare/613b2ae...v0.1.0) (2018-03-20)
258 |
259 |
260 | ### Features
261 |
262 | * v0.1.0 ([613b2ae](https://github.com/binsee/padchat-sdk/commit/613b2ae))
263 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [飞机群地址](https://t.me/+zPGvjRT-WO8yNGM1)
2 | # Padchat-SDK
3 |
4 |
5 |
6 | - [说明](#说明)
7 | - [接口功能列表](#接口功能列表)
8 | - [通讯约定](#通讯约定)
9 | - [通信协议](#通信协议)
10 | - [连接授权](#连接授权)
11 | - [API请求操作结果(识别异步请求)](#api请求操作结果识别异步请求)
12 | - [数据规则约定](#数据规则约定)
13 | - [API请求结构](#api请求结构)
14 | - [data字段总述](#data字段总述)
15 | - [DEMO](#demo)
16 | - [API文档](#api文档)
17 |
18 |
19 |
20 | ## 说明
21 |
22 | Padchat开发包。通过websocket协议与运行在windows平台上的微信ipad协议服务程序通讯,来登陆与操作微信。
23 |
24 | ## 接口功能列表
25 |
26 | | **接口** | **code** | **备注** |
27 | | ------------------ | :-----------------: | ------------------------------------- |
28 | | **登陆管理** | |
29 | | 初始化实例 | init | 初始化任务实例 |
30 | | 登陆 | login | 登陆账号 |
31 | | 注销登录 | logout | 会退出账号登陆 |
32 | | 关闭实例 | close | 关闭任务实例,不退出账号登陆 |
33 | | 获取设备登陆数据 | getWxData | 固定设备登陆数据 |
34 | | 获取二次登陆数据 | getLoginToken | 可使用二次登陆数据免扫码或免密码登陆 |
35 | | **用户管理** |
36 | | 获取用户信息 | getContact | 获取用户详细信息 |
37 | | 搜索用户 | searchContact |
38 | | 通过好友请求 | acceptUser |
39 | | 添加好友 | addContact |
40 | | 打招呼 | sayHello | |
41 | | 删除好友 | deleteContact |
42 | | 设置好友备注 | setRemark |
43 | | 设置头像 | setHeadImg |
44 | | 主动触发同步消息 | syncMsg | |
45 | | 主动同步通讯录 | syncContact | |
46 | | 获取用户二维码 | getContactQrcode | 用于获取自己的二维码图片 |
47 | | 获取当前用户信息 | getMyInfo | 用于获取当前微信号的wxid和uin |
48 | | **群管理** |
49 | | 创建群 | createRoom |
50 | | 获取群成员 | getRoomMembers |
51 | | 添加群成员 | addRoomMember |
52 | | 邀请好友进群 | inviteRoomMember |
53 | | 删除群成员 | deleteRoomMember |
54 | | 退出群 | quitRoom |
55 | | 设置群公告 | setRoomAnnouncement | 设置群公告会自动@通知群内所有成员 |
56 | | 设置群名称 | setRoomName | 修改微信群名称 |
57 | | 获取进群二维码 | getRoomQrcode | 获取到的进群二维码有效期为7天 |
58 | | **发送消息** |
59 | | 发送文本消息 | sendMsg |
60 | | 发送App消息 | sendAppMsg | 发送图文链接消息 |
61 | | 发送图片消息 | sendImage |
62 | | 发送语音消息 | sendVoice | 语音文件必须是silk格式 |
63 | | 发送名片 | shareCard |
64 | | **获取图片、文件** |
65 | | 获取消息图片原图 | getMsgImage | 获取图片消息的原始图片数据 |
66 | | 获取消息视频数据 | getMsgVideo | 获取小视频消息的视频数据 |
67 | | 获取消息语音数据 | getMsgVoice | 获取语音消息的语音数据 |
68 | | **朋友圈操作** |
69 | | 发朋友圈 | snsSendMoment | 发表文字朋友圈信息 |
70 | | 朋友圈上传图片 | snsUpload | 上传后仅能得到url,而非真正的发朋友圈 |
71 | | 查看用户朋友圈 | snsUserPage | 查看指定用户朋友圈信息 |
72 | | 获取朋友圈动态 | snsTimeline | 查看朋友圈时间轴信息 |
73 | | 获取朋友圈消息详情 | snsGetObject |
74 | | 操作朋友圈 | snsObjectOp | |
75 | | 发表评论 | snsComment |
76 | | 点赞 | snsLike |
77 | | **收藏操作** |
78 | | 同步收藏消息 | syncFav |
79 | | 添加收藏 | addFav |
80 | | 获取收藏消息详情 | getFav |
81 | | 删除收藏 | deleteFav |
82 | | **标签管理** |
83 | | 添加标签 | addLabel |
84 | | 删除标签 | deleteLabel |
85 | | 获取所有标签 | getLabelList |
86 | | 设置用户标签 | setLabel |
87 | | **公众号操作** |
88 | | 搜索公众号 | searchMp | 根据关键字搜索公众号 |
89 | | 获取公众号信息 | getSubscriptionInfo |
90 | | 操作公众号菜单 | operateSubscription |
91 | | 获取公众号网页授权 | getRequestToken | 需要授权才能访问的网页需要先授权 |
92 | | 访问授权页面 | requestUrl | 以授权过的身份访问页面 |
93 | | **小程序相关操作** | | 支持转发分享 |
94 |
95 | 完整接口见**API文档**
96 |
97 | ## 通讯约定
98 |
99 | ### 通信协议
100 |
101 | WebSocket 通信协议
102 |
103 | - [websockets 官方github](https://github.com/websockets)
104 | - [NodeJs 参考](https://github.com/websockets/ws)
105 |
106 | #### 连接授权
107 |
108 | 后续更新。
109 |
110 | #### API请求操作结果(识别异步请求)
111 |
112 | 由于websocket自身是异步操作,未原生支持识别请求返回的结果(即向服务端发送一个请求,服务端返回执行结果,客户端却无法确认是自己这个主动请求的结果,或者是另一个请求的返回结果,或者是服务端主动推送)。因此本服务增加了一个字段`cmdId`,用于标识请求,并在返回操作结果时一块返回。
113 |
114 | 如果希望发送api请求后,能识别服务端执行本次请求后的返回结果,可提供`cmdId`字段,请一定提供随机值,建议使用`uuid`模块随机生成。当收到服务端推送过来的数据中包含`cmdId`字段时,即可确认为之前请求对应的执行结果。
115 | 建议结合使用`Promise`+`Event.once(cmdId)`来实现。
116 |
117 | #### 数据规则约定
118 |
119 | > 在sdk内统一字段命名,统一转换为`小驼峰`写法。
120 |
121 | 微信协议原生接口返回的所有数据字段名称下划线写法(如`user_name`),部分接口(公众号相关接口)返回的混合有大驼峰命名。在sdk内已经全部格式化为`小驼峰`写法。
122 |
123 | 目前仅残留有部分xml结构文本内没有格式化,需自行解析提取与转换。
124 |
125 | 如果遇到接口返回的某个字段是json文本,请发issues告知接口名称、返回数据样本,以便增加对其的解析。
126 |
127 | ### API请求结构
128 |
129 | API请求是以websocket协议发送的json数据,以下为json数据的字段
130 |
131 | | **名称** | **类型** | **描述** | **必选** |
132 | | :------: | :------: | ------------------------------------------------------------- | :------: |
133 | | type | String | 请求类型:`sys`/`user` | 是 |
134 | | cmd | String | API命令 | 是 |
135 | | cmdId | String | 指令id。用于识别API异步操作结果,操作结果会增加此属性推送回来 | 否 |
136 | | data | Object | 取决于是不同的API要求 | 否 |
137 |
138 | #### data字段总述
139 |
140 | 此部分为请求API指令时,需要附加的data数据。根据使用的API不同,需要提供不同的字段及对应数据。
141 |
142 | | 字段名称 | 说明 | 备注 |
143 | | :--------------: | -------------------------- | -------------------------------------------------- |
144 | | **登陆** |
145 | | loginType | 登陆类型 | 支持扫码、帐号密码、手机验证码、二次登陆、断线重连 |
146 | | wxData | 登陆设备数据 | 使用已登陆过的设备数据登录,可避免封号 |
147 | | token | 二次登陆token | 结合`wxData`使用可免扫码、帐号登陆 |
148 | | **发送消息** | |
149 | | toUserName | 目标用户/群id | 群id包含@chatroom部分 |
150 | | content | 文本内容 | 文本消息内容、xml结构体文本、名片自定义标题 |
151 | | | | 添加好友时,为验证信息 |
152 | | file | 文件buffer的base64编码 | 发送图片/语音消息、上传头像、朋友圈上传图片 |
153 | | time | 语音的时间长度(单位为毫秒) | 发送语音消息 |
154 | | atList | `Array`,要at的用户用户 | `["wxid1","wxid2"]` 文本消息时有效 |
155 | | **群及好友管理** | |
156 | | roomName | 群名称 |
157 | | userIds | `Array`,用户id列表数组 | `["wxid1","wxid2"]` 创建群 |
158 | | chatroom | 要操作的群id |
159 | | remark | 备注名称 |
160 | | userId | 用户wxid | 主动添加好友、好友验证、添加/邀请用户进入群 |
161 | | stranger | V1码,相对加密的userId | 接受好友请求(仅限stranger字段) |
162 | | | | 主动添加好友(也可使用`userId`字段) |
163 | | ticket | V2码,好友请求中的ticket | 添加单向好友、接受好友请求 |
164 | | type | `Number`,操作类型 | 添加好友来源、朋友圈操作类型 |
165 | | **朋友圈** |
166 | | momentId | 朋友圈消息id |
167 | | commentId | `Number`,朋友圈评论id |
168 | | commentType | `Number`,朋友圈评论类型 |
169 | | **收藏** |
170 | | favKey | 收藏分页key | 通过分页key来分页拉取收藏 |
171 | | favId | `Number`,收藏id |
172 | | **标签** |
173 | | label | 标签名称 |
174 | | labelId | 标签id |
175 | | **公众号** |
176 | | ghName | 公众号id,`gh_`开头 |
177 | | menuId | `Number`,公众号菜单id |
178 | | menuKey | 公众号菜单key |
179 | | url | 网页url |
180 | | xKey | 网页授权key | 以公众号授权方式访问网页需要提供授权key |
181 | | xUin | 网页授权uin | 以公众号授权方式访问网页需要提供授权uin |
182 | | **其他** | |
183 | | rawMsgData | `Object`,push事件中的data | 用于接收红包、接收转账、获取原始图片 |
184 |
185 | ## DEMO
186 |
187 | 使用DEMO见 [demo.js](./demo.js)
188 |
189 | ## API文档
190 |
191 | SDK完整API文档见:[SDK Api文档](docs/index.md)
192 |
--------------------------------------------------------------------------------
/define.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | exports.wsEventType = [
4 | 'log',
5 | 'cmdRet',
6 | 'userEvent',
7 | 'sysEvent',
8 | ]
9 |
10 | exports.userEvents = [
11 | 'qrcode', // 登陆二维码
12 | 'scan', // 扫码登陆状态
13 | 'login', // 登陆完成
14 | 'loaded', // 通讯录载入完毕
15 | 'logout', // 注销登录(账户退出)
16 | 'close', // 任务断线
17 | 'warn', // 错误
18 | 'sns', // 朋友圈事件(朋友圈小圆点)
19 | 'notify', // 推送消息通知
20 | 'autoLogin', // 自动重连成功通知
21 | 'push', // 推送消息(系统、好友消息等)
22 | ]
23 |
24 | exports.loginType = {
25 | auto : 'auto', // 断线重连
26 | request: 'request', // 二次登陆
27 | qrcode : 'qrcode', // 扫码登陆
28 | phone : 'phone', // 手机验证码登陆
29 | user : 'user', // 账号密码登陆
30 | }
31 |
32 | exports.blacklist = [
33 | 'appbrandcustomerservicemsg',
34 | 'blogapp',
35 | 'cardpackage',
36 | 'facebookapp',
37 | 'feedsapp',
38 | 'filehelper',
39 | 'floatbottle',
40 | 'floatbottle', // 漂流瓶
41 | 'fmessage', // 朋友推荐
42 | 'helper_entry',
43 | 'lbsapp',
44 | 'linkedinplugin',
45 | 'masssendapp',
46 | 'medianote', // 语音记事本
47 | 'mphelper', // 公众平台安全助手
48 | 'newsapp', // 腾讯新闻
49 | 'notification_messages',
50 | 'notifymessage',
51 | 'officialaccounts',
52 | 'pc_share',
53 | 'qmessage', // qq离线消息
54 | 'qqfriend',
55 | 'qqmail',
56 | 'qqsync',
57 | 'shakeapp',
58 | 'tmessage',
59 | 'voiceinputapp',
60 | 'voicevoipapp',
61 | 'voipapp',
62 | 'weibo', // 微博-未知
63 | 'weixin', // 腾讯团队
64 | ]
65 |
--------------------------------------------------------------------------------
/demo.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const log4js = require('log4js')
4 | const Padchat = require('./index')
5 | const fs = require('fs')
6 | const util = require('util')
7 | const qrcode = require('qrcode-terminal')
8 |
9 | /**
10 | * 创建日志目录
11 | */
12 |
13 | try {
14 | require('fs').mkdirSync('./logs')
15 | } catch (e) {
16 | if (e.code !== 'EEXIST') {
17 | console.error('Could not set up log directory, error: ', e)
18 | process.exit(1)
19 | }
20 | }
21 |
22 | try {
23 | log4js.configure('./log4js.json')
24 | } catch (e) {
25 | console.error('载入log4js日志输出配置错误: ', e)
26 | process.exit(1);
27 | }
28 |
29 | const logger = log4js.getLogger('app')
30 | const dLog = log4js.getLogger('dev')
31 |
32 | logger.info('demo start!')
33 |
34 | const autoData = {
35 | wxData: '',
36 | token: '',
37 | }
38 | let server = ''
39 | server = 'ws://47.99.211.34:8181/'
40 | // 永久免费使用
41 |
42 | try {
43 | const tmpBuf = fs.readFileSync('./config.json')
44 | const data = JSON.parse(String(tmpBuf))
45 | autoData.wxData = data.wxData
46 | autoData.token = data.token
47 | logger.info('载入设备参数与自动登陆数据:%o ', autoData)
48 | } catch (e) {
49 | logger.warn('没有在本地发现设备登录参数或解析数据失败!如首次登录请忽略!')
50 | }
51 |
52 | const wx = new Padchat(server)
53 | logger.info('当前连接接口服务器为:', server)
54 | let disconnectCount = 0 // 断开计数
55 | let connected = false // 成功连接标志
56 |
57 | wx
58 | .on('close', (code, msg) => {
59 | // 需要注意关闭代码为3201-3203的错误,重连也用,具体参考文档中`close`事件说明
60 | if (code > 3200) {
61 | logger.warn(`Websocket已关闭!code: ${code} - ${msg}`)
62 | return
63 | }
64 | logger.info(`Websocket已关闭!code: ${code} - ${msg}`)
65 | // 根据是否成功连接过判断本次是未能连接成功还是与服务器连接中断
66 | if (connected) {
67 | connected = false
68 | disconnectCount++
69 | logger.info(`第 ${disconnectCount} 次与服务器连接断开!现在将重试连接服务器。`)
70 | } else {
71 | logger.debug(`未能连接服务器!将重试连接服务器。`)
72 | }
73 | // 重新启动websocket连接
74 | wx.start()
75 | })
76 | .on('open', async () => {
77 | let ret
78 | logger.info('连接成功!')
79 | connected = true
80 |
81 | // 非首次登录时最好使用以前成功登录时使用的设备参数,
82 | // 否则可能会被tx服务器怀疑账号被盗,导致手机端被登出
83 | ret = await wx.init()
84 | if (!ret.success) {
85 | logger.error('新建任务失败!', ret)
86 | return
87 | }
88 | logger.info('新建任务成功, json: ', ret)
89 |
90 | //先尝试使用断线重连方式登陆
91 | if (autoData.token) {
92 | ret = await wx.login('auto', autoData)
93 | if (ret.success) {
94 | logger.info('断线重连请求成功!', ret)
95 | return
96 | }
97 | logger.warn('断线重连请求失败!', ret)
98 |
99 | ret = await wx.login('request', autoData)
100 | if (ret.success) {
101 | logger.info('自动登录请求成功!', ret)
102 | return
103 | }
104 | logger.warn('自动登录请求失败!', ret)
105 | }
106 |
107 | ret = await wx.login('qrcode')
108 | if (!ret.success) {
109 | logger.error('使用qrcode登录模式失败!', ret)
110 | return
111 | }
112 | logger.info('使用qrcode登录模式!')
113 | })
114 | .on('qrcode', data => {
115 | // 如果存在url,则直接在终端中生成二维码并显示
116 | if (data.url) {
117 | logger.info(`登陆二维码内容为: "${data.url}",请使用微信扫描下方二维码登陆!`)
118 | qrcode.generate(data.url, { small: true })
119 | } else {
120 | logger.error(`未能获得登陆二维码!`)
121 | }
122 | })
123 | .on('scan', data => {
124 | switch (data.status) {
125 | case 0:
126 | logger.info('等待扫码...', data)
127 | break;
128 | case 1:
129 | // {
130 | // status : 1,
131 | // expiredTime: 239,
132 | // headUrl : 'http://wx.qlogo.cn/mmhead/ver_1/xxxxxxx/0', //头像url
133 | // nickName : '复仇者联盟' //昵称
134 | // }
135 | logger.info('已扫码,请在手机端确认登陆...', data)
136 | break;
137 | case 2:
138 | // {
139 | // password : '***hide***', // 可忽略
140 | // status : 2,
141 | // expiredTime: 238,
142 | // headUrl : 'http://wx.qlogo.cn/mmhead/ver_1/xxxxxxx/0', //头像url
143 | // subStatus : 0 // 登陆操作状态码
144 | // 以下字段仅在登录成功时有效
145 | // external : '1',
146 | // email : '',
147 | // uin : 149806460, // 微信账号uin,全局唯一
148 | // deviceType : 'android', // 登陆的主设备类型
149 | // nickName : '复仇者联盟' //昵称
150 | // userName : 'wxid_xxxxxx', // 微信账号id,全局唯一
151 | // phoneNumber: '18012345678', // 微信账号绑定的手机号
152 | // }
153 | switch (data.subStatus) {
154 | case 0:
155 | logger.info('扫码成功!登陆成功!', data)
156 | break;
157 | case 1:
158 | logger.info('扫码成功!登陆失败!', data)
159 | break;
160 | default:
161 | logger.info('扫码成功!未知状态码!', data)
162 | break;
163 | }
164 | break;
165 | // 如果等待登陆超时或手机上点击了取消登陆,需要重新调用登陆
166 | case 3:
167 | logger.info('二维码已过期!请重新调用登陆接口!', data)
168 | break;
169 | case 4:
170 | logger.info('手机端已取消登陆!请重新调用登陆接口!', data)
171 | break;
172 | default:
173 | logger.warn('未知登陆状态!请重新调用登陆接口!', data)
174 | break;
175 | }
176 | })
177 | .on('login', async () => {
178 | logger.info('微信账号登陆成功!')
179 | let ret
180 |
181 | ret = await wx.getMyInfo()
182 | logger.info('当前账号信息:', ret.data)
183 |
184 | // 如果不想同步通讯录信息,可关闭同步通讯录
185 | // await wx.setSyncContact(false)
186 |
187 | // 主动同步通讯录
188 | await wx.syncContact()
189 |
190 | await saveAutoData()
191 | })
192 | .on('autoLogin', async () => {
193 | // 自动重连后需要保存新的自动登陆数据
194 | await saveAutoData()
195 | })
196 | .on('logout', ({ msg }) => {
197 | logger.info('微信账号已退出!', msg)
198 | })
199 | .on('over', ({ msg }) => {
200 | logger.info('任务实例已关闭!', msg)
201 | })
202 | .on('loaded', async () => {
203 | logger.info('通讯录同步完毕!')
204 |
205 | // 主动触发同步消息
206 | await wx.syncMsg()
207 |
208 | const ret = await wx.sendMsg('filehelper', '你登录了!')
209 | logger.info('发送信息结果:', ret)
210 | })
211 | .on('sns', (data, msg) => {
212 | logger.info('收到朋友圈事件!请查看朋友圈新消息哦!', msg)
213 | })
214 |
215 | .on('contact', async data => {
216 | logger.info('收到推送联系人:%s - %s\n', data.userName, data.nickName, JSON.stringify(data))
217 | })
218 | .on('push', async data => {
219 | // 消息类型 data.mType
220 | // 1 文字消息
221 | // 3 收到图片消息
222 | // 34 语音消息
223 | // 35 用户头像buf
224 | // 37 收到好友请求消息
225 | // 42 名片消息
226 | // 43 视频消息
227 | // 47 表情消息
228 | // 48 定位消息
229 | // 49 APP消息(文件 或者 链接 H5)
230 | // 50 语音通话
231 | // 51 状态通知(如打开与好友/群的聊天界面)
232 | // 52 语音通话通知
233 | // 53 语音通话邀请
234 | // 62 小视频
235 | // 2000 转账消息
236 | // 2001 收到红包消息
237 | // 3000 群邀请
238 | // 9999 系统通知
239 | // 10000 微信通知信息. 微信群信息变更通知,多为群名修改,进群,离群信息,不包含群内聊天信息
240 | // 10002 撤回消息
241 | // --------------------------------
242 | // 注意,如果是来自微信群的消息,data.content字段中包含发言人的wxid及其发言内容,需要自行提取
243 | // 各类复杂消息,data.content中是xml格式的文本内容,需要自行从中提取各类数据。(如好友请求)
244 | let rawFile
245 | switch (data.mType) {
246 | case 3:
247 | logger.info('收到来自 %s 的图片消息,包含图片数据:%s,xml内容:\n%s', data.fromUser, !!data.data, data.content)
248 | rawFile = data.data || null
249 | logger.info('图片缩略图数据base64尺寸:%d', rawFile.length)
250 | await wx.getMsgImage(data)
251 | .then(ret => {
252 | rawFile = ret.data.image || ''
253 | logger.info('获取消息原始图片结果:%s, 获得图片base64尺寸:%d', ret.success, rawFile.length)
254 | })
255 | logger.info('图片数据base64尺寸:%d', rawFile.length)
256 | await wx.sendImage('filehelper', rawFile)
257 | .then(ret => {
258 | logger.info('转发图片信息给 %s 结果:', 'filehelper', ret)
259 | })
260 | .catch(e => {
261 | logger.warn('转发图片信息异常:', e.message)
262 | })
263 | break
264 |
265 | case 43:
266 | logger.info('收到来自 %s 的视频消息,包含视频数据:%s,xml内容:\n%s', data.fromUser, !!data.data, data.content)
267 | rawFile = data.data || null
268 | if (!rawFile) {
269 | await wx.getMsgVideo(data)
270 | .then(ret => {
271 | rawFile = ret.data.video || ''
272 | logger.info('获取消息原始视频结果:%s, 获得视频base64尺寸:%d', ret.success, rawFile.length)
273 | })
274 | }
275 | logger.info('视频数据base64尺寸:%d', rawFile.length)
276 | break
277 |
278 | case 1:
279 | if (data.fromUser === 'newsapp') { // 腾讯新闻发的信息太长
280 | break
281 | }
282 | logger.info('收到来自 %s 的文本消息:', data.fromUser, data.description || data.content)
283 | if (/ding/.test(data.content)) {
284 | await wx.sendMsg(data.fromUser, 'dong. receive:' + data.content)
285 | .then(ret => {
286 | logger.info('回复信息给%s 结果:', data.fromUser, ret)
287 | })
288 | .catch(e => {
289 | logger.warn('回复信息异常:', e.message)
290 | })
291 | } else if (/^#.*/.test(data.content) || /^[\w]*:\n#.*/.test(data.content)) {
292 | await onMsg(data)
293 | .catch(e => {
294 | logger.warn('处理信息异常:', e)
295 | })
296 | }
297 | break
298 |
299 | case 34:
300 | logger.info('收到来自 %s 的语音消息,包含语音数据:%s,xml内容:\n%s', data.fromUser, !!data.data, data.content)
301 | // 超过30Kb的语音数据不会包含在推送信息中,需要主动拉取
302 | rawFile = data.data || null
303 | if (!rawFile) {
304 | // BUG: 超过60Kb的语音数据,只能拉取到60Kb,也就是说大约36~40秒以上的语音会丢失后边部分语音内容
305 | await wx.getMsgVoice(data)
306 | .then(ret => {
307 | rawFile = ret.data.voice || ''
308 | logger.info('获取消息原始语音结果:%s, 获得语音base64尺寸:%d,拉取到数据尺寸:%d', ret.success, rawFile.length, ret.data.size)
309 | })
310 | }
311 | logger.info('语音数据base64尺寸:%d', rawFile.length)
312 | if (rawFile.length > 0) {
313 | let match = data.content.match(/length="(\d+)"/) || []
314 | const length = match[1] || 0
315 | match = data.content.match(/voicelength="(\d+)"/) || []
316 | const ms = match[1] || 0
317 | logger.info('语音数据语音长度:%d ms,xml内记录尺寸:%d', ms, length)
318 |
319 | await wx.sendVoice('filehelper', rawFile, ms)
320 | .then(ret => {
321 | logger.info('转发语音信息给 %s 结果:', 'filehelper', ret)
322 | })
323 | .catch(e => {
324 | logger.warn('转发语音信息异常:', e.message)
325 | })
326 | }
327 | break
328 |
329 | case 49:
330 | logger.info('收到一条来自 %s 的appmsg富媒体消息:', data.fromUser, data)
331 | break
332 |
333 | case 10002:
334 | if (data.fromUser === 'weixin') {
335 | //每次登陆,会收到一条系统垃圾推送,过滤掉
336 | break
337 | }
338 | logger.info('用户 %s 撤回了一条消息:', data.fromUser, data)
339 | break
340 |
341 | default:
342 | logger.info('收到推送消息:', data)
343 | break
344 | }
345 | })
346 | .on('error', e => {
347 | logger.error('ws 错误:', e.message)
348 | })
349 | .on('warn', e => {
350 | logger.error('任务出现错误:', e.message)
351 | })
352 |
353 | /**
354 | * @description 保存自动登陆数据
355 | */
356 | async function saveAutoData() {
357 | let ret = await wx.getWxData()
358 | if (!ret.success) {
359 | logger.warn('获取设备参数未成功! json:', ret)
360 | return
361 | }
362 | logger.info('获取设备参数成功, json: ', ret)
363 | Object.assign(autoData, { wxData: ret.data.wxData })
364 |
365 | ret = await wx.getLoginToken()
366 | if (!ret.success) {
367 | logger.warn('获取自动登陆数据未成功! json:', ret)
368 | return
369 | }
370 | logger.info('获取自动登陆数据成功, json: ', ret)
371 | Object.assign(autoData, { token: ret.data.token })
372 |
373 | // NOTE: 这里将设备参数保存到本地,以后再次登录此账号时提供相同参数
374 | fs.writeFileSync('./config.json', JSON.stringify(autoData, null, 2))
375 | logger.info('设备参数已写入到 ./config.json文件')
376 | }
377 |
378 | async function onMsg(data) {
379 | const content = data.content.replace(/^[\w:\n]*#/m, '')
380 | let [cmd, ...args] = content.split('\n')
381 |
382 | args = args.map(str => {
383 | try {
384 | str = JSON.parse(str)
385 | } catch (e) {
386 | }
387 | return str
388 | })
389 | if (cmd && wx[cmd] && typeof wx[cmd] === 'function') {
390 | logger.info('执行函数 %s,参数:', cmd, args)
391 | await wx[cmd](...args)
392 | .then(ret => {
393 | logger.info('执行函数 %s 结果:%o', cmd, ret)
394 | })
395 | .catch(e => {
396 | logger.warn('执行函数 %s 异常:', e)
397 | })
398 | }
399 | }
400 | process.on('uncaughtException', e => {
401 | logger.error('Main', 'uncaughtException:', e)
402 | })
403 |
404 | process.on('unhandledRejection', e => {
405 | logger.error('Main', 'unhandledRejection:', e)
406 | })
407 |
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | # Padchat Sdk v0.6.1 Documentation
2 |
3 |
4 |
5 | ## Padchat ⇐ EventEmitter
6 | **Kind**: global class
7 | **Extends**: EventEmitter
8 |
9 | * [Padchat](#Padchat) ⇐ EventEmitter
10 | * [new Padchat()](#new_Padchat_new)
11 | * _instance_
12 | * [.start()](#Padchat+start)
13 | * [.init()](#Padchat+init) ⇒ Promise.<object>
14 | * [.close()](#Padchat+close) ⇒ Promise.<object>
15 | * [.login(type, data)](#Padchat+login) ⇒ Promise.<object>
16 | * [.getWxData()](#Padchat+getWxData) ⇒ Promise.<object>
17 | * [.getLoginToken()](#Padchat+getLoginToken) ⇒ Promise.<object>
18 | * [.getMyInfo()](#Padchat+getMyInfo) ⇒ Promise.<object>
19 | * [.setSyncContact()](#Padchat+setSyncContact)
20 | * [.setSyncMsg()](#Padchat+setSyncMsg)
21 | * [.syncMsg()](#Padchat+syncMsg) ⇒ Promise.<object>
22 | * [.syncContact([reset])](#Padchat+syncContact) ⇒ Promise.<object>
23 | * [.logout()](#Padchat+logout) ⇒ Promise.<object>
24 | * [.sendMsg(toUserName, content, [atList])](#Padchat+sendMsg) ⇒ Promise.<object>
25 | * ~~[.massMsg([userList], content)](#Padchat+massMsg) ⇒ Promise.<object>
~~
26 | * [.sendAppMsg(toUserName, content, object)](#Padchat+sendAppMsg) ⇒ Promise.<object>
27 | * [.shareCard(toUserName, content, userId)](#Padchat+shareCard) ⇒ Promise.<object>
28 | * [.sendImage(toUserName, file)](#Padchat+sendImage) ⇒ Promise.<object>
29 | * [.sendVoice(toUserName, file, time)](#Padchat+sendVoice) ⇒ Promise.<object>
30 | * [.getMsgImage(rawMsgData)](#Padchat+getMsgImage) ⇒ Promise.<object>
31 | * [.getMsgVideo(rawMsgData)](#Padchat+getMsgVideo) ⇒ Promise.<object>
32 | * [.getMsgVoice(rawMsgData)](#Padchat+getMsgVoice) ⇒ Promise.<object>
33 | * [.createRoom(userList)](#Padchat+createRoom) ⇒ Promise.<object>
34 | * [.getRoomMembers(groupId)](#Padchat+getRoomMembers) ⇒ Promise.<object>
35 | * [.addRoomMember(groupId, userId)](#Padchat+addRoomMember) ⇒ Promise.<object>
36 | * [.inviteRoomMember(groupId, userId)](#Padchat+inviteRoomMember) ⇒ Promise.<object>
37 | * [.deleteRoomMember(groupId, userId)](#Padchat+deleteRoomMember) ⇒ Promise.<object>
38 | * [.quitRoom(groupId)](#Padchat+quitRoom) ⇒ Promise.<object>
39 | * [.setRoomAnnouncement(groupId, content)](#Padchat+setRoomAnnouncement) ⇒ Promise.<object>
40 | * [.setRoomName(groupId, content)](#Padchat+setRoomName) ⇒ Promise.<object>
41 | * [.getRoomQrcode(groupId)](#Padchat+getRoomQrcode) ⇒ Promise.<object>
42 | * [.getContact(userId)](#Padchat+getContact) ⇒ Promise.<object>
43 | * [.searchContact(userId)](#Padchat+searchContact) ⇒ Promise.<object>
44 | * [.deleteContact(userId)](#Padchat+deleteContact) ⇒ Promise.<object>
45 | * [.getContactQrcode(userId, style)](#Padchat+getContactQrcode) ⇒ Promise.<object>
46 | * [.acceptUser(stranger, ticket)](#Padchat+acceptUser) ⇒ Promise.<object>
47 | * [.addContact(stranger, ticket, type, [content])](#Padchat+addContact) ⇒ Promise.<object>
48 | * [.sayHello(stranger, ticket, content)](#Padchat+sayHello) ⇒ Promise.<object>
49 | * [.setRemark(userId, remark)](#Padchat+setRemark) ⇒ Promise.<object>
50 | * [.setHeadImg(file)](#Padchat+setHeadImg) ⇒ Promise.<object>
51 | * [.snsUpload(file)](#Padchat+snsUpload) ⇒ Promise.<object>
52 | * [.snsobjectOp(momentId, type, commentId, commentType)](#Padchat+snsobjectOp) ⇒ Promise.<object>
53 | * [.snsSendMoment(content)](#Padchat+snsSendMoment) ⇒ Promise.<object>
54 | * [.snsUserPage(userId, [momentId])](#Padchat+snsUserPage) ⇒ Promise.<object>
55 | * [.snsTimeline([momentId])](#Padchat+snsTimeline) ⇒ Promise.<object>
56 | * [.snsGetObject(momentId)](#Padchat+snsGetObject) ⇒ Promise.<object>
57 | * [.snsComment(userId, momentId, content)](#Padchat+snsComment) ⇒ Promise.<object>
58 | * [.snsLike(userId, momentId)](#Padchat+snsLike) ⇒ Promise.<object>
59 | * [.syncFav([favKey])](#Padchat+syncFav) ⇒ Promise.<object>
60 | * [.addFav(content)](#Padchat+addFav) ⇒ Promise.<object>
61 | * [.getFav(favId)](#Padchat+getFav) ⇒ Promise.<object>
62 | * [.deleteFav(favId)](#Padchat+deleteFav) ⇒ Promise.<object>
63 | * [.getLabelList()](#Padchat+getLabelList) ⇒ Promise.<object>
64 | * [.addLabel(label)](#Padchat+addLabel) ⇒ Promise.<object>
65 | * [.deleteLabel(labelId)](#Padchat+deleteLabel) ⇒ Promise.<object>
66 | * [.setLabel(userId, labelId)](#Padchat+setLabel) ⇒ Promise.<object>
67 | * [.queryTransfer(rawMsgData)](#Padchat+queryTransfer) ⇒ Promise.<object>
68 | * [.acceptTransfer(rawMsgData)](#Padchat+acceptTransfer) ⇒ Promise.<object>
69 | * [.receiveRedPacket(rawMsgData)](#Padchat+receiveRedPacket) ⇒ Promise.<object>
70 | * [.queryRedPacket(rawMsgData, [index])](#Padchat+queryRedPacket) ⇒ Promise.<object>
71 | * [.openRedPacket(rawMsgData, key)](#Padchat+openRedPacket) ⇒ Promise.<object>
72 | * [.searchMp(content)](#Padchat+searchMp) ⇒ Promise.<object>
73 | * [.getSubscriptionInfo(ghName)](#Padchat+getSubscriptionInfo) ⇒ Promise.<object>
74 | * [.operateSubscription(ghName, menuId, menuKey)](#Padchat+operateSubscription) ⇒ Promise.<object>
75 | * [.getRequestToken(ghName, url)](#Padchat+getRequestToken) ⇒ Promise.<object>
76 | * [.requestUrl(url, xKey, xUin)](#Padchat+requestUrl) ⇒ Promise.<object>
77 | * ["open"](#Padchat+event_open)
78 | * ["close"](#Padchat+event_close)
79 | * ["error"](#Padchat+event_error)
80 | * ["warn"](#Padchat+event_warn)
81 | * ["qrcode"](#Padchat+event_qrcode)
82 | * ["scan"](#Padchat+event_scan)
83 | * ["login"](#Padchat+event_login)
84 | * ["autoLogin"](#Padchat+event_autoLogin)
85 | * ["loaded"](#Padchat+event_loaded)
86 | * ["logout"](#Padchat+event_logout)
87 | * ["over"](#Padchat+event_over)
88 | * ["sns"](#Padchat+event_sns)
89 | * ["push"](#Padchat+event_push)
90 | * ["contact"](#Padchat+event_contact)
91 | * _static_
92 | * [.Padchat](#Padchat.Padchat)
93 | * [new Padchat([url])](#new_Padchat.Padchat_new)
94 |
95 |
96 |
97 | ### new Padchat()
98 | Padchat模块
99 |
100 | 使用websocket与服务器进行通讯,拥有以下事件
101 |
102 | Event | 说明
103 | ---- | ----
104 | qrcode | 推送的二维码
105 | scan | 扫码状态
106 | push | 新信息事件
107 | login | 登录
108 | loaded | 通讯录载入完毕
109 | logout | 注销登录
110 | over | 实例注销(账号不退出)(要再登录需要重新调用init)
111 | warn | 错误信息
112 | sns | 朋友圈更新事件
113 |
114 | **接口返回数据结构:** 所有接口均返回以下结构数据:
115 | ```
116 | {
117 | success: true, // 执行是否成功
118 | err : '', // 错误提示
119 | msg : '', // 附加信息
120 | data : {} // 返回结果
121 | }
122 | ```
123 |
124 | TODO: 补充各监听事件返回的数据定义
125 |
126 |
127 |
128 | ### padchat.start()
129 | 启动websocket连接
130 |
131 | **Kind**: instance method of [Padchat
](#Padchat)
132 |
133 |
134 | ### padchat.init() ⇒ Promise.<object>
135 | 初始化
136 |
137 | **Kind**: instance method of [Padchat
](#Padchat)
138 | **Returns**: Promise.<object>
- 返回Promise