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,70 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
|
|
4
|
+
require('../models/AutoReply.cjs');
|
|
5
|
+
require('../models/Board.cjs');
|
|
6
|
+
var Enum = require('../models/Enum.cjs');
|
|
7
|
+
require('../models/FriendEvent.cjs');
|
|
8
|
+
require('../models/Group.cjs');
|
|
9
|
+
require('../models/GroupEvent.cjs');
|
|
10
|
+
var utils = require('../utils.cjs');
|
|
11
|
+
require('../models/Reaction.cjs');
|
|
12
|
+
require('../models/Reminder.cjs');
|
|
13
|
+
require('../models/ZBusiness.cjs');
|
|
14
|
+
|
|
15
|
+
const sendLinkFactory = utils.apiFactory()((api, ctx, utils) => {
|
|
16
|
+
const serviceURL = {
|
|
17
|
+
[Enum.ThreadType.User]: utils.makeURL(`${api.zpwServiceMap.chat[0]}/api/message/link`, {
|
|
18
|
+
nretry: 0,
|
|
19
|
+
}),
|
|
20
|
+
[Enum.ThreadType.Group]: utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/sendlink`, {
|
|
21
|
+
nretry: 0,
|
|
22
|
+
}),
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Send link
|
|
26
|
+
*
|
|
27
|
+
* @param options Link and ttl
|
|
28
|
+
* @param threadId Thread ID
|
|
29
|
+
* @param type Thread type
|
|
30
|
+
*
|
|
31
|
+
* @throws {ZaloApiError}
|
|
32
|
+
*/
|
|
33
|
+
return async function sendLink(options, threadId, type = Enum.ThreadType.User) {
|
|
34
|
+
var _a;
|
|
35
|
+
const res = await api.parseLink(options.link);
|
|
36
|
+
const params = {
|
|
37
|
+
msg: options.msg && options.msg.trim() ? (options.msg.includes(options.link) ? options.msg : options.msg + ' ' + options.link) : options.link,
|
|
38
|
+
href: res.data.href,
|
|
39
|
+
src: res.data.src,
|
|
40
|
+
title: res.data.title,
|
|
41
|
+
desc: res.data.desc,
|
|
42
|
+
thumb: res.data.thumb,
|
|
43
|
+
type: 2, // 0
|
|
44
|
+
media: JSON.stringify(res.data.media),
|
|
45
|
+
ttl: (_a = options.ttl) !== null && _a !== void 0 ? _a : 0,
|
|
46
|
+
clientId: Date.now(),
|
|
47
|
+
};
|
|
48
|
+
if (type == Enum.ThreadType.Group) {
|
|
49
|
+
params.grid = threadId;
|
|
50
|
+
params.imei = ctx.imei;
|
|
51
|
+
// params.mentionInfo = "[]"; @TODO: implement this
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
params.toId = threadId;
|
|
55
|
+
params.mentionInfo = '';
|
|
56
|
+
}
|
|
57
|
+
const encryptedParams = utils.encodeAES(JSON.stringify(params));
|
|
58
|
+
if (!encryptedParams)
|
|
59
|
+
throw new ZaloApiError.ZaloApiError('Failed to encrypt params');
|
|
60
|
+
const response = await utils.request(serviceURL[type], {
|
|
61
|
+
method: 'POST',
|
|
62
|
+
body: new URLSearchParams({
|
|
63
|
+
params: encryptedParams,
|
|
64
|
+
}),
|
|
65
|
+
});
|
|
66
|
+
return utils.resolve(response);
|
|
67
|
+
};
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
exports.sendLinkFactory = sendLinkFactory;
|
|
@@ -1,25 +1,47 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
require('form-data');
|
|
3
|
+
var FormData = require('form-data');
|
|
4
|
+
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
|
|
4
5
|
require('../models/AutoReply.cjs');
|
|
5
6
|
require('../models/Board.cjs');
|
|
6
|
-
require('../models/Enum.cjs');
|
|
7
|
+
var Enum = require('../models/Enum.cjs');
|
|
7
8
|
require('../models/FriendEvent.cjs');
|
|
8
9
|
require('../models/Group.cjs');
|
|
9
10
|
require('../models/GroupEvent.cjs');
|
|
10
|
-
require('
|
|
11
|
-
require('json-bigint');
|
|
12
|
-
require('node:crypto');
|
|
13
|
-
require('node:fs');
|
|
14
|
-
require('node:path');
|
|
15
|
-
require('pako');
|
|
16
|
-
require('spark-md5');
|
|
17
|
-
require('tough-cookie');
|
|
18
|
-
require('sharp');
|
|
11
|
+
var utils = require('../utils.cjs');
|
|
19
12
|
require('../models/Reaction.cjs');
|
|
20
13
|
require('../models/Reminder.cjs');
|
|
21
14
|
require('../models/ZBusiness.cjs');
|
|
22
15
|
|
|
16
|
+
const attachmentUrlType = {
|
|
17
|
+
image: 'photo_original/send?',
|
|
18
|
+
gif: 'gif?',
|
|
19
|
+
video: 'asyncfile/msg?',
|
|
20
|
+
others: 'asyncfile/msg?',
|
|
21
|
+
};
|
|
22
|
+
function prepareQMSGAttach(quote) {
|
|
23
|
+
const quoteData = quote;
|
|
24
|
+
if (typeof quoteData.content == 'string')
|
|
25
|
+
return quoteData.propertyExt;
|
|
26
|
+
if (quoteData.msgType == 'chat.todo')
|
|
27
|
+
return {
|
|
28
|
+
properties: {
|
|
29
|
+
color: 0,
|
|
30
|
+
size: 0,
|
|
31
|
+
type: 0,
|
|
32
|
+
subType: 0,
|
|
33
|
+
ext: '{"shouldParseLinkOrContact":0}',
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
return Object.assign(Object.assign({}, quoteData.content), { thumbUrl: quoteData.content.thumb, oriUrl: quoteData.content.href, normalUrl: quoteData.content.href });
|
|
37
|
+
}
|
|
38
|
+
function prepareQMSG(quote) {
|
|
39
|
+
const quoteData = quote;
|
|
40
|
+
if (quoteData.msgType == 'chat.todo' && typeof quoteData.content == 'object' && typeof quoteData.content.params == 'string') {
|
|
41
|
+
return JSON.parse(quoteData.content.params).item.content;
|
|
42
|
+
}
|
|
43
|
+
return '';
|
|
44
|
+
}
|
|
23
45
|
exports.TextStyle = void 0;
|
|
24
46
|
(function (TextStyle) {
|
|
25
47
|
TextStyle["Bold"] = "b";
|
|
@@ -42,3 +64,407 @@ exports.Urgency = void 0;
|
|
|
42
64
|
Urgency[Urgency["Important"] = 1] = "Important";
|
|
43
65
|
Urgency[Urgency["Urgent"] = 2] = "Urgent";
|
|
44
66
|
})(exports.Urgency || (exports.Urgency = {}));
|
|
67
|
+
const sendMessageFactory = utils.apiFactory()((api, ctx, utils$1) => {
|
|
68
|
+
const serviceURLs = {
|
|
69
|
+
message: {
|
|
70
|
+
[Enum.ThreadType.User]: utils$1.makeURL(`${api.zpwServiceMap.chat[0]}/api/message`, {
|
|
71
|
+
nretry: 0,
|
|
72
|
+
}),
|
|
73
|
+
[Enum.ThreadType.Group]: utils$1.makeURL(`${api.zpwServiceMap.group[0]}/api/group`, {
|
|
74
|
+
nretry: 0,
|
|
75
|
+
}),
|
|
76
|
+
},
|
|
77
|
+
attachment: {
|
|
78
|
+
[Enum.ThreadType.User]: `${api.zpwServiceMap.file[0]}/api/message/`,
|
|
79
|
+
[Enum.ThreadType.Group]: `${api.zpwServiceMap.file[0]}/api/group/`,
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
const { sharefile } = ctx.settings.features;
|
|
83
|
+
function isExceedMaxFile(totalFile) {
|
|
84
|
+
return totalFile > sharefile.max_file;
|
|
85
|
+
}
|
|
86
|
+
function isExceedMaxFileSize(fileSize) {
|
|
87
|
+
return fileSize > sharefile.max_size_share_file_v3 * 1024 * 1024;
|
|
88
|
+
}
|
|
89
|
+
function getGroupLayoutId() {
|
|
90
|
+
return Date.now();
|
|
91
|
+
}
|
|
92
|
+
async function send(data) {
|
|
93
|
+
if (!Array.isArray(data))
|
|
94
|
+
data = [data];
|
|
95
|
+
const requests = [];
|
|
96
|
+
for (const each of data) {
|
|
97
|
+
requests.push((async () => {
|
|
98
|
+
const response = await utils$1.request(each.url, {
|
|
99
|
+
method: 'POST',
|
|
100
|
+
body: each.body,
|
|
101
|
+
headers: each.headers,
|
|
102
|
+
});
|
|
103
|
+
return await utils.resolveResponse(ctx, response);
|
|
104
|
+
})());
|
|
105
|
+
}
|
|
106
|
+
return await Promise.all(requests);
|
|
107
|
+
}
|
|
108
|
+
async function upthumb(file, url) {
|
|
109
|
+
const formData = new FormData();
|
|
110
|
+
formData.append('fileContent', file.buffer, {
|
|
111
|
+
filename: 'blob',
|
|
112
|
+
contentType: 'image/png',
|
|
113
|
+
});
|
|
114
|
+
const params = {
|
|
115
|
+
clientId: Date.now(),
|
|
116
|
+
imei: ctx.imei,
|
|
117
|
+
};
|
|
118
|
+
const encryptedParams = utils$1.encodeAES(JSON.stringify(params));
|
|
119
|
+
if (!encryptedParams)
|
|
120
|
+
throw new ZaloApiError.ZaloApiError('Failed to encrypt message');
|
|
121
|
+
const response = await utils$1.request(utils$1.makeURL(url + 'upthumb?', {
|
|
122
|
+
params: encryptedParams,
|
|
123
|
+
}), {
|
|
124
|
+
method: 'POST',
|
|
125
|
+
headers: formData.getHeaders(),
|
|
126
|
+
body: formData.getBuffer(),
|
|
127
|
+
});
|
|
128
|
+
return await utils.resolveResponse(ctx, response);
|
|
129
|
+
}
|
|
130
|
+
function handleMentions(type, msg, mentions) {
|
|
131
|
+
let totalMentionLen = 0;
|
|
132
|
+
const mentionsFinal = Array.isArray(mentions) && type == Enum.ThreadType.Group
|
|
133
|
+
? mentions
|
|
134
|
+
.filter((m) => m.pos >= 0 && m.uid && m.len > 0)
|
|
135
|
+
.map((m) => {
|
|
136
|
+
totalMentionLen += m.len;
|
|
137
|
+
return {
|
|
138
|
+
pos: m.pos,
|
|
139
|
+
uid: m.uid,
|
|
140
|
+
len: m.len,
|
|
141
|
+
type: m.uid == '-1' ? 1 : 0,
|
|
142
|
+
};
|
|
143
|
+
})
|
|
144
|
+
: [];
|
|
145
|
+
if (totalMentionLen > msg.length) {
|
|
146
|
+
throw new ZaloApiError.ZaloApiError('Invalid mentions: total mention characters exceed message length');
|
|
147
|
+
}
|
|
148
|
+
return {
|
|
149
|
+
mentionsFinal,
|
|
150
|
+
msgFinal: msg,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
function handleStyles(params, styles) {
|
|
154
|
+
if (styles)
|
|
155
|
+
Object.assign(params, {
|
|
156
|
+
textProperties: JSON.stringify({
|
|
157
|
+
styles: styles.map((e) => {
|
|
158
|
+
var _a;
|
|
159
|
+
const styleFinal = Object.assign(Object.assign({}, e), { indentSize: undefined, st: e.st == exports.TextStyle.Indent ? exports.TextStyle.Indent.replace(/\$/g, `${(_a = e.indentSize) !== null && _a !== void 0 ? _a : 1}0`) : e.st });
|
|
160
|
+
utils.removeUndefinedKeys(styleFinal);
|
|
161
|
+
return styleFinal;
|
|
162
|
+
}),
|
|
163
|
+
ver: 0,
|
|
164
|
+
}),
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
function handleUrgency(params, urgency) {
|
|
168
|
+
if (urgency == exports.Urgency.Important || urgency == exports.Urgency.Urgent) {
|
|
169
|
+
Object.assign(params, { metaData: { urgency } });
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
async function handleMessage({ msg, styles, urgency, mentions, parseLink, quote, ttl }, threadId, type) {
|
|
173
|
+
if (!msg || msg.length == 0)
|
|
174
|
+
throw new ZaloApiError.ZaloApiError('Missing message content');
|
|
175
|
+
const isGroupMessage = type == Enum.ThreadType.Group;
|
|
176
|
+
const { mentionsFinal, msgFinal } = handleMentions(type, msg, mentions);
|
|
177
|
+
msg = msgFinal;
|
|
178
|
+
if (quote) {
|
|
179
|
+
if (typeof quote.content != 'string' && quote.msgType == 'webchat') {
|
|
180
|
+
throw new ZaloApiError.ZaloApiError('This kind of `webchat` quote type is not available');
|
|
181
|
+
}
|
|
182
|
+
if (quote.msgType == 'group.poll') {
|
|
183
|
+
throw new ZaloApiError.ZaloApiError('The `group.poll` quote type is not available');
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
const isMentionsValid = mentionsFinal.length > 0 && isGroupMessage;
|
|
187
|
+
const params = quote
|
|
188
|
+
? {
|
|
189
|
+
toid: isGroupMessage ? undefined : threadId,
|
|
190
|
+
grid: isGroupMessage ? threadId : undefined,
|
|
191
|
+
message: msg,
|
|
192
|
+
clientId: Date.now(),
|
|
193
|
+
mentionInfo: isMentionsValid ? JSON.stringify(mentionsFinal) : undefined,
|
|
194
|
+
qmsgOwner: quote.uidFrom,
|
|
195
|
+
qmsgId: quote.msgId,
|
|
196
|
+
qmsgCliId: quote.cliMsgId,
|
|
197
|
+
qmsgType: utils.getClientMessageType(quote.msgType),
|
|
198
|
+
qmsgTs: quote.ts,
|
|
199
|
+
qmsg: typeof quote.content == 'string' ? quote.content : prepareQMSG(quote),
|
|
200
|
+
imei: isGroupMessage ? undefined : ctx.imei,
|
|
201
|
+
visibility: isGroupMessage ? 0 : undefined,
|
|
202
|
+
qmsgAttach: JSON.stringify(prepareQMSGAttach(quote)),
|
|
203
|
+
qmsgTTL: quote.ttl,
|
|
204
|
+
ttl: ttl !== null && ttl !== void 0 ? ttl : 0,
|
|
205
|
+
}
|
|
206
|
+
: parseLink
|
|
207
|
+
? {
|
|
208
|
+
msg: msg,
|
|
209
|
+
href: parseLink.href,
|
|
210
|
+
src: parseLink.src,
|
|
211
|
+
title: parseLink.title || parseLink.href,
|
|
212
|
+
desc: parseLink.desc,
|
|
213
|
+
thumb: parseLink.thumb,
|
|
214
|
+
type: 0,
|
|
215
|
+
media: JSON.stringify(parseLink.media),
|
|
216
|
+
ttl: 0,
|
|
217
|
+
toId: isGroupMessage ? undefined : threadId,
|
|
218
|
+
grid: isGroupMessage ? threadId : undefined,
|
|
219
|
+
clientId: Date.now(),
|
|
220
|
+
mentionInfo: isMentionsValid ? JSON.stringify(mentionsFinal) : '',
|
|
221
|
+
imei: isGroupMessage ? ctx.imei : undefined,
|
|
222
|
+
}
|
|
223
|
+
: {
|
|
224
|
+
message: msg,
|
|
225
|
+
clientId: Date.now(),
|
|
226
|
+
mentionInfo: isMentionsValid ? JSON.stringify(mentionsFinal) : undefined,
|
|
227
|
+
imei: isGroupMessage ? undefined : ctx.imei,
|
|
228
|
+
ttl: ttl !== null && ttl !== void 0 ? ttl : 0,
|
|
229
|
+
visibility: isGroupMessage ? 0 : undefined,
|
|
230
|
+
toid: isGroupMessage ? undefined : threadId,
|
|
231
|
+
grid: isGroupMessage ? threadId : undefined,
|
|
232
|
+
};
|
|
233
|
+
handleStyles(params, styles);
|
|
234
|
+
handleUrgency(params, urgency);
|
|
235
|
+
utils.removeUndefinedKeys(params);
|
|
236
|
+
const encryptedParams = utils$1.encodeAES(JSON.stringify(params));
|
|
237
|
+
if (!encryptedParams)
|
|
238
|
+
throw new ZaloApiError.ZaloApiError('Failed to encrypt message');
|
|
239
|
+
const finalServiceUrl = new URL(serviceURLs.message[type]);
|
|
240
|
+
if (quote) {
|
|
241
|
+
finalServiceUrl.pathname = finalServiceUrl.pathname + '/quote';
|
|
242
|
+
}
|
|
243
|
+
else if (parseLink) {
|
|
244
|
+
finalServiceUrl.pathname = finalServiceUrl.pathname + '/' + (isGroupMessage ? 'sendlink' : 'link');
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
finalServiceUrl.pathname = finalServiceUrl.pathname + '/' + (isGroupMessage ? (params.mentionInfo ? 'mention' : 'sendmsg') : 'sms');
|
|
248
|
+
}
|
|
249
|
+
return {
|
|
250
|
+
url: finalServiceUrl.toString(),
|
|
251
|
+
body: new URLSearchParams({ params: encryptedParams }),
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
async function handleAttachment({ msg, attachments, mentions, quote, ttl, urgency }, threadId, type) {
|
|
255
|
+
if (!attachments || attachments.length == 0)
|
|
256
|
+
throw new ZaloApiError.ZaloApiError('Missing attachments');
|
|
257
|
+
const firstExtFile = utils.getFileExtension(attachments[0].mimetype);
|
|
258
|
+
const isSingleFile = attachments.length == 1;
|
|
259
|
+
const isGroupMessage = type == Enum.ThreadType.Group;
|
|
260
|
+
const canBeDesc = isSingleFile && ['jpg', 'jpeg', 'png', 'webp'].includes(firstExtFile);
|
|
261
|
+
const gifFiles = attachments.filter((e) => utils.getFileExtension(e.mimetype) == 'gif');
|
|
262
|
+
attachments = attachments.filter((e) => utils.getFileExtension(e.mimetype) != 'gif');
|
|
263
|
+
const uploadAttachment = attachments.length == 0 ? [] : await api.uploadAttachment(attachments, threadId, type);
|
|
264
|
+
const attachmentsData = [];
|
|
265
|
+
let indexInGroupLayout = uploadAttachment.length - 1;
|
|
266
|
+
const groupLayoutId = getGroupLayoutId();
|
|
267
|
+
const { mentionsFinal, msgFinal } = handleMentions(type, msg, mentions);
|
|
268
|
+
msg = msgFinal;
|
|
269
|
+
const isMentionsValid = mentionsFinal.length > 0 && isGroupMessage && attachments.length == 1;
|
|
270
|
+
const isMultiFile = attachments.length > 1;
|
|
271
|
+
let clientId = Date.now();
|
|
272
|
+
for (const attachment of uploadAttachment) {
|
|
273
|
+
let data = {};
|
|
274
|
+
switch (attachment.fileType) {
|
|
275
|
+
case 'image': {
|
|
276
|
+
data = {
|
|
277
|
+
fileType: attachment.fileType,
|
|
278
|
+
params: {
|
|
279
|
+
photoId: attachment.photoId,
|
|
280
|
+
clientId: (clientId++).toString(),
|
|
281
|
+
desc: msg,
|
|
282
|
+
width: attachment.width,
|
|
283
|
+
height: attachment.height,
|
|
284
|
+
toid: isGroupMessage ? undefined : String(threadId),
|
|
285
|
+
grid: isGroupMessage ? String(threadId) : undefined,
|
|
286
|
+
rawUrl: attachment.normalUrl,
|
|
287
|
+
hdUrl: attachment.hdUrl,
|
|
288
|
+
thumbUrl: attachment.thumbUrl,
|
|
289
|
+
oriUrl: isGroupMessage ? attachment.normalUrl : undefined,
|
|
290
|
+
normalUrl: isGroupMessage ? undefined : attachment.normalUrl,
|
|
291
|
+
hdSize: String(attachment.totalSize),
|
|
292
|
+
zsource: -1,
|
|
293
|
+
ttl: ttl !== null && ttl !== void 0 ? ttl : 0,
|
|
294
|
+
jcp: '{"convertible":"jxl"}',
|
|
295
|
+
groupLayoutId: isMultiFile ? groupLayoutId : undefined,
|
|
296
|
+
isGroupLayout: isMultiFile ? 1 : undefined,
|
|
297
|
+
idInGroup: isMultiFile ? indexInGroupLayout-- : undefined,
|
|
298
|
+
totalItemInGroup: isMultiFile ? uploadAttachment.length : undefined,
|
|
299
|
+
mentionInfo: isMentionsValid && canBeDesc && !quote ? JSON.stringify(mentionsFinal) : undefined,
|
|
300
|
+
},
|
|
301
|
+
body: new URLSearchParams(),
|
|
302
|
+
};
|
|
303
|
+
break;
|
|
304
|
+
}
|
|
305
|
+
case 'video': {
|
|
306
|
+
data = {
|
|
307
|
+
fileType: attachment.fileType,
|
|
308
|
+
params: {
|
|
309
|
+
fileId: attachment.fileId,
|
|
310
|
+
checksum: attachment.checksum,
|
|
311
|
+
checksumSha: '',
|
|
312
|
+
extention: utils.getFileExtension(attachment.fileName),
|
|
313
|
+
totalSize: attachment.totalSize,
|
|
314
|
+
fileName: attachment.fileName,
|
|
315
|
+
clientId: attachment.clientFileId,
|
|
316
|
+
fType: 1,
|
|
317
|
+
fileCount: 0,
|
|
318
|
+
fdata: '{}',
|
|
319
|
+
toid: isGroupMessage ? undefined : String(threadId),
|
|
320
|
+
grid: isGroupMessage ? String(threadId) : undefined,
|
|
321
|
+
fileUrl: attachment.fileUrl,
|
|
322
|
+
zsource: -1,
|
|
323
|
+
ttl: ttl !== null && ttl !== void 0 ? ttl : 0,
|
|
324
|
+
},
|
|
325
|
+
body: new URLSearchParams(),
|
|
326
|
+
};
|
|
327
|
+
break;
|
|
328
|
+
}
|
|
329
|
+
case 'others': {
|
|
330
|
+
data = {
|
|
331
|
+
fileType: attachment.fileType,
|
|
332
|
+
params: {
|
|
333
|
+
fileId: attachment.fileId,
|
|
334
|
+
checksum: attachment.checksum,
|
|
335
|
+
checksumSha: '',
|
|
336
|
+
extention: utils.getFileExtension(attachment.fileName),
|
|
337
|
+
totalSize: attachment.totalSize,
|
|
338
|
+
fileName: attachment.fileName,
|
|
339
|
+
clientId: attachment.clientFileId,
|
|
340
|
+
fType: 1,
|
|
341
|
+
fileCount: 0,
|
|
342
|
+
fdata: '{}',
|
|
343
|
+
toid: isGroupMessage ? undefined : String(threadId),
|
|
344
|
+
grid: isGroupMessage ? String(threadId) : undefined,
|
|
345
|
+
fileUrl: attachment.fileUrl,
|
|
346
|
+
zsource: -1,
|
|
347
|
+
ttl: ttl !== null && ttl !== void 0 ? ttl : 0,
|
|
348
|
+
},
|
|
349
|
+
body: new URLSearchParams(),
|
|
350
|
+
};
|
|
351
|
+
break;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
handleUrgency((data === null || data === void 0 ? void 0 : data.params) || {}, urgency);
|
|
355
|
+
utils.removeUndefinedKeys((data === null || data === void 0 ? void 0 : data.params) || {});
|
|
356
|
+
const encryptedParams = utils$1.encodeAES(JSON.stringify(data === null || data === void 0 ? void 0 : data.params));
|
|
357
|
+
if (!encryptedParams)
|
|
358
|
+
throw new ZaloApiError.ZaloApiError('Failed to encrypt message');
|
|
359
|
+
data.body.append('params', encryptedParams);
|
|
360
|
+
attachmentsData.push(data);
|
|
361
|
+
}
|
|
362
|
+
for (const gif of gifFiles) {
|
|
363
|
+
const gifData = await utils.getGifMetaData(gif);
|
|
364
|
+
if (isExceedMaxFileSize(gifData.totalSize))
|
|
365
|
+
throw new ZaloApiError.ZaloApiError(`File ${gif.originalname} size exceed maximum size of ${sharefile.max_size_share_file_v3}MB`);
|
|
366
|
+
const _upthumb = await upthumb(gif, serviceURLs.attachment[Enum.ThreadType.User]);
|
|
367
|
+
const formData = new FormData();
|
|
368
|
+
formData.append('chunkContent', gif.buffer, {
|
|
369
|
+
filename: gif.originalname,
|
|
370
|
+
contentType: 'application/octet-stream',
|
|
371
|
+
});
|
|
372
|
+
const params = {
|
|
373
|
+
clientId: Date.now().toString(),
|
|
374
|
+
fileName: gifData.fileName,
|
|
375
|
+
totalSize: gifData.totalSize,
|
|
376
|
+
width: gifData.width,
|
|
377
|
+
height: gifData.height,
|
|
378
|
+
msg: msg,
|
|
379
|
+
type: 1,
|
|
380
|
+
ttl: ttl !== null && ttl !== void 0 ? ttl : 0,
|
|
381
|
+
visibility: isGroupMessage ? 0 : undefined,
|
|
382
|
+
toid: isGroupMessage ? undefined : threadId,
|
|
383
|
+
grid: isGroupMessage ? threadId : undefined,
|
|
384
|
+
thumb: _upthumb.url,
|
|
385
|
+
checksum: (await utils.getMd5LargeFileObject(gif)).data,
|
|
386
|
+
totalChunk: 1,
|
|
387
|
+
chunkId: 1,
|
|
388
|
+
};
|
|
389
|
+
handleUrgency(params, urgency);
|
|
390
|
+
utils.removeUndefinedKeys(params);
|
|
391
|
+
const encryptedParams = utils$1.encodeAES(JSON.stringify(params));
|
|
392
|
+
if (!encryptedParams)
|
|
393
|
+
throw new ZaloApiError.ZaloApiError('Failed to encrypt message');
|
|
394
|
+
attachmentsData.push({
|
|
395
|
+
query: {
|
|
396
|
+
params: encryptedParams,
|
|
397
|
+
type: '1',
|
|
398
|
+
},
|
|
399
|
+
body: formData.getBuffer(),
|
|
400
|
+
headers: formData.getHeaders(),
|
|
401
|
+
fileType: 'gif',
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
const responses = [];
|
|
405
|
+
for (const data of attachmentsData) {
|
|
406
|
+
responses.push({
|
|
407
|
+
url: utils$1.makeURL(serviceURLs.attachment[type] + attachmentUrlType[data.fileType], Object.assign({
|
|
408
|
+
nretry: '0',
|
|
409
|
+
}, data.query || {})),
|
|
410
|
+
body: data.body,
|
|
411
|
+
headers: data.fileType == 'gif' ? data.headers : {},
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
return responses;
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Send a message to a thread
|
|
418
|
+
*
|
|
419
|
+
* @param message Message content
|
|
420
|
+
* @param threadId group or user id
|
|
421
|
+
* @param type Message type (User or Group)
|
|
422
|
+
* @param quote Message or GroupMessage instance (optional), used for quoting
|
|
423
|
+
*
|
|
424
|
+
* @throws {ZaloApiError | ZaloApiMissingImageMetadataGetter}
|
|
425
|
+
*/
|
|
426
|
+
return async function sendMessage(message, threadId, type = Enum.ThreadType.User) {
|
|
427
|
+
if (!message)
|
|
428
|
+
throw new ZaloApiError.ZaloApiError('Missing message content');
|
|
429
|
+
if (!threadId)
|
|
430
|
+
throw new ZaloApiError.ZaloApiError('Missing threadId');
|
|
431
|
+
if (typeof message == 'string')
|
|
432
|
+
message = { msg: message };
|
|
433
|
+
let { msg, attachments, mentions } = message;
|
|
434
|
+
const { quote, ttl, styles, urgency } = message;
|
|
435
|
+
if (attachments && !Array.isArray(attachments)) {
|
|
436
|
+
attachments = [attachments];
|
|
437
|
+
}
|
|
438
|
+
if (!msg && (!attachments || (attachments && attachments.length == 0)))
|
|
439
|
+
throw new ZaloApiError.ZaloApiError('Missing message content');
|
|
440
|
+
if (attachments && isExceedMaxFile(attachments.length))
|
|
441
|
+
throw new ZaloApiError.ZaloApiError('Exceed maximum file of ' + sharefile.max_file);
|
|
442
|
+
const responses = {
|
|
443
|
+
message: null,
|
|
444
|
+
attachment: [],
|
|
445
|
+
};
|
|
446
|
+
if (attachments && attachments.length > 0) {
|
|
447
|
+
const firstExtFile = utils.getFileExtension(attachments[0].mimetype);
|
|
448
|
+
const isSingleFile = attachments.length == 1;
|
|
449
|
+
const canBeDesc = isSingleFile && ['jpg', 'jpeg', 'png', 'webp'].includes(firstExtFile);
|
|
450
|
+
if ((!canBeDesc && msg.length > 0) || (msg.length > 0 && quote)) {
|
|
451
|
+
// send message and attachment separately
|
|
452
|
+
await handleMessage(message, threadId, type).then(async (data) => {
|
|
453
|
+
responses.message = (await send(data))[0];
|
|
454
|
+
});
|
|
455
|
+
msg = '';
|
|
456
|
+
mentions = undefined;
|
|
457
|
+
}
|
|
458
|
+
const handledData = await handleAttachment({ msg, mentions, attachments, quote, ttl, urgency }, threadId, type);
|
|
459
|
+
responses.attachment = await send(handledData);
|
|
460
|
+
msg = '';
|
|
461
|
+
}
|
|
462
|
+
if (msg.length > 0) {
|
|
463
|
+
const handledData = await handleMessage(message, threadId, type);
|
|
464
|
+
responses.message = (await send(handledData))[0];
|
|
465
|
+
}
|
|
466
|
+
return responses;
|
|
467
|
+
};
|
|
468
|
+
});
|
|
469
|
+
|
|
470
|
+
exports.sendMessageFactory = sendMessageFactory;
|
|
@@ -1,20 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
|
|
3
4
|
require('../models/AutoReply.cjs');
|
|
4
5
|
require('../models/Board.cjs');
|
|
5
|
-
require('../models/Enum.cjs');
|
|
6
|
+
var Enum = require('../models/Enum.cjs');
|
|
6
7
|
require('../models/FriendEvent.cjs');
|
|
7
8
|
require('../models/Group.cjs');
|
|
8
9
|
require('../models/GroupEvent.cjs');
|
|
9
|
-
require('
|
|
10
|
-
require('json-bigint');
|
|
11
|
-
require('node:crypto');
|
|
12
|
-
require('node:fs');
|
|
13
|
-
require('node:path');
|
|
14
|
-
require('pako');
|
|
15
|
-
require('spark-md5');
|
|
16
|
-
require('tough-cookie');
|
|
17
|
-
require('sharp');
|
|
10
|
+
var utils = require('../utils.cjs');
|
|
18
11
|
require('../models/Reaction.cjs');
|
|
19
12
|
require('../models/Reminder.cjs');
|
|
20
13
|
require('../models/ZBusiness.cjs');
|
|
@@ -26,3 +19,48 @@ exports.ReportReason = void 0;
|
|
|
26
19
|
ReportReason[ReportReason["Fraud"] = 3] = "Fraud";
|
|
27
20
|
ReportReason[ReportReason["Other"] = 0] = "Other";
|
|
28
21
|
})(exports.ReportReason || (exports.ReportReason = {}));
|
|
22
|
+
const sendReportFactory = utils.apiFactory()((api, ctx, utils$1) => {
|
|
23
|
+
const serviceURL = {
|
|
24
|
+
[Enum.ThreadType.User]: utils$1.makeURL(`${api.zpwServiceMap.profile[0]}/api/report/abuse-v2`),
|
|
25
|
+
[Enum.ThreadType.Group]: utils$1.makeURL(`${api.zpwServiceMap.profile[0]}/api/social/profile/reportabuse`),
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Send report to Zalo
|
|
29
|
+
*
|
|
30
|
+
* @param options Report options
|
|
31
|
+
* @param threadId The threadID to report
|
|
32
|
+
* @param type Thread type, default direct
|
|
33
|
+
*
|
|
34
|
+
* @throws {ZaloApiError}
|
|
35
|
+
*
|
|
36
|
+
*/
|
|
37
|
+
return async function sendReport(options, threadId, type = Enum.ThreadType.User) {
|
|
38
|
+
const params = type == Enum.ThreadType.User
|
|
39
|
+
? {
|
|
40
|
+
idTo: threadId,
|
|
41
|
+
objId: 'person.profile',
|
|
42
|
+
reason: options.reason.toString(),
|
|
43
|
+
content: options.reason == exports.ReportReason.Other ? options.content : undefined,
|
|
44
|
+
}
|
|
45
|
+
: {
|
|
46
|
+
uidTo: threadId,
|
|
47
|
+
type: 14,
|
|
48
|
+
reason: options.reason,
|
|
49
|
+
content: options.reason == exports.ReportReason.Other ? options.content : '',
|
|
50
|
+
imei: ctx.imei,
|
|
51
|
+
};
|
|
52
|
+
utils.removeUndefinedKeys(params);
|
|
53
|
+
const encryptedParams = utils$1.encodeAES(JSON.stringify(params));
|
|
54
|
+
if (!encryptedParams)
|
|
55
|
+
throw new ZaloApiError.ZaloApiError('Failed to encrypt params');
|
|
56
|
+
const response = await utils$1.request(serviceURL[type], {
|
|
57
|
+
method: 'POST',
|
|
58
|
+
body: new URLSearchParams({
|
|
59
|
+
params: encryptedParams,
|
|
60
|
+
}),
|
|
61
|
+
});
|
|
62
|
+
return utils$1.resolve(response);
|
|
63
|
+
};
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
exports.sendReportFactory = sendReportFactory;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
|
|
4
|
+
var context = require('../context.cjs');
|
|
5
|
+
require('../models/AutoReply.cjs');
|
|
6
|
+
require('../models/Board.cjs');
|
|
7
|
+
var Enum = require('../models/Enum.cjs');
|
|
8
|
+
require('../models/FriendEvent.cjs');
|
|
9
|
+
require('../models/Group.cjs');
|
|
10
|
+
require('../models/GroupEvent.cjs');
|
|
11
|
+
var utils = require('../utils.cjs');
|
|
12
|
+
require('../models/Reaction.cjs');
|
|
13
|
+
require('../models/Reminder.cjs');
|
|
14
|
+
require('../models/ZBusiness.cjs');
|
|
15
|
+
|
|
16
|
+
const sendSeenEventFactory = utils.apiFactory()((api, ctx, utils) => {
|
|
17
|
+
const serviceURL = {
|
|
18
|
+
[Enum.ThreadType.User]: utils.makeURL(`${api.zpwServiceMap.chat[0]}/api/message/seenv2`, {
|
|
19
|
+
nretry: 0,
|
|
20
|
+
}),
|
|
21
|
+
[Enum.ThreadType.Group]: utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/seenv2`, {
|
|
22
|
+
nretry: 0,
|
|
23
|
+
}),
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Send message seen event
|
|
27
|
+
*
|
|
28
|
+
* @param messages List of messages to send seen event
|
|
29
|
+
* @param type Messages type (User or Group), defaults to User
|
|
30
|
+
*
|
|
31
|
+
* @throws {ZaloApiError}
|
|
32
|
+
*/
|
|
33
|
+
return async function sendSeenEvent(messages, type = Enum.ThreadType.User) {
|
|
34
|
+
if (!messages)
|
|
35
|
+
throw new ZaloApiError.ZaloApiError('messages are missing or not in a valid array format.');
|
|
36
|
+
if (!Array.isArray(messages))
|
|
37
|
+
messages = [messages];
|
|
38
|
+
if (messages.length === 0 || messages.length > context.MAX_MESSAGES_PER_SEND)
|
|
39
|
+
throw new ZaloApiError.ZaloApiError('messages must contain between 1 and 50 messages.');
|
|
40
|
+
const isGroup = type === Enum.ThreadType.Group;
|
|
41
|
+
const threadId = isGroup ? messages[0].idTo : messages[0].uidFrom;
|
|
42
|
+
const msgInfos = {
|
|
43
|
+
data: messages.map((msg) => {
|
|
44
|
+
const curThreadId = isGroup ? msg.idTo : msg.uidFrom;
|
|
45
|
+
if (curThreadId !== threadId) {
|
|
46
|
+
throw new ZaloApiError.ZaloApiError('All messages must belong to the same thread.');
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
cmi: msg.cliMsgId,
|
|
50
|
+
gmi: msg.msgId,
|
|
51
|
+
si: msg.uidFrom,
|
|
52
|
+
di: msg.idTo === ctx.uid ? '0' : msg.idTo,
|
|
53
|
+
mt: msg.msgType,
|
|
54
|
+
st: msg.st || 0 === msg.st ? 0 : -1,
|
|
55
|
+
at: msg.at || 0 === msg.at ? 0 : -1,
|
|
56
|
+
cmd: msg.cmd || 0 === msg.cmd ? 0 : -1,
|
|
57
|
+
ts: parseInt(`${msg.ts}`) || 0 === parseInt(`${msg.ts}`) ? 0 : -1,
|
|
58
|
+
};
|
|
59
|
+
}),
|
|
60
|
+
[isGroup ? 'grid' : 'senderId']: threadId,
|
|
61
|
+
};
|
|
62
|
+
const params = Object.assign({ msgInfos: JSON.stringify(msgInfos) }, (isGroup ? { imei: ctx.imei } : {}));
|
|
63
|
+
const encryptedParams = utils.encodeAES(JSON.stringify(params));
|
|
64
|
+
if (!encryptedParams)
|
|
65
|
+
throw new ZaloApiError.ZaloApiError('Failed to encrypt params');
|
|
66
|
+
const response = await utils.request(serviceURL[type], {
|
|
67
|
+
method: 'POST',
|
|
68
|
+
body: new URLSearchParams({
|
|
69
|
+
params: encryptedParams,
|
|
70
|
+
}),
|
|
71
|
+
});
|
|
72
|
+
return utils.resolve(response);
|
|
73
|
+
};
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
exports.sendSeenEventFactory = sendSeenEventFactory;
|