zalo-toolkit 1.0.0 → 1.0.2
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/apis/sendMessage.d.ts +5 -0
- package/dist/apis/sendMessage.js +31 -11
- package/dist/cjs/apis/acceptFriendRequest.cjs +33 -0
- package/dist/cjs/apis/addGroupBlockedMember.cjs +33 -0
- package/dist/cjs/apis/addGroupDeputy.cjs +36 -0
- package/dist/cjs/apis/addPollOptions.cjs +31 -0
- package/dist/cjs/apis/addQuickMessage.cjs +65 -0
- package/dist/cjs/apis/addReaction.cjs +297 -0
- package/dist/cjs/apis/addUnreadMark.cjs +65 -0
- package/dist/cjs/apis/addUserToGroup.cjs +39 -0
- package/dist/cjs/apis/blockUser.cjs +33 -0
- package/dist/cjs/apis/blockViewFeed.cjs +35 -0
- package/dist/cjs/apis/changeAccountAvatar.cjs +56 -0
- package/dist/cjs/apis/changeFriendAlias.cjs +32 -0
- package/dist/cjs/apis/changeGroupAvatar.cjs +47 -0
- package/dist/cjs/apis/changeGroupName.cjs +37 -0
- package/dist/cjs/apis/changeGroupOwner.cjs +36 -0
- package/dist/cjs/apis/createAutoReply.cjs +42 -0
- package/dist/cjs/apis/createCatalog.cjs +34 -0
- package/dist/cjs/apis/createGroup.cjs +48 -0
- package/dist/cjs/apis/createNote.cjs +52 -0
- package/dist/cjs/apis/createPoll.cjs +45 -0
- package/dist/cjs/apis/createProductCatalog.cjs +55 -0
- package/dist/cjs/apis/createReminder.cjs +76 -0
- package/dist/cjs/apis/custom.cjs +19 -0
- package/dist/cjs/apis/deleteAutoReply.cjs +34 -0
- package/dist/cjs/apis/deleteAvatar.cjs +32 -0
- package/dist/cjs/apis/deleteCatalog.cjs +33 -0
- package/dist/cjs/apis/deleteChat.cjs +63 -0
- package/dist/cjs/apis/deleteGroupInviteBox.cjs +32 -0
- package/dist/cjs/apis/deleteMessage.cjs +65 -0
- package/dist/cjs/apis/deleteProductCatalog.cjs +36 -0
- package/dist/cjs/apis/disableGroupLink.cjs +29 -0
- package/dist/cjs/apis/disperseGroup.cjs +33 -0
- package/dist/cjs/apis/editNote.cjs +51 -0
- package/dist/cjs/apis/editReminder.cjs +74 -0
- package/dist/cjs/apis/enableGroupLink.cjs +30 -0
- package/dist/cjs/apis/fetchAccountInfo.cjs +15 -0
- package/dist/cjs/apis/findUser.cjs +45 -0
- package/dist/cjs/apis/forwardAttachment.cjs +85 -0
- package/dist/cjs/apis/forwardMessage.cjs +122 -0
- package/dist/cjs/apis/getAliasList.cjs +33 -0
- package/dist/cjs/apis/getAllFriends.cjs +37 -0
- package/dist/cjs/apis/getAllGroups.cjs +15 -0
- package/dist/cjs/apis/getArchivedChatList.cjs +28 -0
- package/dist/cjs/apis/getAutoDeleteChat.cjs +26 -0
- package/dist/cjs/apis/getAutoReplyList.cjs +29 -0
- package/dist/cjs/apis/getAvatarList.cjs +33 -0
- package/dist/cjs/apis/getBizAccount.cjs +32 -0
- package/dist/cjs/apis/getCatalogList.cjs +37 -0
- package/dist/cjs/apis/getContext.cjs +9 -0
- package/dist/cjs/apis/getCookie.cjs +14 -0
- package/dist/cjs/apis/getFriendBoardList.cjs +31 -0
- package/dist/cjs/apis/getFriendOnlines.cjs +40 -0
- package/dist/cjs/apis/getFriendRecommendations.cjs +32 -0
- package/dist/cjs/apis/getFriendRequestStatus.cjs +30 -0
- package/dist/cjs/apis/getGroupBlockedMember.cjs +34 -0
- package/dist/cjs/apis/getGroupInfo.cjs +37 -0
- package/dist/cjs/apis/getGroupInviteBoxInfo.cjs +43 -0
- package/dist/cjs/apis/getGroupInviteBoxList.cjs +36 -0
- package/dist/cjs/apis/getGroupLinkDetail.cjs +30 -0
- package/dist/cjs/apis/getGroupLinkInfo.cjs +33 -0
- package/dist/cjs/apis/getGroupMembersInfo.cjs +29 -0
- package/dist/cjs/apis/getHiddenConversations.cjs +28 -0
- package/dist/cjs/apis/getLabels.cjs +33 -0
- package/dist/cjs/apis/getLastMessage.cjs +25 -0
- package/dist/cjs/apis/getListBoard.cjs +58 -0
- package/dist/cjs/apis/getListReminder.cjs +60 -0
- package/dist/cjs/apis/getMute.cjs +27 -0
- package/dist/cjs/apis/getOwnId.cjs +9 -0
- package/dist/cjs/apis/getPendingGroupMembers.cjs +32 -0
- package/dist/cjs/apis/getPinConversations.cjs +27 -0
- package/dist/cjs/apis/getPollDetail.cjs +35 -0
- package/dist/cjs/apis/getProductCatalogList.cjs +38 -0
- package/dist/cjs/apis/getQR.cjs +34 -0
- package/dist/cjs/apis/getQuickMessageList.cjs +29 -0
- package/dist/cjs/apis/getRecommendFriends.cjs +25 -0
- package/dist/cjs/apis/getRelatedFriendGroup.cjs +35 -0
- package/dist/cjs/apis/getReminder.cjs +30 -0
- package/dist/cjs/apis/getReminderResponses.cjs +29 -0
- package/dist/cjs/apis/getSentFriendRequest.cjs +29 -0
- package/dist/cjs/apis/getSettings.cjs +25 -0
- package/dist/cjs/apis/getStickers.cjs +45 -0
- package/dist/cjs/apis/getStickersDetail.cjs +45 -0
- package/dist/cjs/apis/getUnreadMark.cjs +35 -0
- package/dist/cjs/apis/getUserInfo.cjs +47 -0
- package/dist/cjs/apis/inviteUserToGroups.cjs +35 -0
- package/dist/cjs/apis/joinGroupInviteBox.cjs +30 -0
- package/dist/cjs/apis/joinGroupLink.cjs +32 -0
- package/dist/cjs/apis/keepAlive.cjs +27 -0
- package/dist/cjs/apis/lastOnline.cjs +31 -0
- package/dist/cjs/apis/leaveGroup.cjs +38 -0
- package/dist/cjs/apis/lockPoll.cjs +33 -0
- package/dist/cjs/apis/parseLink.cjs +32 -0
- package/dist/cjs/apis/rejectFriendRequest.cjs +32 -0
- package/dist/cjs/apis/removeFriend.cjs +33 -0
- package/dist/cjs/apis/removeFriendAlias.cjs +29 -0
- package/dist/cjs/apis/removeGroupBlockedMember.cjs +33 -0
- package/dist/cjs/apis/removeGroupDeputy.cjs +35 -0
- package/dist/cjs/apis/removeQuickMessage.cjs +32 -0
- package/dist/cjs/apis/removeReminder.cjs +53 -0
- package/dist/cjs/apis/removeUnreadMark.cjs +63 -0
- package/dist/cjs/apis/removeUserFromGroup.cjs +39 -0
- package/dist/cjs/apis/resetHiddenConversPin.cjs +25 -0
- package/dist/cjs/apis/reuseAvatar.cjs +31 -0
- package/dist/cjs/apis/reviewPendingMemberRequest.cjs +33 -11
- package/dist/cjs/apis/sendBankCard.cjs +50 -0
- package/dist/cjs/apis/sendCard.cjs +72 -0
- package/dist/cjs/apis/sendDeliveredEvent.cjs +68 -0
- package/dist/cjs/apis/sendFriendRequest.cjs +44 -0
- package/dist/cjs/apis/sendLink.cjs +70 -0
- package/dist/cjs/apis/sendMessage.cjs +437 -11
- package/dist/cjs/apis/sendReport.cjs +48 -10
- package/dist/cjs/apis/sendSeenEvent.cjs +76 -0
- package/dist/cjs/apis/sendSticker.cjs +69 -0
- package/dist/cjs/apis/sendTypingEvent.cjs +46 -0
- package/dist/cjs/apis/sendVideo.cjs +131 -0
- package/dist/cjs/apis/sendVoice.cjs +86 -0
- package/dist/cjs/apis/setArchivedConversations.cjs +39 -0
- package/dist/cjs/apis/setHiddenConversations.cjs +52 -0
- package/dist/cjs/apis/setMute.cjs +57 -10
- package/dist/cjs/apis/setPinnedConversations.cjs +47 -0
- package/dist/cjs/apis/sharePoll.cjs +33 -0
- package/dist/cjs/apis/unblockUser.cjs +33 -0
- package/dist/cjs/apis/undo.cjs +55 -0
- package/dist/cjs/apis/undoFriendRequest.cjs +32 -0
- package/dist/cjs/apis/updateActiveStatus.cjs +32 -0
- package/dist/cjs/apis/updateAutoDeleteChat.cjs +35 -10
- package/dist/cjs/apis/updateAutoReply.cjs +43 -0
- package/dist/cjs/apis/updateCatalog.cjs +35 -0
- package/dist/cjs/apis/updateGroupSettings.cjs +48 -0
- package/dist/cjs/apis/updateHiddenConversPin.cjs +35 -0
- package/dist/cjs/apis/updateLabels.cjs +39 -0
- package/dist/cjs/apis/updateLang.cjs +27 -11
- package/dist/cjs/apis/updateProductCatalog.cjs +56 -0
- package/dist/cjs/apis/updateProfile.cjs +48 -0
- package/dist/cjs/apis/updateQuickMessage.cjs +66 -0
- package/dist/cjs/apis/updateSettings.cjs +77 -11
- package/dist/cjs/apis/uploadAttachment.cjs +208 -0
- package/dist/cjs/apis/uploadProductPhoto.cjs +50 -0
- package/dist/cjs/apis/votePoll.cjs +34 -0
- package/dist/cjs/apis.cjs +292 -0
- package/dist/cjs/context.cjs +15 -0
- package/dist/cjs/core/enums/common.cjs +14 -0
- package/dist/cjs/core/utils/index.cjs +33 -0
- package/dist/cjs/models/GroupEvent.cjs +2 -4
- package/dist/cjs/utils.cjs +229 -3
- package/dist/cjs/zalo.cjs +18 -7
- package/dist/index.d.ts +1 -0
- package/dist/models/GroupEvent.d.ts +2 -2
- package/dist/models/GroupEvent.js +2 -4
- package/dist/models/Message.d.ts +6 -0
- package/dist/zalo.d.ts +17 -10
- package/dist/zalo.js +19 -8
- package/package.json +1 -1
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var axios = require('axios');
|
|
4
|
+
var fileType = require('file-type');
|
|
5
|
+
var moment = require('moment');
|
|
6
|
+
|
|
7
|
+
async function getFileUpload(url) {
|
|
8
|
+
try {
|
|
9
|
+
const response = await axios.request({
|
|
10
|
+
url: url,
|
|
11
|
+
method: 'GET',
|
|
12
|
+
responseType: 'arraybuffer',
|
|
13
|
+
family: 4,
|
|
14
|
+
});
|
|
15
|
+
const fileBuffer = Buffer.from(response.data, 'binary');
|
|
16
|
+
const buffer = fileBuffer;
|
|
17
|
+
const extensionFile = await fileType.fileTypeFromBuffer(fileBuffer);
|
|
18
|
+
const originalname = `${moment().valueOf()}`;
|
|
19
|
+
const size = Buffer.byteLength(buffer);
|
|
20
|
+
return {
|
|
21
|
+
originalname: originalname,
|
|
22
|
+
buffer: buffer,
|
|
23
|
+
size: size,
|
|
24
|
+
mimetype: (extensionFile === null || extensionFile === void 0 ? void 0 : extensionFile.mime) || '',
|
|
25
|
+
ext: (extensionFile === null || extensionFile === void 0 ? void 0 : extensionFile.ext) || '',
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
catch (e) {
|
|
29
|
+
throw new Error(e);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
exports.getFileUpload = getFileUpload;
|
|
@@ -28,13 +28,11 @@ exports.GroupEventType = void 0;
|
|
|
28
28
|
})(exports.GroupEventType || (exports.GroupEventType = {}));
|
|
29
29
|
function initializeGroupEvent(uid, data, type, act) {
|
|
30
30
|
var _a;
|
|
31
|
-
const threadId =
|
|
31
|
+
const threadId = 'group_id' in data ? data.group_id : data.groupId;
|
|
32
32
|
if (type == exports.GroupEventType.JOIN_REQUEST) {
|
|
33
33
|
return { type, act, data: data, threadId, isSelf: false };
|
|
34
34
|
}
|
|
35
|
-
else if (type == exports.GroupEventType.NEW_PIN_TOPIC ||
|
|
36
|
-
type == exports.GroupEventType.UNPIN_TOPIC ||
|
|
37
|
-
type == exports.GroupEventType.UPDATE_PIN_TOPIC) {
|
|
35
|
+
else if (type == exports.GroupEventType.NEW_PIN_TOPIC || type == exports.GroupEventType.UNPIN_TOPIC || type == exports.GroupEventType.UPDATE_PIN_TOPIC) {
|
|
38
36
|
return {
|
|
39
37
|
type,
|
|
40
38
|
act,
|
package/dist/cjs/utils.cjs
CHANGED
|
@@ -4,11 +4,12 @@ var cryptojs = require('crypto-js');
|
|
|
4
4
|
require('json-bigint');
|
|
5
5
|
var crypto = require('node:crypto');
|
|
6
6
|
require('node:fs');
|
|
7
|
-
require('node:path');
|
|
7
|
+
var path = require('node:path');
|
|
8
8
|
require('pako');
|
|
9
|
-
require('spark-md5');
|
|
9
|
+
var SparkMD5 = require('spark-md5');
|
|
10
10
|
var ToughCookie = require('tough-cookie');
|
|
11
|
-
require('sharp');
|
|
11
|
+
var sharp = require('sharp');
|
|
12
|
+
var context = require('./context.cjs');
|
|
12
13
|
var ZaloApiError = require('./Errors/ZaloApiError.cjs');
|
|
13
14
|
require('./models/FriendEvent.cjs');
|
|
14
15
|
require('./models/GroupEvent.cjs');
|
|
@@ -191,6 +192,35 @@ function decodeRespAES(key, data) {
|
|
|
191
192
|
padding: cryptojs.pad.Pkcs7,
|
|
192
193
|
}).toString(cryptojs.enc.Utf8);
|
|
193
194
|
}
|
|
195
|
+
function encodeAES(secretKey, data, t = 0) {
|
|
196
|
+
try {
|
|
197
|
+
const key = cryptojs.enc.Base64.parse(secretKey);
|
|
198
|
+
return cryptojs.AES.encrypt(data, key, {
|
|
199
|
+
iv: cryptojs.enc.Hex.parse('00000000000000000000000000000000'),
|
|
200
|
+
mode: cryptojs.mode.CBC,
|
|
201
|
+
padding: cryptojs.pad.Pkcs7,
|
|
202
|
+
}).ciphertext.toString(cryptojs.enc.Base64);
|
|
203
|
+
}
|
|
204
|
+
catch (_a) {
|
|
205
|
+
return t < 3 ? encodeAES(secretKey, data, t + 1) : null;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
function decodeAES(secretKey, data, t = 0) {
|
|
209
|
+
try {
|
|
210
|
+
data = decodeURIComponent(data);
|
|
211
|
+
const key = cryptojs.enc.Base64.parse(secretKey);
|
|
212
|
+
return cryptojs.AES.decrypt({
|
|
213
|
+
ciphertext: cryptojs.enc.Base64.parse(data),
|
|
214
|
+
}, key, {
|
|
215
|
+
iv: cryptojs.enc.Hex.parse('00000000000000000000000000000000'),
|
|
216
|
+
mode: cryptojs.mode.CBC,
|
|
217
|
+
padding: cryptojs.pad.Pkcs7,
|
|
218
|
+
}).toString(cryptojs.enc.Utf8);
|
|
219
|
+
}
|
|
220
|
+
catch (_a) {
|
|
221
|
+
return t < 3 ? decodeAES(secretKey, data, t + 1) : null;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
194
224
|
async function getDefaultHeaders(ctx, origin = 'https://chat.zalo.me') {
|
|
195
225
|
if (!ctx.cookie)
|
|
196
226
|
throw new ZaloApiError.ZaloApiError('Cookie is not available');
|
|
@@ -247,6 +277,45 @@ async function request(ctx, url, options, raw = false) {
|
|
|
247
277
|
}
|
|
248
278
|
return response;
|
|
249
279
|
}
|
|
280
|
+
async function getImageMetaData(file) {
|
|
281
|
+
const imageData = await sharp(file.buffer).metadata();
|
|
282
|
+
return {
|
|
283
|
+
fileName: file.originalname,
|
|
284
|
+
totalSize: imageData.size,
|
|
285
|
+
width: imageData.width,
|
|
286
|
+
height: imageData.height,
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
async function getGifMetaData(file) {
|
|
290
|
+
const gifData = await sharp(file.buffer).metadata();
|
|
291
|
+
return {
|
|
292
|
+
fileName: file.originalname,
|
|
293
|
+
totalSize: gifData.size,
|
|
294
|
+
width: gifData.width,
|
|
295
|
+
height: gifData.height,
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
function getMd5LargeFileObject(file) {
|
|
299
|
+
return new Promise(async (resolve, reject) => {
|
|
300
|
+
let chunkSize = 2097152, // Read in chunks of 2MB
|
|
301
|
+
chunks = Math.ceil(file.size / chunkSize), currentChunk = 0, spark = new SparkMD5.ArrayBuffer(), buffer = file.buffer;
|
|
302
|
+
function loadNext() {
|
|
303
|
+
const start = currentChunk * chunkSize, end = start + chunkSize >= file.size ? file.size : start + chunkSize;
|
|
304
|
+
spark.append(buffer.subarray(start, end));
|
|
305
|
+
currentChunk++;
|
|
306
|
+
if (currentChunk < chunks) {
|
|
307
|
+
loadNext();
|
|
308
|
+
}
|
|
309
|
+
else {
|
|
310
|
+
resolve({
|
|
311
|
+
currentChunk,
|
|
312
|
+
data: spark.end(),
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
loadNext();
|
|
317
|
+
});
|
|
318
|
+
}
|
|
250
319
|
const logger = (ctx) => ({
|
|
251
320
|
verbose: (...args) => {
|
|
252
321
|
if (ctx.options.logging)
|
|
@@ -274,9 +343,151 @@ const logger = (ctx) => ({
|
|
|
274
343
|
console.log(`\x1b[90m[${now}]\x1b[0m`, ...args);
|
|
275
344
|
},
|
|
276
345
|
});
|
|
346
|
+
function getClientMessageType(msgType) {
|
|
347
|
+
if (msgType === 'webchat')
|
|
348
|
+
return 1;
|
|
349
|
+
if (msgType === 'chat.voice')
|
|
350
|
+
return 31;
|
|
351
|
+
if (msgType === 'chat.photo')
|
|
352
|
+
return 32;
|
|
353
|
+
if (msgType === 'chat.sticker')
|
|
354
|
+
return 36;
|
|
355
|
+
if (msgType === 'chat.doodle')
|
|
356
|
+
return 37;
|
|
357
|
+
if (msgType === 'chat.recommended')
|
|
358
|
+
return 38;
|
|
359
|
+
if (msgType === 'chat.link')
|
|
360
|
+
return 38; // don't know || if (msgType === "chat.link") return 1;
|
|
361
|
+
if (msgType === 'chat.video.msg')
|
|
362
|
+
return 44; // not sure
|
|
363
|
+
if (msgType === 'share.file')
|
|
364
|
+
return 46;
|
|
365
|
+
if (msgType === 'chat.gif')
|
|
366
|
+
return 49;
|
|
367
|
+
if (msgType === 'chat.location.new')
|
|
368
|
+
return 43;
|
|
369
|
+
return 1;
|
|
370
|
+
}
|
|
371
|
+
function strPadLeft(e, t, n) {
|
|
372
|
+
const a = (e = '' + e).length;
|
|
373
|
+
return a === n ? e : a > n ? e.slice(-n) : t.repeat(n - a) + e;
|
|
374
|
+
}
|
|
375
|
+
function formatTime(format, timestamp = Date.now()) {
|
|
376
|
+
const date = new Date(timestamp);
|
|
377
|
+
// using lib Intl
|
|
378
|
+
const options = {
|
|
379
|
+
year: 'numeric',
|
|
380
|
+
month: '2-digit',
|
|
381
|
+
day: '2-digit',
|
|
382
|
+
hour: '2-digit',
|
|
383
|
+
minute: '2-digit',
|
|
384
|
+
second: '2-digit',
|
|
385
|
+
// hour12: false, // true or false is same <(")
|
|
386
|
+
};
|
|
387
|
+
const formatted = new Intl.DateTimeFormat('vi-VN', options).format(date);
|
|
388
|
+
if (format.includes('%H') || format.includes('%d')) {
|
|
389
|
+
return format
|
|
390
|
+
.replace('%H', date.getHours().toString().padStart(2, '0'))
|
|
391
|
+
.replace('%M', date.getMinutes().toString().padStart(2, '0'))
|
|
392
|
+
.replace('%S', date.getSeconds().toString().padStart(2, '0'))
|
|
393
|
+
.replace('%d', date.getDate().toString().padStart(2, '0'))
|
|
394
|
+
.replace('%m', (date.getMonth() + 1).toString().padStart(2, '0'))
|
|
395
|
+
.replace('%Y', date.getFullYear().toString());
|
|
396
|
+
}
|
|
397
|
+
return formatted;
|
|
398
|
+
}
|
|
399
|
+
function getFullTimeFromMillisecond(e) {
|
|
400
|
+
const t = new Date(e);
|
|
401
|
+
return strPadLeft(t.getHours(), '0', 2) + ':' + strPadLeft(t.getMinutes(), '0', 2) + ' ' + strPadLeft(t.getDate(), '0', 2) + '/' + strPadLeft(t.getMonth() + 1, '0', 2) + '/' + t.getFullYear();
|
|
402
|
+
}
|
|
403
|
+
function getFileExtension(e) {
|
|
404
|
+
return path.extname(e).slice(1);
|
|
405
|
+
}
|
|
406
|
+
function removeUndefinedKeys(e) {
|
|
407
|
+
for (const t in e)
|
|
408
|
+
if (e[t] === undefined)
|
|
409
|
+
delete e[t];
|
|
410
|
+
return e;
|
|
411
|
+
}
|
|
412
|
+
async function handleZaloResponse(ctx, response, isEncrypted = true) {
|
|
413
|
+
const result = {
|
|
414
|
+
data: null,
|
|
415
|
+
error: null,
|
|
416
|
+
};
|
|
417
|
+
if (!response.ok) {
|
|
418
|
+
result.error = {
|
|
419
|
+
message: 'Request failed with status code ' + response.status,
|
|
420
|
+
};
|
|
421
|
+
return result;
|
|
422
|
+
}
|
|
423
|
+
try {
|
|
424
|
+
const jsonData = await response.json();
|
|
425
|
+
if (jsonData.error_code != 0) {
|
|
426
|
+
result.error = {
|
|
427
|
+
message: jsonData.error_message,
|
|
428
|
+
code: jsonData.error_code,
|
|
429
|
+
};
|
|
430
|
+
return result;
|
|
431
|
+
}
|
|
432
|
+
const decodedData = isEncrypted ? JSON.parse(decodeAES(ctx.secretKey, jsonData.data)) : jsonData;
|
|
433
|
+
if (decodedData.error_code != 0) {
|
|
434
|
+
result.error = {
|
|
435
|
+
message: decodedData.error_message,
|
|
436
|
+
code: decodedData.error_code,
|
|
437
|
+
};
|
|
438
|
+
return result;
|
|
439
|
+
}
|
|
440
|
+
result.data = decodedData.data;
|
|
441
|
+
}
|
|
442
|
+
catch (error) {
|
|
443
|
+
logger(ctx).error('Failed to parse response data:', error);
|
|
444
|
+
result.error = {
|
|
445
|
+
message: 'Failed to parse response data',
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
return result;
|
|
449
|
+
}
|
|
450
|
+
async function resolveResponse(ctx, res, cb, isEncrypted) {
|
|
451
|
+
const result = await handleZaloResponse(ctx, res, isEncrypted);
|
|
452
|
+
if (result.error)
|
|
453
|
+
throw new ZaloApiError.ZaloApiError(result.error.message, result.error.code);
|
|
454
|
+
if (cb)
|
|
455
|
+
return cb(result);
|
|
456
|
+
return result.data;
|
|
457
|
+
}
|
|
458
|
+
function apiFactory() {
|
|
459
|
+
return (callback) => {
|
|
460
|
+
return (ctx, api) => {
|
|
461
|
+
if (!context.isContextSession(ctx))
|
|
462
|
+
throw new ZaloApiError.ZaloApiError('Invalid context ' + JSON.stringify(ctx, null, 2));
|
|
463
|
+
const utils = {
|
|
464
|
+
makeURL(baseURL, params, apiVersion) {
|
|
465
|
+
return makeURL(ctx, baseURL, params, apiVersion);
|
|
466
|
+
},
|
|
467
|
+
encodeAES(data, t) {
|
|
468
|
+
return encodeAES(ctx.secretKey, data, t);
|
|
469
|
+
},
|
|
470
|
+
request(url, options, raw) {
|
|
471
|
+
return request(ctx, url, options, raw);
|
|
472
|
+
},
|
|
473
|
+
logger: logger(ctx),
|
|
474
|
+
resolve: (res, cb, isEncrypted) => resolveResponse(ctx, res, cb, isEncrypted),
|
|
475
|
+
};
|
|
476
|
+
return callback(api, ctx, utils);
|
|
477
|
+
};
|
|
478
|
+
};
|
|
479
|
+
}
|
|
277
480
|
function generateZaloUUID(userAgent) {
|
|
278
481
|
return crypto.randomUUID() + '-' + cryptojs.MD5(userAgent).toString();
|
|
279
482
|
}
|
|
483
|
+
/**
|
|
484
|
+
* Encrypts a 4-digit PIN to a 32-character hex string
|
|
485
|
+
* @param pin 4-digit PIN number
|
|
486
|
+
* @returns 32-character hex string
|
|
487
|
+
*/
|
|
488
|
+
function encryptPin(pin) {
|
|
489
|
+
return crypto.createHash('md5').update(pin).digest('hex');
|
|
490
|
+
}
|
|
280
491
|
function getSecChUaPlatform(userAgent = '') {
|
|
281
492
|
const platformRegex = /\(([^)]+)\)/;
|
|
282
493
|
const platformMatch = userAgent.match(platformRegex);
|
|
@@ -308,13 +519,28 @@ function handleQueueStatus(queueStatus) {
|
|
|
308
519
|
}
|
|
309
520
|
|
|
310
521
|
exports.ParamsEncryptor = ParamsEncryptor;
|
|
522
|
+
exports.apiFactory = apiFactory;
|
|
523
|
+
exports.decodeAES = decodeAES;
|
|
311
524
|
exports.decryptResp = decryptResp;
|
|
525
|
+
exports.encodeAES = encodeAES;
|
|
526
|
+
exports.encryptPin = encryptPin;
|
|
527
|
+
exports.formatTime = formatTime;
|
|
312
528
|
exports.generateZaloUUID = generateZaloUUID;
|
|
529
|
+
exports.getClientMessageType = getClientMessageType;
|
|
313
530
|
exports.getDefaultHeaders = getDefaultHeaders;
|
|
531
|
+
exports.getFileExtension = getFileExtension;
|
|
532
|
+
exports.getFullTimeFromMillisecond = getFullTimeFromMillisecond;
|
|
533
|
+
exports.getGifMetaData = getGifMetaData;
|
|
534
|
+
exports.getImageMetaData = getImageMetaData;
|
|
535
|
+
exports.getMd5LargeFileObject = getMd5LargeFileObject;
|
|
314
536
|
exports.getSecChUaPlatform = getSecChUaPlatform;
|
|
315
537
|
exports.getSignKey = getSignKey;
|
|
316
538
|
exports.handleQueueStatus = handleQueueStatus;
|
|
539
|
+
exports.handleZaloResponse = handleZaloResponse;
|
|
317
540
|
exports.hasOwn = hasOwn;
|
|
318
541
|
exports.logger = logger;
|
|
319
542
|
exports.makeURL = makeURL;
|
|
543
|
+
exports.removeUndefinedKeys = removeUndefinedKeys;
|
|
320
544
|
exports.request = request;
|
|
545
|
+
exports.resolveResponse = resolveResponse;
|
|
546
|
+
exports.strPadLeft = strPadLeft;
|
package/dist/cjs/zalo.cjs
CHANGED
|
@@ -6,6 +6,7 @@ var loginQR = require('./apis/loginQR.cjs');
|
|
|
6
6
|
var context = require('./context.cjs');
|
|
7
7
|
var ZaloApiError = require('./Errors/ZaloApiError.cjs');
|
|
8
8
|
var utils = require('./utils.cjs');
|
|
9
|
+
var apis = require('./apis.cjs');
|
|
9
10
|
|
|
10
11
|
function _interopNamespaceDefault(e) {
|
|
11
12
|
var n = Object.create(null);
|
|
@@ -59,7 +60,7 @@ class Zalo {
|
|
|
59
60
|
}
|
|
60
61
|
}
|
|
61
62
|
async loginCookie(props) {
|
|
62
|
-
const { ctx, credentials,
|
|
63
|
+
const { ctx, credentials, imei, getPreviousImei, uploadCompleted, onUploadCompleted } = props;
|
|
63
64
|
this.validateParams(credentials);
|
|
64
65
|
ctx.imei = credentials.imei;
|
|
65
66
|
ctx.cookie = this.parseCookies(credentials.cookie);
|
|
@@ -69,10 +70,12 @@ class Zalo {
|
|
|
69
70
|
ctx.imei = imei;
|
|
70
71
|
}
|
|
71
72
|
let serverInfo = await login.getServerInfo(ctx, this.enableEncryptParam).catch(() => null);
|
|
72
|
-
if (typeof getPreviousImei === 'function') {
|
|
73
|
+
if (typeof getPreviousImei === 'function' && !imei) {
|
|
73
74
|
const previousImei = await getPreviousImei(serverInfo);
|
|
74
|
-
|
|
75
|
-
|
|
75
|
+
if (previousImei) {
|
|
76
|
+
ctx.imei = previousImei;
|
|
77
|
+
serverInfo = await login.getServerInfo(ctx, this.enableEncryptParam).catch(() => null);
|
|
78
|
+
}
|
|
76
79
|
}
|
|
77
80
|
const loginData = await login.login(ctx, this.enableEncryptParam);
|
|
78
81
|
const loginInfo = loginData === null || loginData === void 0 ? void 0 : loginData.data;
|
|
@@ -86,7 +89,13 @@ class Zalo {
|
|
|
86
89
|
if (!context.isContextSession(ctx))
|
|
87
90
|
throw new ZaloApiError.ZaloApiError('Khởi tạo ngữ cảnh thất bại.');
|
|
88
91
|
utils.logger(ctx).info('Logged in as', loginInfo.uid);
|
|
89
|
-
return {
|
|
92
|
+
return new apis.ZaloAPI({
|
|
93
|
+
ctx,
|
|
94
|
+
zpwServiceMap: loginInfo.zpw_service_map_v3,
|
|
95
|
+
wsUrls: loginInfo.zpw_ws,
|
|
96
|
+
uploadCompleted,
|
|
97
|
+
onUploadCompleted,
|
|
98
|
+
});
|
|
90
99
|
}
|
|
91
100
|
async generateQR(options) {
|
|
92
101
|
if (!options)
|
|
@@ -105,7 +114,7 @@ class Zalo {
|
|
|
105
114
|
return await loginQR.waitingScan(ctx, loginVersion, code);
|
|
106
115
|
}
|
|
107
116
|
async waitingConfirm(props) {
|
|
108
|
-
const { ctx, loginVersion, code,
|
|
117
|
+
const { ctx, loginVersion, code, imei, getPreviousImei } = props;
|
|
109
118
|
const loginQRResult = await loginQR.handleWaitingConfirm(ctx, loginVersion, code);
|
|
110
119
|
if (!loginQRResult || !(ctx === null || ctx === void 0 ? void 0 : ctx.userAgent))
|
|
111
120
|
return null;
|
|
@@ -117,11 +126,13 @@ class Zalo {
|
|
|
117
126
|
userAgent: ctx.userAgent,
|
|
118
127
|
language: ctx.language,
|
|
119
128
|
},
|
|
120
|
-
sessionId: sessionId,
|
|
121
129
|
imei: imei,
|
|
122
130
|
getPreviousImei: getPreviousImei,
|
|
123
131
|
});
|
|
124
132
|
}
|
|
133
|
+
async getUserInfo(ctx) {
|
|
134
|
+
return await loginQR.getUserInfo(ctx);
|
|
135
|
+
}
|
|
125
136
|
}
|
|
126
137
|
|
|
127
138
|
exports.Zalo = Zalo;
|
package/dist/index.d.ts
CHANGED
|
@@ -134,6 +134,7 @@ export type { FileData, ImageData, UploadAttachmentResponse, UploadAttachmentTyp
|
|
|
134
134
|
export type { UploadProductPhotoPayload, UploadProductPhotoResponse } from './apis/uploadProductPhoto.js';
|
|
135
135
|
export type { VotePollResponse } from './apis/votePoll.js';
|
|
136
136
|
export type { CustomAPICallback, CustomAPIProps } from './apis/custom.js';
|
|
137
|
+
export type { Listener } from './apis/listen.js';
|
|
137
138
|
export { CloseReason } from './models/Listen.js';
|
|
138
139
|
export { ReviewPendingMemberRequestStatus } from './apis/reviewPendingMemberRequest.js';
|
|
139
140
|
export { TextStyle, Urgency } from './apis/sendMessage.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { GroupSetting, GroupTopic } from
|
|
2
|
-
import type { ReminderGroup } from
|
|
1
|
+
import type { GroupSetting, GroupTopic } from './Group.js';
|
|
2
|
+
import type { ReminderGroup } from './Reminder.js';
|
|
3
3
|
export declare enum GroupEventType {
|
|
4
4
|
JOIN_REQUEST = "join_request",
|
|
5
5
|
JOIN = "join",
|
|
@@ -26,13 +26,11 @@ export var GroupEventType;
|
|
|
26
26
|
})(GroupEventType || (GroupEventType = {}));
|
|
27
27
|
export function initializeGroupEvent(uid, data, type, act) {
|
|
28
28
|
var _a;
|
|
29
|
-
const threadId =
|
|
29
|
+
const threadId = 'group_id' in data ? data.group_id : data.groupId;
|
|
30
30
|
if (type == GroupEventType.JOIN_REQUEST) {
|
|
31
31
|
return { type, act, data: data, threadId, isSelf: false };
|
|
32
32
|
}
|
|
33
|
-
else if (type == GroupEventType.NEW_PIN_TOPIC ||
|
|
34
|
-
type == GroupEventType.UNPIN_TOPIC ||
|
|
35
|
-
type == GroupEventType.UPDATE_PIN_TOPIC) {
|
|
33
|
+
else if (type == GroupEventType.NEW_PIN_TOPIC || type == GroupEventType.UNPIN_TOPIC || type == GroupEventType.UPDATE_PIN_TOPIC) {
|
|
36
34
|
return {
|
|
37
35
|
type,
|
|
38
36
|
act,
|
package/dist/models/Message.d.ts
CHANGED
package/dist/zalo.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as ToughCookie from 'tough-cookie';
|
|
2
2
|
import { type ContextBase, type Options, type ServerInfo } from './context.js';
|
|
3
|
+
import { ZaloAPI, type ZaloAPIOptions } from './apis.js';
|
|
3
4
|
export type Credentials = {
|
|
4
5
|
imei: string;
|
|
5
6
|
cookie: ToughCookie.Cookie[] | ToughCookie.SerializedCookie[] | {
|
|
@@ -13,16 +14,16 @@ export interface WaitingConfirmProps {
|
|
|
13
14
|
ctx: ContextBase;
|
|
14
15
|
loginVersion: string;
|
|
15
16
|
code: string;
|
|
16
|
-
sessionId: string;
|
|
17
17
|
imei?: string;
|
|
18
18
|
getPreviousImei?: (serverInfo: ServerInfo) => Promise<string>;
|
|
19
19
|
}
|
|
20
20
|
export interface LoginCookieProps {
|
|
21
21
|
ctx: ContextBase;
|
|
22
22
|
credentials: Credentials;
|
|
23
|
-
sessionId: string;
|
|
24
23
|
imei?: string;
|
|
25
24
|
getPreviousImei?: (serverInfo: ServerInfo) => Promise<string>;
|
|
25
|
+
uploadCompleted?: ZaloAPIOptions['uploadCompleted'];
|
|
26
|
+
onUploadCompleted?: ZaloAPIOptions['onUploadCompleted'];
|
|
26
27
|
}
|
|
27
28
|
export declare class Zalo {
|
|
28
29
|
private options;
|
|
@@ -30,10 +31,7 @@ export declare class Zalo {
|
|
|
30
31
|
constructor(options?: Partial<Options>);
|
|
31
32
|
private parseCookies;
|
|
32
33
|
private validateParams;
|
|
33
|
-
loginCookie(props: LoginCookieProps): Promise<
|
|
34
|
-
ctx: import("./context.js").ContextSession;
|
|
35
|
-
loginInfo: import("./context.js").LoginInfo;
|
|
36
|
-
}>;
|
|
34
|
+
loginCookie(props: LoginCookieProps): Promise<ZaloAPI>;
|
|
37
35
|
generateQR(options?: {
|
|
38
36
|
userAgent?: string;
|
|
39
37
|
language?: string;
|
|
@@ -57,8 +55,17 @@ export declare class Zalo {
|
|
|
57
55
|
error_code: number;
|
|
58
56
|
error_message: string;
|
|
59
57
|
} | undefined>;
|
|
60
|
-
waitingConfirm(props: WaitingConfirmProps): Promise<
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
58
|
+
waitingConfirm(props: WaitingConfirmProps): Promise<ZaloAPI | null>;
|
|
59
|
+
getUserInfo(ctx: ContextBase): Promise<{
|
|
60
|
+
data: {
|
|
61
|
+
logged: boolean;
|
|
62
|
+
session_chat_valid: boolean;
|
|
63
|
+
info: {
|
|
64
|
+
name: string;
|
|
65
|
+
avatar: string;
|
|
66
|
+
};
|
|
67
|
+
} | null;
|
|
68
|
+
error_code: number;
|
|
69
|
+
error_message: string;
|
|
70
|
+
} | undefined>;
|
|
64
71
|
}
|
package/dist/zalo.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import * as ToughCookie from 'tough-cookie';
|
|
2
2
|
import { getServerInfo, login } from './apis/login.js';
|
|
3
|
-
import { generateQR, handleWaitingConfirm, waitingScan } from './apis/loginQR.js';
|
|
3
|
+
import { generateQR, getUserInfo, handleWaitingConfirm, waitingScan } from './apis/loginQR.js';
|
|
4
4
|
import { createContext, isContextSession } from './context.js';
|
|
5
5
|
import { ZaloApiError } from './Errors/ZaloApiError.js';
|
|
6
6
|
import { generateZaloUUID, logger } from './utils.js';
|
|
7
|
+
import { ZaloAPI } from './apis.js';
|
|
7
8
|
export class Zalo {
|
|
8
9
|
constructor(options = {}) {
|
|
9
10
|
this.options = options;
|
|
@@ -37,7 +38,7 @@ export class Zalo {
|
|
|
37
38
|
}
|
|
38
39
|
}
|
|
39
40
|
async loginCookie(props) {
|
|
40
|
-
const { ctx, credentials,
|
|
41
|
+
const { ctx, credentials, imei, getPreviousImei, uploadCompleted, onUploadCompleted } = props;
|
|
41
42
|
this.validateParams(credentials);
|
|
42
43
|
ctx.imei = credentials.imei;
|
|
43
44
|
ctx.cookie = this.parseCookies(credentials.cookie);
|
|
@@ -47,10 +48,12 @@ export class Zalo {
|
|
|
47
48
|
ctx.imei = imei;
|
|
48
49
|
}
|
|
49
50
|
let serverInfo = await getServerInfo(ctx, this.enableEncryptParam).catch(() => null);
|
|
50
|
-
if (typeof getPreviousImei === 'function') {
|
|
51
|
+
if (typeof getPreviousImei === 'function' && !imei) {
|
|
51
52
|
const previousImei = await getPreviousImei(serverInfo);
|
|
52
|
-
|
|
53
|
-
|
|
53
|
+
if (previousImei) {
|
|
54
|
+
ctx.imei = previousImei;
|
|
55
|
+
serverInfo = await getServerInfo(ctx, this.enableEncryptParam).catch(() => null);
|
|
56
|
+
}
|
|
54
57
|
}
|
|
55
58
|
const loginData = await login(ctx, this.enableEncryptParam);
|
|
56
59
|
const loginInfo = loginData === null || loginData === void 0 ? void 0 : loginData.data;
|
|
@@ -64,7 +67,13 @@ export class Zalo {
|
|
|
64
67
|
if (!isContextSession(ctx))
|
|
65
68
|
throw new ZaloApiError('Khởi tạo ngữ cảnh thất bại.');
|
|
66
69
|
logger(ctx).info('Logged in as', loginInfo.uid);
|
|
67
|
-
return {
|
|
70
|
+
return new ZaloAPI({
|
|
71
|
+
ctx,
|
|
72
|
+
zpwServiceMap: loginInfo.zpw_service_map_v3,
|
|
73
|
+
wsUrls: loginInfo.zpw_ws,
|
|
74
|
+
uploadCompleted,
|
|
75
|
+
onUploadCompleted,
|
|
76
|
+
});
|
|
68
77
|
}
|
|
69
78
|
async generateQR(options) {
|
|
70
79
|
if (!options)
|
|
@@ -83,7 +92,7 @@ export class Zalo {
|
|
|
83
92
|
return await waitingScan(ctx, loginVersion, code);
|
|
84
93
|
}
|
|
85
94
|
async waitingConfirm(props) {
|
|
86
|
-
const { ctx, loginVersion, code,
|
|
95
|
+
const { ctx, loginVersion, code, imei, getPreviousImei } = props;
|
|
87
96
|
const loginQRResult = await handleWaitingConfirm(ctx, loginVersion, code);
|
|
88
97
|
if (!loginQRResult || !(ctx === null || ctx === void 0 ? void 0 : ctx.userAgent))
|
|
89
98
|
return null;
|
|
@@ -95,9 +104,11 @@ export class Zalo {
|
|
|
95
104
|
userAgent: ctx.userAgent,
|
|
96
105
|
language: ctx.language,
|
|
97
106
|
},
|
|
98
|
-
sessionId: sessionId,
|
|
99
107
|
imei: imei,
|
|
100
108
|
getPreviousImei: getPreviousImei,
|
|
101
109
|
});
|
|
102
110
|
}
|
|
111
|
+
async getUserInfo(ctx) {
|
|
112
|
+
return await getUserInfo(ctx);
|
|
113
|
+
}
|
|
103
114
|
}
|