wx2tg-puppet 1.0.9 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/ToolsApi.d.ts +2 -0
- package/dist/api/ToolsApi.js +4 -0
- package/dist/core/Friendship.d.ts +32 -0
- package/dist/core/Friendship.js +121 -0
- package/dist/core/Message.js +19 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +38 -1
- package/package.json +1 -1
- package/README.md +0 -40
package/dist/api/ToolsApi.d.ts
CHANGED
|
@@ -27,6 +27,8 @@ declare class ToolsApi {
|
|
|
27
27
|
UploadFile(body: any): Axios.IPromise<Axios.AxiosXHR<unknown>>;
|
|
28
28
|
/** 设置/删除代理IP */
|
|
29
29
|
setproxy(body: any): Axios.IPromise<Axios.AxiosXHR<unknown>>;
|
|
30
|
+
/** CDN图片下载 */
|
|
31
|
+
CdnDownloadImage(body: any): Axios.IPromise<Axios.AxiosXHR<unknown>>;
|
|
30
32
|
}
|
|
31
33
|
export declare const toolsApi: ToolsApi;
|
|
32
34
|
export {};
|
package/dist/api/ToolsApi.js
CHANGED
|
@@ -59,5 +59,9 @@ class ToolsApi {
|
|
|
59
59
|
setproxy(body) {
|
|
60
60
|
return axiosInstance_1.axiosInstance.post('/Tools/setproxy', body);
|
|
61
61
|
}
|
|
62
|
+
/** CDN图片下载 */
|
|
63
|
+
CdnDownloadImage(body) {
|
|
64
|
+
return axiosInstance_1.axiosInstance.post('/Tools/CdnDownloadImage', body);
|
|
65
|
+
}
|
|
62
66
|
}
|
|
63
67
|
exports.toolsApi = new ToolsApi();
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
interface FriendshipConstructor {
|
|
2
|
+
fromnickname?: string;
|
|
3
|
+
nickName?: string;
|
|
4
|
+
fromusername: string;
|
|
5
|
+
encryptusername?: string;
|
|
6
|
+
v3?: string;
|
|
7
|
+
ticket?: string;
|
|
8
|
+
v4?: string;
|
|
9
|
+
BigHeadImgUrl?: string;
|
|
10
|
+
bigHeadImgUrl?: string;
|
|
11
|
+
SmallHeadImgUrl?: string;
|
|
12
|
+
smallHeadImgUrl?: string;
|
|
13
|
+
content?: string;
|
|
14
|
+
scene: number;
|
|
15
|
+
}
|
|
16
|
+
export declare class Friendship {
|
|
17
|
+
private fromName;
|
|
18
|
+
private formId;
|
|
19
|
+
private v3;
|
|
20
|
+
private v4;
|
|
21
|
+
private bigHeadImgUrl;
|
|
22
|
+
private smallHeadImgUrl;
|
|
23
|
+
private content;
|
|
24
|
+
private scene;
|
|
25
|
+
constructor(obj: FriendshipConstructor);
|
|
26
|
+
accept(): Promise<any>;
|
|
27
|
+
hello(): string;
|
|
28
|
+
type(): number;
|
|
29
|
+
static search(mobile: string): Promise<Friendship | undefined>;
|
|
30
|
+
static add(contact: Friendship, helloMessage?: string): Promise<any>;
|
|
31
|
+
}
|
|
32
|
+
export {};
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.Friendship = void 0;
|
|
13
|
+
const FriendApi_1 = require("../api/FriendApi");
|
|
14
|
+
const config_service_1 = require("../services/config.service");
|
|
15
|
+
class Friendship {
|
|
16
|
+
constructor(obj) {
|
|
17
|
+
this.fromName = obj.fromnickname || obj.nickName || ''; // 代表联系人的信息
|
|
18
|
+
this.formId = obj.fromusername;
|
|
19
|
+
this.v3 = obj.encryptusername || obj.v3 || '';
|
|
20
|
+
this.v4 = obj.ticket || obj.v4 || '';
|
|
21
|
+
this.bigHeadImgUrl = obj.BigHeadImgUrl || obj.bigHeadImgUrl || '';
|
|
22
|
+
this.smallHeadImgUrl = obj.SmallHeadImgUrl || obj.smallHeadImgUrl || '';
|
|
23
|
+
this.content = obj.content || '';
|
|
24
|
+
this.scene = obj.scene;
|
|
25
|
+
/**
|
|
26
|
+
* 3 :微信号搜索
|
|
27
|
+
* 4 :QQ好友
|
|
28
|
+
* 8 :来自群聊
|
|
29
|
+
* 15:手机号
|
|
30
|
+
*/
|
|
31
|
+
}
|
|
32
|
+
// 实例方法1:accept()
|
|
33
|
+
accept() {
|
|
34
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
35
|
+
const config = yield config_service_1.configService.get();
|
|
36
|
+
return FriendApi_1.friendApi.PassVerify({
|
|
37
|
+
"Scene": parseInt(this.scene + ''),
|
|
38
|
+
"V1": this.v3,
|
|
39
|
+
"V2": this.v4,
|
|
40
|
+
"Wxid": config === null || config === void 0 ? void 0 : config.wxid
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
// 实例方法2:hello()
|
|
45
|
+
hello() {
|
|
46
|
+
return this.content;
|
|
47
|
+
}
|
|
48
|
+
// 实例方法3:contact()
|
|
49
|
+
// contact(): Contact {
|
|
50
|
+
// const contactEntity: ContactEntity = {
|
|
51
|
+
// userName: this.formId,
|
|
52
|
+
// nickName: this.fromName,
|
|
53
|
+
// bigHeadImgUrl: this.bigHeadImgUrl,
|
|
54
|
+
// smallHeadImgUrl: this.smallHeadImgUrl,
|
|
55
|
+
// pyInitial: '',
|
|
56
|
+
// quanPin: '',
|
|
57
|
+
// sex: 0,
|
|
58
|
+
// remark: '',
|
|
59
|
+
// remarkPyInitial: '',
|
|
60
|
+
// remarkQuanPin: '',
|
|
61
|
+
// signature: '',
|
|
62
|
+
// alias: '',
|
|
63
|
+
// snsBgImg: '',
|
|
64
|
+
// country: '',
|
|
65
|
+
// description: '',
|
|
66
|
+
// cardImgUrl: '',
|
|
67
|
+
// labelList: '',
|
|
68
|
+
// province: '',
|
|
69
|
+
// city: '',
|
|
70
|
+
// phoneNumList: ''
|
|
71
|
+
// };
|
|
72
|
+
// return new Contact(contactEntity);
|
|
73
|
+
// }
|
|
74
|
+
// 实例方法4:type()
|
|
75
|
+
type() {
|
|
76
|
+
return this.scene;
|
|
77
|
+
}
|
|
78
|
+
static search(mobile) {
|
|
79
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
80
|
+
var _a, _b, _c;
|
|
81
|
+
try {
|
|
82
|
+
const config = yield config_service_1.configService.get();
|
|
83
|
+
const res = yield FriendApi_1.friendApi.Search({
|
|
84
|
+
"FromScene": 0,
|
|
85
|
+
"SearchScene": 1,
|
|
86
|
+
"ToUserName": mobile,
|
|
87
|
+
"Wxid": config === null || config === void 0 ? void 0 : config.wxid
|
|
88
|
+
});
|
|
89
|
+
if (res === null || res === void 0 ? void 0 : res.data) {
|
|
90
|
+
return new Friendship({
|
|
91
|
+
fromnickname: (_a = res.data.Data.NickName) === null || _a === void 0 ? void 0 : _a.string,
|
|
92
|
+
fromusername: (_b = res.data.Data.UserName) === null || _b === void 0 ? void 0 : _b.string,
|
|
93
|
+
v3: (_c = res.data.Data.UserName) === null || _c === void 0 ? void 0 : _c.string,
|
|
94
|
+
v4: res.data.Data.AntispamTicket,
|
|
95
|
+
bigHeadImgUrl: res.data.Data.BigHeadImgUrl,
|
|
96
|
+
smallHeadImgUrl: res.data.Data.SmallHeadImgUrl,
|
|
97
|
+
scene: 0
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
console.error('Error searching contact:', error);
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
// 静态方法1:add()
|
|
107
|
+
static add(contact, helloMessage) {
|
|
108
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
109
|
+
const config = yield config_service_1.configService.get();
|
|
110
|
+
return FriendApi_1.friendApi.SendRequest({
|
|
111
|
+
"Opcode": 2,
|
|
112
|
+
"Scene": 0,
|
|
113
|
+
"V1": contact.v3,
|
|
114
|
+
"V2": contact.v4,
|
|
115
|
+
"VerifyContent": helloMessage || '',
|
|
116
|
+
"Wxid": config === null || config === void 0 ? void 0 : config.wxid
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
exports.Friendship = Friendship;
|
package/dist/core/Message.js
CHANGED
|
@@ -341,10 +341,29 @@ class Message {
|
|
|
341
341
|
}
|
|
342
342
|
toFileBox() {
|
|
343
343
|
return __awaiter(this, void 0, void 0, function* () {
|
|
344
|
+
var _a;
|
|
344
345
|
if (this.type() === MessageType_1.MessageType.Image) {
|
|
345
346
|
const xml = this.msg.Content;
|
|
346
347
|
const json = Message.getXmlToJson(xml);
|
|
347
348
|
const config = yield config_service_1.configService.get();
|
|
349
|
+
// 优先使用 cdn 下载
|
|
350
|
+
const aeskey = json.msg.img.aeskey;
|
|
351
|
+
let url = json.msg.img.cdnbigimgurl;
|
|
352
|
+
if (!url) {
|
|
353
|
+
url = json.msg.img.cdnmidimgurl;
|
|
354
|
+
}
|
|
355
|
+
else if (!url) {
|
|
356
|
+
url = json.msg.img.cdnthumburl;
|
|
357
|
+
}
|
|
358
|
+
const cdnResp = yield ToolsApi_1.toolsApi.CdnDownloadImage({
|
|
359
|
+
"FileAesKey": aeskey,
|
|
360
|
+
"FileNo": url,
|
|
361
|
+
"Wxid": (config === null || config === void 0 ? void 0 : config.wxid) || ''
|
|
362
|
+
});
|
|
363
|
+
if (((_a = cdnResp === null || cdnResp === void 0 ? void 0 : cdnResp.data) === null || _a === void 0 ? void 0 : _a.Message) === '成功') {
|
|
364
|
+
const fileBox = file_box_1.FileBox.fromBase64(cdnResp.data.Data.Image, `${this.msg.MsgId}.png`);
|
|
365
|
+
return fileBox;
|
|
366
|
+
}
|
|
348
367
|
const totalSize = parseInt(json.msg.img.length);
|
|
349
368
|
// Get initial chunk size from first request
|
|
350
369
|
const firstChunk = FileChunkHelper_1.FileChunkHelper.getChunk(totalSize, 0);
|
package/dist/index.d.ts
CHANGED
|
@@ -22,6 +22,11 @@ export declare class WxBot extends EventEmitter {
|
|
|
22
22
|
private msgInterval;
|
|
23
23
|
private recentMsgIds;
|
|
24
24
|
constructor({ baseUrl, databasePath }: WxBotOptions);
|
|
25
|
+
qrcode(style?: number): Promise<{
|
|
26
|
+
qr: {
|
|
27
|
+
qrCode: any;
|
|
28
|
+
};
|
|
29
|
+
}>;
|
|
25
30
|
private fetchAndShowQRCode;
|
|
26
31
|
private setupHeartbeat;
|
|
27
32
|
private checkLoginStatus;
|
package/dist/index.js
CHANGED
|
@@ -36,6 +36,9 @@ const WEVIDEO_1 = require("./core/WEVIDEO");
|
|
|
36
36
|
Object.defineProperty(exports, "WeVideo", { enumerable: true, get: function () { return WEVIDEO_1.WeVideo; } });
|
|
37
37
|
const URLLINK_1 = require("./core/URLLINK");
|
|
38
38
|
Object.defineProperty(exports, "UrlLink", { enumerable: true, get: function () { return URLLINK_1.UrlLink; } });
|
|
39
|
+
const MessageType_1 = require("./type/MessageType");
|
|
40
|
+
const Friendship_1 = require("./core/Friendship");
|
|
41
|
+
const UserApi_1 = require("./api/UserApi");
|
|
39
42
|
class WxBot extends events_1.EventEmitter {
|
|
40
43
|
constructor({ baseUrl, databasePath }) {
|
|
41
44
|
super();
|
|
@@ -48,6 +51,20 @@ class WxBot extends events_1.EventEmitter {
|
|
|
48
51
|
this.databasePath = databasePath;
|
|
49
52
|
(0, axiosInstance_1.setBaseUrl)(baseUrl);
|
|
50
53
|
}
|
|
54
|
+
qrcode(style) {
|
|
55
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
56
|
+
const config = yield config_service_1.configService.get();
|
|
57
|
+
const res = yield UserApi_1.userApi.GetQRCode({
|
|
58
|
+
"Style": style || 8,
|
|
59
|
+
"Wxid": config === null || config === void 0 ? void 0 : config.wxid
|
|
60
|
+
});
|
|
61
|
+
return {
|
|
62
|
+
qr: {
|
|
63
|
+
qrCode: res.data.Data.qrcode.buffer
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
});
|
|
67
|
+
}
|
|
51
68
|
fetchAndShowQRCode() {
|
|
52
69
|
return __awaiter(this, void 0, void 0, function* () {
|
|
53
70
|
try {
|
|
@@ -201,6 +218,9 @@ class WxBot extends events_1.EventEmitter {
|
|
|
201
218
|
if (data.Message === '当前未有新消息') {
|
|
202
219
|
return;
|
|
203
220
|
}
|
|
221
|
+
if (!data.Data.AddMsgs) {
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
204
224
|
// 更新联系人或者群组信息
|
|
205
225
|
// 新增:触发 message 事件
|
|
206
226
|
for (const msg of data.Data.AddMsgs) {
|
|
@@ -232,7 +252,24 @@ class WxBot extends events_1.EventEmitter {
|
|
|
232
252
|
IsSelf: msg.FromUserName.string === userName,
|
|
233
253
|
xml: msg.Content.string
|
|
234
254
|
});
|
|
235
|
-
|
|
255
|
+
if (message.type() === MessageType_1.MessageType.AddFriend) { // 好友请求
|
|
256
|
+
const obj = Message_1.Message.getXmlToJson(message.text());
|
|
257
|
+
console.log(obj);
|
|
258
|
+
const friendship = new Friendship_1.Friendship({
|
|
259
|
+
fromnickname: obj.msg.fromnickname,
|
|
260
|
+
v3: obj.msg.encryptusername,
|
|
261
|
+
v4: obj.msg.ticket,
|
|
262
|
+
scene: obj.msg.scene,
|
|
263
|
+
fromusername: obj.msg.fromusername,
|
|
264
|
+
bigHeadImgUrl: obj.msg.bigHeadImgUrl,
|
|
265
|
+
smallHeadImgUrl: obj.msg.smallHeadImgUrl,
|
|
266
|
+
content: obj.msg.content
|
|
267
|
+
});
|
|
268
|
+
this.emit('friendship', friendship);
|
|
269
|
+
}
|
|
270
|
+
else {
|
|
271
|
+
this.emit('message', message);
|
|
272
|
+
}
|
|
236
273
|
}
|
|
237
274
|
}
|
|
238
275
|
else if (data.Message === '用户可能退出') {
|
package/package.json
CHANGED
package/README.md
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
# wx2tg-puppet
|
|
2
|
-
|
|
3
|
-
微信机器人核心库,可作为依赖被其他项目引入。
|
|
4
|
-
|
|
5
|
-
## 安装
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npm install /path/to/your/wx2tg-puppet
|
|
9
|
-
# 或发布到 npm 后
|
|
10
|
-
npm install wx2tg-puppet
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
## 使用示例
|
|
14
|
-
|
|
15
|
-
```ts
|
|
16
|
-
import { WxBot } from 'wx2tg-puppet';
|
|
17
|
-
|
|
18
|
-
const bot = new WxBot({
|
|
19
|
-
baseUrl: 'http://your-api-url',
|
|
20
|
-
databasePath: './db.sqlite',
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
bot.on('scan', (qrcode) => {
|
|
24
|
-
// 展示二维码
|
|
25
|
-
});
|
|
26
|
-
bot.on('login', (user) => {
|
|
27
|
-
// 登录成功
|
|
28
|
-
});
|
|
29
|
-
bot.on('message', (msg) => {
|
|
30
|
-
// 收到消息
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
bot.start();
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
## 导出内容
|
|
37
|
-
- WxBot
|
|
38
|
-
- Contact
|
|
39
|
-
- Room
|
|
40
|
-
- Message
|