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.
Files changed (155) hide show
  1. package/dist/apis/sendMessage.d.ts +5 -0
  2. package/dist/apis/sendMessage.js +31 -11
  3. package/dist/cjs/apis/acceptFriendRequest.cjs +33 -0
  4. package/dist/cjs/apis/addGroupBlockedMember.cjs +33 -0
  5. package/dist/cjs/apis/addGroupDeputy.cjs +36 -0
  6. package/dist/cjs/apis/addPollOptions.cjs +31 -0
  7. package/dist/cjs/apis/addQuickMessage.cjs +65 -0
  8. package/dist/cjs/apis/addReaction.cjs +297 -0
  9. package/dist/cjs/apis/addUnreadMark.cjs +65 -0
  10. package/dist/cjs/apis/addUserToGroup.cjs +39 -0
  11. package/dist/cjs/apis/blockUser.cjs +33 -0
  12. package/dist/cjs/apis/blockViewFeed.cjs +35 -0
  13. package/dist/cjs/apis/changeAccountAvatar.cjs +56 -0
  14. package/dist/cjs/apis/changeFriendAlias.cjs +32 -0
  15. package/dist/cjs/apis/changeGroupAvatar.cjs +47 -0
  16. package/dist/cjs/apis/changeGroupName.cjs +37 -0
  17. package/dist/cjs/apis/changeGroupOwner.cjs +36 -0
  18. package/dist/cjs/apis/createAutoReply.cjs +42 -0
  19. package/dist/cjs/apis/createCatalog.cjs +34 -0
  20. package/dist/cjs/apis/createGroup.cjs +48 -0
  21. package/dist/cjs/apis/createNote.cjs +52 -0
  22. package/dist/cjs/apis/createPoll.cjs +45 -0
  23. package/dist/cjs/apis/createProductCatalog.cjs +55 -0
  24. package/dist/cjs/apis/createReminder.cjs +76 -0
  25. package/dist/cjs/apis/custom.cjs +19 -0
  26. package/dist/cjs/apis/deleteAutoReply.cjs +34 -0
  27. package/dist/cjs/apis/deleteAvatar.cjs +32 -0
  28. package/dist/cjs/apis/deleteCatalog.cjs +33 -0
  29. package/dist/cjs/apis/deleteChat.cjs +63 -0
  30. package/dist/cjs/apis/deleteGroupInviteBox.cjs +32 -0
  31. package/dist/cjs/apis/deleteMessage.cjs +65 -0
  32. package/dist/cjs/apis/deleteProductCatalog.cjs +36 -0
  33. package/dist/cjs/apis/disableGroupLink.cjs +29 -0
  34. package/dist/cjs/apis/disperseGroup.cjs +33 -0
  35. package/dist/cjs/apis/editNote.cjs +51 -0
  36. package/dist/cjs/apis/editReminder.cjs +74 -0
  37. package/dist/cjs/apis/enableGroupLink.cjs +30 -0
  38. package/dist/cjs/apis/fetchAccountInfo.cjs +15 -0
  39. package/dist/cjs/apis/findUser.cjs +45 -0
  40. package/dist/cjs/apis/forwardAttachment.cjs +85 -0
  41. package/dist/cjs/apis/forwardMessage.cjs +122 -0
  42. package/dist/cjs/apis/getAliasList.cjs +33 -0
  43. package/dist/cjs/apis/getAllFriends.cjs +37 -0
  44. package/dist/cjs/apis/getAllGroups.cjs +15 -0
  45. package/dist/cjs/apis/getArchivedChatList.cjs +28 -0
  46. package/dist/cjs/apis/getAutoDeleteChat.cjs +26 -0
  47. package/dist/cjs/apis/getAutoReplyList.cjs +29 -0
  48. package/dist/cjs/apis/getAvatarList.cjs +33 -0
  49. package/dist/cjs/apis/getBizAccount.cjs +32 -0
  50. package/dist/cjs/apis/getCatalogList.cjs +37 -0
  51. package/dist/cjs/apis/getContext.cjs +9 -0
  52. package/dist/cjs/apis/getCookie.cjs +14 -0
  53. package/dist/cjs/apis/getFriendBoardList.cjs +31 -0
  54. package/dist/cjs/apis/getFriendOnlines.cjs +40 -0
  55. package/dist/cjs/apis/getFriendRecommendations.cjs +32 -0
  56. package/dist/cjs/apis/getFriendRequestStatus.cjs +30 -0
  57. package/dist/cjs/apis/getGroupBlockedMember.cjs +34 -0
  58. package/dist/cjs/apis/getGroupInfo.cjs +37 -0
  59. package/dist/cjs/apis/getGroupInviteBoxInfo.cjs +43 -0
  60. package/dist/cjs/apis/getGroupInviteBoxList.cjs +36 -0
  61. package/dist/cjs/apis/getGroupLinkDetail.cjs +30 -0
  62. package/dist/cjs/apis/getGroupLinkInfo.cjs +33 -0
  63. package/dist/cjs/apis/getGroupMembersInfo.cjs +29 -0
  64. package/dist/cjs/apis/getHiddenConversations.cjs +28 -0
  65. package/dist/cjs/apis/getLabels.cjs +33 -0
  66. package/dist/cjs/apis/getLastMessage.cjs +25 -0
  67. package/dist/cjs/apis/getListBoard.cjs +58 -0
  68. package/dist/cjs/apis/getListReminder.cjs +60 -0
  69. package/dist/cjs/apis/getMute.cjs +27 -0
  70. package/dist/cjs/apis/getOwnId.cjs +9 -0
  71. package/dist/cjs/apis/getPendingGroupMembers.cjs +32 -0
  72. package/dist/cjs/apis/getPinConversations.cjs +27 -0
  73. package/dist/cjs/apis/getPollDetail.cjs +35 -0
  74. package/dist/cjs/apis/getProductCatalogList.cjs +38 -0
  75. package/dist/cjs/apis/getQR.cjs +34 -0
  76. package/dist/cjs/apis/getQuickMessageList.cjs +29 -0
  77. package/dist/cjs/apis/getRecommendFriends.cjs +25 -0
  78. package/dist/cjs/apis/getRelatedFriendGroup.cjs +35 -0
  79. package/dist/cjs/apis/getReminder.cjs +30 -0
  80. package/dist/cjs/apis/getReminderResponses.cjs +29 -0
  81. package/dist/cjs/apis/getSentFriendRequest.cjs +29 -0
  82. package/dist/cjs/apis/getSettings.cjs +25 -0
  83. package/dist/cjs/apis/getStickers.cjs +45 -0
  84. package/dist/cjs/apis/getStickersDetail.cjs +45 -0
  85. package/dist/cjs/apis/getUnreadMark.cjs +35 -0
  86. package/dist/cjs/apis/getUserInfo.cjs +47 -0
  87. package/dist/cjs/apis/inviteUserToGroups.cjs +35 -0
  88. package/dist/cjs/apis/joinGroupInviteBox.cjs +30 -0
  89. package/dist/cjs/apis/joinGroupLink.cjs +32 -0
  90. package/dist/cjs/apis/keepAlive.cjs +27 -0
  91. package/dist/cjs/apis/lastOnline.cjs +31 -0
  92. package/dist/cjs/apis/leaveGroup.cjs +38 -0
  93. package/dist/cjs/apis/lockPoll.cjs +33 -0
  94. package/dist/cjs/apis/parseLink.cjs +32 -0
  95. package/dist/cjs/apis/rejectFriendRequest.cjs +32 -0
  96. package/dist/cjs/apis/removeFriend.cjs +33 -0
  97. package/dist/cjs/apis/removeFriendAlias.cjs +29 -0
  98. package/dist/cjs/apis/removeGroupBlockedMember.cjs +33 -0
  99. package/dist/cjs/apis/removeGroupDeputy.cjs +35 -0
  100. package/dist/cjs/apis/removeQuickMessage.cjs +32 -0
  101. package/dist/cjs/apis/removeReminder.cjs +53 -0
  102. package/dist/cjs/apis/removeUnreadMark.cjs +63 -0
  103. package/dist/cjs/apis/removeUserFromGroup.cjs +39 -0
  104. package/dist/cjs/apis/resetHiddenConversPin.cjs +25 -0
  105. package/dist/cjs/apis/reuseAvatar.cjs +31 -0
  106. package/dist/cjs/apis/reviewPendingMemberRequest.cjs +33 -11
  107. package/dist/cjs/apis/sendBankCard.cjs +50 -0
  108. package/dist/cjs/apis/sendCard.cjs +72 -0
  109. package/dist/cjs/apis/sendDeliveredEvent.cjs +68 -0
  110. package/dist/cjs/apis/sendFriendRequest.cjs +44 -0
  111. package/dist/cjs/apis/sendLink.cjs +70 -0
  112. package/dist/cjs/apis/sendMessage.cjs +437 -11
  113. package/dist/cjs/apis/sendReport.cjs +48 -10
  114. package/dist/cjs/apis/sendSeenEvent.cjs +76 -0
  115. package/dist/cjs/apis/sendSticker.cjs +69 -0
  116. package/dist/cjs/apis/sendTypingEvent.cjs +46 -0
  117. package/dist/cjs/apis/sendVideo.cjs +131 -0
  118. package/dist/cjs/apis/sendVoice.cjs +86 -0
  119. package/dist/cjs/apis/setArchivedConversations.cjs +39 -0
  120. package/dist/cjs/apis/setHiddenConversations.cjs +52 -0
  121. package/dist/cjs/apis/setMute.cjs +57 -10
  122. package/dist/cjs/apis/setPinnedConversations.cjs +47 -0
  123. package/dist/cjs/apis/sharePoll.cjs +33 -0
  124. package/dist/cjs/apis/unblockUser.cjs +33 -0
  125. package/dist/cjs/apis/undo.cjs +55 -0
  126. package/dist/cjs/apis/undoFriendRequest.cjs +32 -0
  127. package/dist/cjs/apis/updateActiveStatus.cjs +32 -0
  128. package/dist/cjs/apis/updateAutoDeleteChat.cjs +35 -10
  129. package/dist/cjs/apis/updateAutoReply.cjs +43 -0
  130. package/dist/cjs/apis/updateCatalog.cjs +35 -0
  131. package/dist/cjs/apis/updateGroupSettings.cjs +48 -0
  132. package/dist/cjs/apis/updateHiddenConversPin.cjs +35 -0
  133. package/dist/cjs/apis/updateLabels.cjs +39 -0
  134. package/dist/cjs/apis/updateLang.cjs +27 -11
  135. package/dist/cjs/apis/updateProductCatalog.cjs +56 -0
  136. package/dist/cjs/apis/updateProfile.cjs +48 -0
  137. package/dist/cjs/apis/updateQuickMessage.cjs +66 -0
  138. package/dist/cjs/apis/updateSettings.cjs +77 -11
  139. package/dist/cjs/apis/uploadAttachment.cjs +208 -0
  140. package/dist/cjs/apis/uploadProductPhoto.cjs +50 -0
  141. package/dist/cjs/apis/votePoll.cjs +34 -0
  142. package/dist/cjs/apis.cjs +292 -0
  143. package/dist/cjs/context.cjs +15 -0
  144. package/dist/cjs/core/enums/common.cjs +14 -0
  145. package/dist/cjs/core/utils/index.cjs +33 -0
  146. package/dist/cjs/models/GroupEvent.cjs +2 -4
  147. package/dist/cjs/utils.cjs +229 -3
  148. package/dist/cjs/zalo.cjs +18 -7
  149. package/dist/index.d.ts +1 -0
  150. package/dist/models/GroupEvent.d.ts +2 -2
  151. package/dist/models/GroupEvent.js +2 -4
  152. package/dist/models/Message.d.ts +6 -0
  153. package/dist/zalo.d.ts +17 -10
  154. package/dist/zalo.js +19 -8
  155. 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('crypto-js');
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('crypto-js');
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;