zalo-toolkit 1.1.0 → 1.1.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.
@@ -8,7 +8,7 @@ import { Reaction } from '../models/Reaction.js';
8
8
  import { GroupSeenMessage, UserSeenMessage } from '../models/SeenMessage.js';
9
9
  import { GroupTyping, UserTyping } from '../models/Typing.js';
10
10
  import { Undo } from '../models/Undo.js';
11
- import { decodeEventData, FibonacciRetry, getFriendEventType, getGroupEventType, hasOwn, logger, looksLikeJson, makeURL } from '../utils.js';
11
+ import { decodeEventData, FibonacciRetry, getFriendEventType, getGroupEventType, hasOwn, logger, looksLikeJson, makeURL, safeJsonParse } from '../utils.js';
12
12
  import { ConfigSocket } from '../socket/config-socket.js';
13
13
  import { ZaloApiError } from '../Errors/ZaloApiError.js';
14
14
  import WebSocket from 'ws';
@@ -157,7 +157,9 @@ export class Listener extends EventEmitter {
157
157
  const decodedData = new TextDecoder('utf-8').decode(dataToDecode);
158
158
  if (decodedData.length == 0)
159
159
  return;
160
- const parsed = JSON.parse(decodedData);
160
+ const parsed = safeJsonParse(decodedData);
161
+ if (!parsed)
162
+ return;
161
163
  if (cmd === MessageCommand.Ping) {
162
164
  if (subCmd === KeepAliveCommand.KeepConnection || this.onlineConfigs.send_active_to_keep_live) {
163
165
  if ((_a = this.settingSocket.debug) === null || _a === void 0 ? void 0 : _a.skip_ping) {
@@ -261,7 +263,7 @@ export class Listener extends EventEmitter {
261
263
  // Zalo itself doesn't seem to handle this properly either, so we gonna ignore the join_reject event
262
264
  if (control.content.act == 'join_reject')
263
265
  continue;
264
- const groupEventData = typeof control.content.data == 'string' ? JSON.parse(control.content.data) : control.content.data;
266
+ const groupEventData = typeof control.content.data == 'string' && looksLikeJson(control.content.data) ? safeJsonParse(control.content.data) : control.content.data;
265
267
  const groupEvent = initializeGroupEvent(this.ctx.uid, groupEventData, getGroupEventType(control.content.act), control.content.act);
266
268
  const { data } = groupEvent;
267
269
  if (groupEvent.isSelf && !this.selfListen)
@@ -277,7 +279,7 @@ export class Listener extends EventEmitter {
277
279
  // Zalo itself doesn't seem to handle this properly either, so we gonna ignore the req event
278
280
  if (control.content.act == 'req' || control.content.act == 'seen_fr_req')
279
281
  continue;
280
- const friendEventData = typeof control.content.data === 'string' && looksLikeJson(control.content.data) ? JSON.parse(control.content.data) : control.content.data;
282
+ const friendEventData = typeof control.content.data === 'string' && looksLikeJson(control.content.data) ? safeJsonParse(control.content.data) : control.content.data;
281
283
  // Handles the case when act is "pin_create" and params is a string
282
284
  if (typeof friendEventData == 'object' && 'topic' in friendEventData && typeof friendEventData.topic == 'object' && 'params' in friendEventData.topic) {
283
285
  friendEventData.topic.params = JSON.parse(`${friendEventData.topic.params}`);
@@ -288,7 +290,7 @@ export class Listener extends EventEmitter {
288
290
  listFriendEvents.push(friendEvent);
289
291
  }
290
292
  else if (control.content.act_type == 'mute') {
291
- const muteData = typeof control.content.data == 'string' && looksLikeJson(control.content.data) ? JSON.parse(control.content.data) : control.content.data;
293
+ const muteData = typeof control.content.data == 'string' && looksLikeJson(control.content.data) ? safeJsonParse(control.content.data) : control.content.data;
292
294
  const { systemTime } = muteData;
293
295
  listMuteEvents.push({ data: muteData, act: control.content.act });
294
296
  if (systemTime) {
@@ -311,7 +313,7 @@ export class Listener extends EventEmitter {
311
313
  const { reacts, reactGroups, queueStatus } = parsedData;
312
314
  const listReactions = [];
313
315
  for (const react of reacts) {
314
- react.content = JSON.parse(react.content);
316
+ react.content = safeJsonParse(react.content);
315
317
  const reactionObject = new Reaction(this.ctx.uid, react, false);
316
318
  if (reactionObject.isSelf && !this.selfListen)
317
319
  continue;
@@ -319,7 +321,7 @@ export class Listener extends EventEmitter {
319
321
  this.emit('reaction', reactionObject);
320
322
  }
321
323
  for (const reactGroup of reactGroups) {
322
- reactGroup.content = JSON.parse(reactGroup.content);
324
+ reactGroup.content = safeJsonParse(reactGroup.content);
323
325
  const reactionObject = new Reaction(this.ctx.uid, reactGroup, true);
324
326
  if (reactionObject.isSelf && !this.selfListen)
325
327
  continue;
@@ -391,7 +393,7 @@ export class Listener extends EventEmitter {
391
393
  const parsedData = (await decodeEventData(parsed, this.cipherKey)).data;
392
394
  const { actions } = parsedData;
393
395
  for (const action of actions) {
394
- const data = JSON.parse(`{${action.data}}`);
396
+ const data = safeJsonParse(`{${action.data}}`);
395
397
  if (action.act_type == 'typing') {
396
398
  if (action.act == 'typing') {
397
399
  const typingObject = new UserTyping(data);
@@ -160,7 +160,9 @@ class Listener extends stream.EventEmitter {
160
160
  const decodedData = new TextDecoder('utf-8').decode(dataToDecode);
161
161
  if (decodedData.length == 0)
162
162
  return;
163
- const parsed = JSON.parse(decodedData);
163
+ const parsed = utils.safeJsonParse(decodedData);
164
+ if (!parsed)
165
+ return;
164
166
  if (cmd === Listen.MessageCommand.Ping) {
165
167
  if (subCmd === Listen.KeepAliveCommand.KeepConnection || this.onlineConfigs.send_active_to_keep_live) {
166
168
  if ((_a = this.settingSocket.debug) === null || _a === void 0 ? void 0 : _a.skip_ping) {
@@ -264,7 +266,7 @@ class Listener extends stream.EventEmitter {
264
266
  // Zalo itself doesn't seem to handle this properly either, so we gonna ignore the join_reject event
265
267
  if (control.content.act == 'join_reject')
266
268
  continue;
267
- const groupEventData = typeof control.content.data == 'string' ? JSON.parse(control.content.data) : control.content.data;
269
+ const groupEventData = typeof control.content.data == 'string' && utils.looksLikeJson(control.content.data) ? utils.safeJsonParse(control.content.data) : control.content.data;
268
270
  const groupEvent = GroupEvent.initializeGroupEvent(this.ctx.uid, groupEventData, utils.getGroupEventType(control.content.act), control.content.act);
269
271
  const { data } = groupEvent;
270
272
  if (groupEvent.isSelf && !this.selfListen)
@@ -280,7 +282,7 @@ class Listener extends stream.EventEmitter {
280
282
  // Zalo itself doesn't seem to handle this properly either, so we gonna ignore the req event
281
283
  if (control.content.act == 'req' || control.content.act == 'seen_fr_req')
282
284
  continue;
283
- const friendEventData = typeof control.content.data === 'string' && utils.looksLikeJson(control.content.data) ? JSON.parse(control.content.data) : control.content.data;
285
+ const friendEventData = typeof control.content.data === 'string' && utils.looksLikeJson(control.content.data) ? utils.safeJsonParse(control.content.data) : control.content.data;
284
286
  // Handles the case when act is "pin_create" and params is a string
285
287
  if (typeof friendEventData == 'object' && 'topic' in friendEventData && typeof friendEventData.topic == 'object' && 'params' in friendEventData.topic) {
286
288
  friendEventData.topic.params = JSON.parse(`${friendEventData.topic.params}`);
@@ -291,7 +293,7 @@ class Listener extends stream.EventEmitter {
291
293
  listFriendEvents.push(friendEvent);
292
294
  }
293
295
  else if (control.content.act_type == 'mute') {
294
- const muteData = typeof control.content.data == 'string' && utils.looksLikeJson(control.content.data) ? JSON.parse(control.content.data) : control.content.data;
296
+ const muteData = typeof control.content.data == 'string' && utils.looksLikeJson(control.content.data) ? utils.safeJsonParse(control.content.data) : control.content.data;
295
297
  const { systemTime } = muteData;
296
298
  listMuteEvents.push({ data: muteData, act: control.content.act });
297
299
  if (systemTime) {
@@ -314,7 +316,7 @@ class Listener extends stream.EventEmitter {
314
316
  const { reacts, reactGroups, queueStatus } = parsedData;
315
317
  const listReactions = [];
316
318
  for (const react of reacts) {
317
- react.content = JSON.parse(react.content);
319
+ react.content = utils.safeJsonParse(react.content);
318
320
  const reactionObject = new Reaction.Reaction(this.ctx.uid, react, false);
319
321
  if (reactionObject.isSelf && !this.selfListen)
320
322
  continue;
@@ -322,7 +324,7 @@ class Listener extends stream.EventEmitter {
322
324
  this.emit('reaction', reactionObject);
323
325
  }
324
326
  for (const reactGroup of reactGroups) {
325
- reactGroup.content = JSON.parse(reactGroup.content);
327
+ reactGroup.content = utils.safeJsonParse(reactGroup.content);
326
328
  const reactionObject = new Reaction.Reaction(this.ctx.uid, reactGroup, true);
327
329
  if (reactionObject.isSelf && !this.selfListen)
328
330
  continue;
@@ -394,7 +396,7 @@ class Listener extends stream.EventEmitter {
394
396
  const parsedData = (await utils.decodeEventData(parsed, this.cipherKey)).data;
395
397
  const { actions } = parsedData;
396
398
  for (const action of actions) {
397
- const data = JSON.parse(`{${action.data}}`);
399
+ const data = utils.safeJsonParse(`{${action.data}}`);
398
400
  if (action.act_type == 'typing') {
399
401
  if (action.act == 'typing') {
400
402
  const typingObject = new Typing.UserTyping(data);
@@ -692,6 +692,14 @@ function handleQueueStatus(queueStatus) {
692
692
  function looksLikeJson(str) {
693
693
  return /^[\[{].*[\]}]$/.test(str.trim());
694
694
  }
695
+ function safeJsonParse(input) {
696
+ try {
697
+ return JSON.parse(input);
698
+ }
699
+ catch (_a) {
700
+ return undefined;
701
+ }
702
+ }
695
703
 
696
704
  exports.FibonacciRetry = FibonacciRetry;
697
705
  exports.ParamsEncryptor = ParamsEncryptor;
@@ -725,4 +733,5 @@ exports.makeURL = makeURL;
725
733
  exports.removeUndefinedKeys = removeUndefinedKeys;
726
734
  exports.request = request;
727
735
  exports.resolveResponse = resolveResponse;
736
+ exports.safeJsonParse = safeJsonParse;
728
737
  exports.strPadLeft = strPadLeft;
package/dist/utils.d.ts CHANGED
@@ -187,4 +187,5 @@ export declare class FibonacciRetry {
187
187
  }
188
188
  export declare function handleQueueStatus(queueStatus: TypeQueueStatus): TypeQueueStatus;
189
189
  export declare function looksLikeJson(str: string): boolean;
190
+ export declare function safeJsonParse<T = any>(input: string): T | undefined;
190
191
  export {};
package/dist/utils.js CHANGED
@@ -749,3 +749,11 @@ export function handleQueueStatus(queueStatus) {
749
749
  export function looksLikeJson(str) {
750
750
  return /^[\[{].*[\]}]$/.test(str.trim());
751
751
  }
752
+ export function safeJsonParse(input) {
753
+ try {
754
+ return JSON.parse(input);
755
+ }
756
+ catch (_a) {
757
+ return undefined;
758
+ }
759
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zalo-toolkit",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "description": "Unofficial Zalo API for JavaScript",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",