chore: initialize dependencies and zca-js project files

This commit is contained in:
Victor Phan
2026-07-17 20:35:17 +07:00
parent caa9717571
commit d36007d989
1551 changed files with 191538 additions and 0 deletions
+33
View File
@@ -0,0 +1,33 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const acceptFriendRequestFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.friend[0]}/api/friend/accept`);
/**
* Accept a friend request from a User
*
* @param friendId The friend ID to user request is accept
*
* @throws {ZaloApiError}
*/
return async function acceptFriendRequest(friendId) {
const params = {
fid: friendId,
language: ctx.language,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
exports.acceptFriendRequestFactory = acceptFriendRequestFactory;
+33
View File
@@ -0,0 +1,33 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const addGroupBlockedMemberFactory = utils.apiFactory()((api, _, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/blockedmems/add`);
/**
* Add group blocked member
*
* @param memberId member id(s)
* @param groupId group id
*
* @throws {ZaloApiError}
*/
return async function addGroupBlockedMember(memberId, groupId) {
if (!Array.isArray(memberId))
memberId = [memberId];
const params = {
grid: groupId,
members: memberId,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.addGroupBlockedMemberFactory = addGroupBlockedMemberFactory;
+35
View File
@@ -0,0 +1,35 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const addGroupDeputyFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/admins/add`);
/**
* Add group deputy
*
* @param memberId user Id or list of user Ids
* @param groupId group Id
*
* @throws {ZaloApiError}
*
*/
return async function addGroupDeputy(memberId, groupId) {
if (!Array.isArray(memberId))
memberId = [memberId];
const params = {
grid: groupId,
members: memberId,
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.addGroupDeputyFactory = addGroupDeputyFactory;
+31
View File
@@ -0,0 +1,31 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const addPollOptionsFactory = utils.apiFactory()((api, _ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/poll/option/add`);
/**
* Add new option to poll
*
* @param payload
*
* @throws {ZaloApiError}
*/
return async function addPollOptions(payload) {
const params = {
poll_id: payload.pollId,
new_options: JSON.stringify(payload.options),
voted_option_ids: payload.votedOptionIds,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.addPollOptionsFactory = addPollOptionsFactory;
+65
View File
@@ -0,0 +1,65 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const addQuickMessageFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.quick_message[0]}/api/quickmessage/create`);
/**
* Add quick message
*
* @param addPayload - The payload containing data to add the quick message
*
* @note Zalo might throw an error with code 821 if you have reached the limit of quick messages.
*
* @throws {ZaloApiError}
*/
return async function addQuickMessage(addPayload) {
const isType = !addPayload.media ? 0 : 1;
const params = {
keyword: addPayload.keyword,
message: {
title: addPayload.title,
params: "",
},
type: isType,
imei: ctx.imei,
};
if (isType === 1) {
if (!addPayload.media)
throw new ZaloApiError.ZaloApiError("Media is required");
const uploadMedia = await api.uploadProductPhoto({
file: addPayload.media,
});
const photoId = uploadMedia.photoId;
const thumbUrl = uploadMedia.thumbUrl;
const normalUrl = uploadMedia.normalUrl;
const hdUrl = uploadMedia.hdUrl;
params.media = {
items: [
{
type: 0,
photoId: photoId,
title: "",
width: "",
height: "",
previewThumb: thumbUrl,
rawUrl: normalUrl || hdUrl,
thumbUrl: thumbUrl,
normalUrl: normalUrl || hdUrl,
hdUrl: hdUrl || normalUrl,
},
],
};
}
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.addQuickMessageFactory = addQuickMessageFactory;
+307
View File
@@ -0,0 +1,307 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
require('../models/AutoReply.cjs');
require('../models/Board.cjs');
var Enum = require('../models/Enum.cjs');
require('../models/FriendEvent.cjs');
require('../models/Group.cjs');
require('../models/GroupEvent.cjs');
var Reaction = require('../models/Reaction.cjs');
require('../models/Reminder.cjs');
require('../models/ZBusiness.cjs');
var utils = require('../utils.cjs');
const addReactionFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURLs = {
[Enum.ThreadType.User]: utils.makeURL(`${api.zpwServiceMap.reaction[0]}/api/message/reaction`),
[Enum.ThreadType.Group]: utils.makeURL(`${api.zpwServiceMap.reaction[0]}/api/group/reaction`),
};
/**
* Add reaction to a message
*
* @param icon Reaction icon
* @param dest Destination data including message IDs and thread information
*
* @throws {ZaloApiError}
*/
return async function addReaction(icon, dest) {
const serviceURL = serviceURLs[dest.type];
let rType, source;
if (typeof icon == "object") {
rType = icon.rType;
source = icon.source;
}
else
switch (icon) {
case Reaction.Reactions.HAHA:
rType = 0;
source = 6;
break;
case Reaction.Reactions.LIKE:
rType = 3;
source = 6;
break;
case Reaction.Reactions.HEART:
rType = 5;
source = 6;
break;
case Reaction.Reactions.WOW:
rType = 32;
source = 6;
break;
case Reaction.Reactions.CRY:
rType = 2;
source = 6;
break;
case Reaction.Reactions.ANGRY:
rType = 20;
source = 6;
break;
case Reaction.Reactions.KISS:
rType = 8;
source = 6;
break;
case Reaction.Reactions.TEARS_OF_JOY:
rType = 7;
source = 6;
break;
case Reaction.Reactions.SHIT:
rType = 66;
source = 6;
break;
case Reaction.Reactions.ROSE:
rType = 120;
source = 6;
break;
case Reaction.Reactions.BROKEN_HEART:
rType = 65;
source = 6;
break;
case Reaction.Reactions.DISLIKE:
rType = 4;
source = 6;
break;
case Reaction.Reactions.LOVE:
rType = 29;
source = 6;
break;
case Reaction.Reactions.CONFUSED:
rType = 51;
source = 6;
break;
case Reaction.Reactions.WINK:
rType = 45;
source = 6;
break;
case Reaction.Reactions.FADE:
rType = 121;
source = 6;
break;
case Reaction.Reactions.SUN:
rType = 67;
source = 6;
break;
case Reaction.Reactions.BIRTHDAY:
rType = 126;
source = 6;
break;
case Reaction.Reactions.BOMB:
rType = 127;
source = 6;
break;
case Reaction.Reactions.OK:
rType = 68;
source = 6;
break;
case Reaction.Reactions.PEACE:
rType = 69;
source = 6;
break;
case Reaction.Reactions.THANKS:
rType = 70;
source = 6;
break;
case Reaction.Reactions.PUNCH:
rType = 71;
source = 6;
break;
case Reaction.Reactions.SHARE:
rType = 72;
source = 6;
break;
case Reaction.Reactions.PRAY:
rType = 73;
source = 6;
break;
case Reaction.Reactions.NO:
rType = 131;
source = 6;
break;
case Reaction.Reactions.BAD:
rType = 132;
source = 6;
break;
case Reaction.Reactions.LOVE_YOU:
rType = 133;
source = 6;
break;
case Reaction.Reactions.SAD:
rType = 1;
source = 6;
break;
case Reaction.Reactions.VERY_SAD:
rType = 16;
source = 6;
break;
case Reaction.Reactions.COOL:
rType = 21;
source = 6;
break;
case Reaction.Reactions.NERD:
rType = 22;
source = 6;
break;
case Reaction.Reactions.BIG_SMILE:
rType = 23;
source = 6;
break;
case Reaction.Reactions.SUNGLASSES:
rType = 26;
source = 6;
break;
case Reaction.Reactions.NEUTRAL:
rType = 30;
source = 6;
break;
case Reaction.Reactions.SAD_FACE:
rType = 35;
source = 6;
break;
case Reaction.Reactions.BYE:
rType = 36;
source = 6;
break;
case Reaction.Reactions.SLEEPY:
rType = 38;
source = 6;
break;
case Reaction.Reactions.WIPE:
rType = 39;
source = 6;
break;
case Reaction.Reactions.DIG:
rType = 42;
source = 6;
break;
case Reaction.Reactions.ANGUISH:
rType = 44;
source = 6;
break;
case Reaction.Reactions.HANDCLAP:
rType = 46;
source = 6;
break;
case Reaction.Reactions.ANGRY_FACE:
rType = 47;
source = 6;
break;
case Reaction.Reactions.F_CHAIR:
rType = 48;
source = 6;
break;
case Reaction.Reactions.L_CHAIR:
rType = 49;
source = 6;
break;
case Reaction.Reactions.R_CHAIR:
rType = 50;
source = 6;
break;
case Reaction.Reactions.SILENT:
rType = 52;
source = 6;
break;
case Reaction.Reactions.SURPRISE:
rType = 53;
source = 6;
break;
case Reaction.Reactions.EMBARRASSED:
rType = 54;
source = 6;
break;
case Reaction.Reactions.AFRAID:
rType = 60;
source = 6;
break;
case Reaction.Reactions.SAD2:
rType = 61;
source = 6;
break;
case Reaction.Reactions.BIG_LAUGH:
rType = 62;
source = 6;
break;
case Reaction.Reactions.RICH:
rType = 63;
source = 6;
break;
case Reaction.Reactions.BEER:
rType = 99;
source = 6;
break;
default:
rType = -1;
source = 6;
}
const rIcon = typeof icon == "object" ? icon.icon : icon;
if (rType == undefined || source == undefined || rIcon == undefined) {
throw new ZaloApiError.ZaloApiError("Invalid reaction");
}
const params = {
react_list: [
{
message: JSON.stringify({
rMsg: [
{
gMsgID: parseInt(dest.data.msgId),
cMsgID: parseInt(dest.data.cliMsgId),
msgType: 1,
},
],
rIcon,
rType,
source,
}),
clientId: Date.now(),
},
],
};
if (dest.type == Enum.ThreadType.User) {
params.toid = dest.threadId;
}
else {
params.grid = dest.threadId;
params.imei = ctx.imei;
}
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt message");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response, (result) => {
if (typeof result.data.msgIds === "string") {
return {
msgIds: JSON.parse(result.data.msgIds),
};
}
return result.data;
});
};
});
exports.addReactionFactory = addReactionFactory;
+65
View File
@@ -0,0 +1,65 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
require('../models/AutoReply.cjs');
require('../models/Board.cjs');
var Enum = require('../models/Enum.cjs');
require('../models/FriendEvent.cjs');
require('../models/Group.cjs');
require('../models/GroupEvent.cjs');
require('../models/Reaction.cjs');
require('../models/Reminder.cjs');
require('../models/ZBusiness.cjs');
var utils = require('../utils.cjs');
const addUnreadMarkFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.conversation[0]}/api/conv/addUnreadMark`);
/**
* Add unread mark to conversation
*
* @param threadId Thread ID
* @param type Thread type (User/Group)
*
* @throws {ZaloApiError}
*/
return async function addUnreadMark(threadId, type = Enum.ThreadType.User) {
const timestamp = Date.now();
const timestampString = timestamp.toString();
const isGroup = type === Enum.ThreadType.Group;
const requestParams = {
param: JSON.stringify({
[isGroup ? "convsGroup" : "convsUser"]: [
{
id: threadId,
cliMsgId: timestampString,
fromUid: "0",
ts: timestamp,
},
],
[isGroup ? "convsUser" : "convsGroup"]: [],
imei: ctx.imei,
}),
};
const encryptedParams = utils.encodeAES(JSON.stringify(requestParams));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response, (result) => {
const data = result.data;
if (typeof data.data === "string") {
return {
data: JSON.parse(data.data),
status: data.status,
};
}
return result.data;
});
};
});
exports.addUnreadMarkFactory = addUnreadMarkFactory;
+39
View File
@@ -0,0 +1,39 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const addUserToGroupFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/invite/v2`);
/**
* Add user to existing group
*
* @param memberId User ID or list of user IDs to add
* @param groupId Group ID
*
* @throws {ZaloApiError}
*/
return async function addUserToGroup(memberId, groupId) {
if (!Array.isArray(memberId))
memberId = [memberId];
const params = {
grid: groupId,
members: memberId,
memberTypes: memberId.map(() => -1),
imei: ctx.imei,
clientLang: ctx.language,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
exports.addUserToGroupFactory = addUserToGroupFactory;
+33
View File
@@ -0,0 +1,33 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const blockUserFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.friend[0]}/api/friend/block`);
/**
* Block a User
*
* @param userId The ID of the User to block
*
* @throws {ZaloApiError}
*/
return async function blockUser(userId) {
const params = {
fid: userId,
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
exports.blockUserFactory = blockUserFactory;
+35
View File
@@ -0,0 +1,35 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const blockViewFeedFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.friend[0]}/api/friend/feed/block`);
/**
* Block/Unblock friend view feed by ID
*
* @param isBlockFeed Boolean to block/unblock view feed
* @param userId User ID to block/unblock view feed
*
* @throws {ZaloApiError}
*/
return async function blockViewFeed(isBlockFeed, userId) {
const params = {
fid: userId,
isBlockFeed: isBlockFeed ? 1 : 0,
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
exports.blockViewFeedFactory = blockViewFeedFactory;
+57
View File
@@ -0,0 +1,57 @@
'use strict';
var FormData = require('form-data');
var fs = require('node:fs');
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const changeAccountAvatarFactory = utils.apiFactory()((api, ctx, utils$1) => {
const serviceURL = utils$1.makeURL(`${api.zpwServiceMap.file[0]}/api/profile/upavatar`);
/**
* Change account avatar
*
* @param avatarSource Attachment source, can be a file path or an Attachment object
*
* @throws {ZaloApiError | ZaloApiMissingImageMetadataGetter}
*/
return async function changeAccountAvatar(avatarSource) {
const isSourceFilePath = typeof avatarSource == "string";
const imageMetaData = isSourceFilePath ? await utils.getImageMetaData(ctx, avatarSource) : avatarSource.metadata;
const fileSize = imageMetaData.totalSize || 0;
const params = {
avatarSize: 120,
clientId: String(ctx.uid + utils.formatTime("%H:%M %d/%m/%Y")),
language: ctx.language,
metaData: JSON.stringify({
origin: {
width: imageMetaData.width || 1080,
height: imageMetaData.height || 1080,
},
processed: {
width: imageMetaData.width || 1080,
height: imageMetaData.height || 1080,
size: fileSize,
},
}),
};
const avatarData = isSourceFilePath ? fs.readFileSync(avatarSource) : avatarSource.data;
const formData = new FormData();
formData.append("fileContent", avatarData, {
filename: "blob",
contentType: "image/jpeg",
});
const encryptedParams = utils$1.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils$1.request(utils$1.makeURL(serviceURL, {
params: encryptedParams,
}), {
method: "POST",
headers: formData.getHeaders(),
body: formData.getBuffer(),
});
return utils$1.resolve(response);
};
});
exports.changeAccountAvatarFactory = changeAccountAvatarFactory;
+32
View File
@@ -0,0 +1,32 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const changeFriendAliasFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.alias[0]}/api/alias/update`);
/**
* Change friend's alias
*
* @param alias new alias (nickname - bietdanh)
* @param friendId friend id
*
* @throws {ZaloApiError}
*/
return async function changeFriendAlias(alias, friendId) {
const params = {
friendId: friendId,
alias: alias,
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.changeFriendAliasFactory = changeFriendAliasFactory;
+49
View File
@@ -0,0 +1,49 @@
'use strict';
var FormData = require('form-data');
var fs = require('node:fs');
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const changeGroupAvatarFactory = utils.apiFactory()((api, ctx, utils$1) => {
const serviceURL = utils$1.makeURL(`${api.zpwServiceMap.file[0]}/api/group/upavatar`);
/**
* Change group avatar
*
* @param avatarSource Attachment source, can be a file path or an Attachment object
* @param groupId Group ID
*
* @throws {ZaloApiError | ZaloApiMissingImageMetadataGetter}
*/
return async function changeGroupAvatar(avatarSource, groupId) {
const params = {
grid: groupId,
avatarSize: 120,
clientId: `g${groupId}${utils.getFullTimeFromMillisecond(new Date().getTime())}`,
imei: ctx.imei,
};
const isSourceFilePath = typeof avatarSource == "string";
const imageMetaData = isSourceFilePath ? await utils.getImageMetaData(ctx, avatarSource) : avatarSource.metadata;
params.originWidth = imageMetaData.width || 1080;
params.originHeight = imageMetaData.height || 1080;
const avatarData = isSourceFilePath ? fs.readFileSync(avatarSource) : avatarSource.data;
const formData = new FormData();
formData.append("fileContent", avatarData, {
filename: "blob",
contentType: "image/jpeg",
});
const encryptedParams = utils$1.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils$1.request(utils$1.makeURL(serviceURL, {
params: encryptedParams,
}), {
method: "POST",
headers: formData.getHeaders(),
body: formData.getBuffer(),
});
return utils$1.resolve(response);
};
});
exports.changeGroupAvatarFactory = changeGroupAvatarFactory;
+37
View File
@@ -0,0 +1,37 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const changeGroupNameFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/updateinfo`);
/**
* Change group name
*
* @param name New group name
* @param groupId Group ID
*
* @throws {ZaloApiError}
*/
return async function changeGroupName(name, groupId) {
if (name.length == 0)
name = Date.now().toString();
const params = {
grid: groupId,
gname: name,
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
exports.changeGroupNameFactory = changeGroupNameFactory;
+35
View File
@@ -0,0 +1,35 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const changeGroupOwnerFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/change-owner`);
/**
* Change group owner
*
* @param memberId User Id of new group owner
* @param groupId Group Id
* @note Be careful when changing the key, as it will result in losing group admin rights
*
* @throws {ZaloApiError}
*
*/
return async function changeGroupOwner(memberId, groupId) {
const params = {
grid: groupId,
newAdminId: memberId,
imei: ctx.imei,
language: ctx.language,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.changeGroupOwnerFactory = changeGroupOwnerFactory;
+42
View File
@@ -0,0 +1,42 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const createAutoReplyFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.auto_reply[0]}/api/autoreply/create`);
/**
* Create auto reply
*
* @param payload payload
*
* @note this API used for zBusiness
* @throws {ZaloApiError}
*/
return async function createAutoReply(payload) {
const uids = Array.isArray(payload.uids) ? payload.uids : [payload.uids];
const resultUids = (payload.scope === 2 || payload.scope === 3) ? uids : [];
const params = {
cliLang: ctx.language,
enable: payload.isEnable,
content: payload.content,
startTime: payload.startTime,
endTime: payload.endTime,
recurrence: ["RRULE:FREQ=DAILY;"],
scope: payload.scope,
uids: resultUids,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
exports.createAutoReplyFactory = createAutoReplyFactory;
+34
View File
@@ -0,0 +1,34 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const createCatalogFactory = utils.apiFactory()((api, _, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.catalog[0]}/api/prodcatalog/catalog/create`);
/**
* Create catalog?
*
* @param catalogName catalog name
*
* @note this API is used for zBusiness
* @throws {ZaloApiError}
*/
return async function createCatalog(catalogName) {
const params = {
catalog_name: catalogName,
catalog_photo: "",
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
exports.createCatalogFactory = createCatalogFactory;
+48
View File
@@ -0,0 +1,48 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const createGroupFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/create/v2`);
/**
* Create a new group
*
* @param options Group options
*
* @throws {ZaloApiError}
*/
return async function createGroup(options) {
if (options.members.length == 0)
throw new ZaloApiError.ZaloApiError("Group must have at least one member");
const params = {
clientId: Date.now(),
gname: String(Date.now()),
gdesc: null,
members: options.members,
membersTypes: options.members.map(() => -1),
nameChanged: 0,
createLink: 1,
clientLang: ctx.language,
imei: ctx.imei,
zsource: 601,
};
if (options.name && options.name.length > 0) {
params.gname = options.name;
params.nameChanged = 1;
}
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt message");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "POST",
});
const data = await utils.resolve(response);
options.avatarSource = options.avatarSource || options.avatarPath;
if (options.avatarSource)
await api.changeGroupAvatar(options.avatarSource, data.groupId).catch(utils.logger.error);
return data;
};
});
exports.createGroupFactory = createGroupFactory;
+52
View File
@@ -0,0 +1,52 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const createNoteFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group_board[0]}/api/board/topic/createv2`);
/**
* Create a note in a group
*
* @param options note options
* @param options.title note title
* @param options.pinAct pin action (pin note)
* @param groupId group id
*
* @throws {ZaloApiError}
*/
return async function createNote(options, groupId) {
const params = {
grid: groupId,
type: 0,
color: -16777216,
emoji: "",
startTime: -1,
duration: -1,
params: JSON.stringify({
title: options.title,
}),
repeat: 0,
src: 1,
imei: ctx.imei,
pinAct: options.pinAct ? 1 : 0,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response, (result) => {
if (typeof result.data.params === "string") {
result.data.params = JSON.parse(result.data.params);
}
return result.data;
});
};
});
exports.createNoteFactory = createNoteFactory;
+45
View File
@@ -0,0 +1,45 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const createPollFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/poll/create`);
/**
* Create a poll in a group.
*
* @param options Poll options
* @param groupId Group ID to create poll from
*
* @throws {ZaloApiError}
*/
return async function createPoll(options, groupId) {
var _a;
const params = {
group_id: groupId,
question: options.question,
options: options.options,
expired_time: (_a = options.expiredTime) !== null && _a !== void 0 ? _a : 0,
pinAct: false,
allow_multi_choices: !!options.allowMultiChoices,
allow_add_new_option: !!options.allowAddNewOption,
is_hide_vote_preview: !!options.hideVotePreview,
is_anonymous: !!options.isAnonymous,
poll_type: 0,
src: 1,
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
exports.createPollFactory = createPollFactory;
+55
View File
@@ -0,0 +1,55 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const createProductCatalogFactory = utils.apiFactory()((api, _, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.catalog[0]}/api/prodcatalog/product/create`);
/**
* Create product catalog?
*
* @param payload payload
*
* @note this API is used for zBussiness - Maximum 5 media files are supported
* @throws {ZaloApiError}
*/
return async function createProductCatalog(payload) {
const productPhoto = payload.product_photos || [];
if (payload.files && payload.files.length == 0) {
if (payload.files.length > 5) {
throw new ZaloApiError.ZaloApiError("Maximum 5 media files are allowed");
}
for (const mediaFile of payload.files) {
const uploadMedia = await api.uploadProductPhoto({
file: mediaFile,
});
const url = uploadMedia.normalUrl || uploadMedia.hdUrl;
productPhoto.push(url);
}
}
if (productPhoto.length > 5) {
throw new ZaloApiError.ZaloApiError("Maximum 5 media files are allowed");
}
const params = {
product_name: payload.productName,
price: payload.price,
description: payload.description,
product_photos: productPhoto,
catalog_id: payload.catalogId,
currency_unit: "₫", // $
create_time: Date.now(),
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
exports.createProductCatalogFactory = createProductCatalogFactory;
+76
View File
@@ -0,0 +1,76 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
require('../models/AutoReply.cjs');
require('../models/Board.cjs');
var Enum = require('../models/Enum.cjs');
require('../models/FriendEvent.cjs');
require('../models/Group.cjs');
require('../models/GroupEvent.cjs');
require('../models/Reaction.cjs');
var Reminder = require('../models/Reminder.cjs');
require('../models/ZBusiness.cjs');
var utils = require('../utils.cjs');
const createReminderFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = {
[Enum.ThreadType.User]: utils.makeURL(`${api.zpwServiceMap.group_board[0]}/api/board/oneone/create`),
[Enum.ThreadType.Group]: utils.makeURL(`${api.zpwServiceMap.group_board[0]}/api/board/topic/createv2`),
};
/**
* Create a reminder in a group
*
* @param options reminder options
* @param threadId Group ID to create note from
* @param type Thread type (User or Group)
*
* @throws {ZaloApiError}
*/
return async function createReminder(options, threadId, type = Enum.ThreadType.User) {
var _a, _b, _c, _d, _e, _f;
const params = type === Enum.ThreadType.User
? {
objectData: JSON.stringify({
toUid: threadId,
type: 0,
color: -16245706,
emoji: (_a = options.emoji) !== null && _a !== void 0 ? _a : "⏰",
startTime: (_b = options.startTime) !== null && _b !== void 0 ? _b : Date.now(),
duration: -1,
params: { title: options.title },
needPin: false,
repeat: (_c = options.repeat) !== null && _c !== void 0 ? _c : Reminder.ReminderRepeatMode.None,
creatorUid: ctx.uid, // Note: for some reason, you can put any valid UID here instead of your own and it still works, atleast for mobile
src: 1,
}),
imei: ctx.imei,
}
: {
grid: threadId,
type: 0,
color: -16245706,
emoji: (_d = options.emoji) !== null && _d !== void 0 ? _d : "⏰",
startTime: (_e = options.startTime) !== null && _e !== void 0 ? _e : Date.now(),
duration: -1,
params: JSON.stringify({
title: options.title,
}),
repeat: (_f = options.repeat) !== null && _f !== void 0 ? _f : Reminder.ReminderRepeatMode.None,
src: 1,
imei: ctx.imei,
pinAct: 0,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL[type], {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
exports.createReminderFactory = createReminderFactory;
+19
View File
@@ -0,0 +1,19 @@
'use strict';
var utils = require('../utils.cjs');
/* eslint-disable */
const customFactory = utils.apiFactory()((api, ctx, utils) => {
return function custom(name, callback) {
Object.defineProperty(api, name, {
value: function (props) {
return callback({ ctx, utils, props });
},
writable: false,
enumerable: false,
configurable: false,
});
};
});
exports.customFactory = customFactory;
+34
View File
@@ -0,0 +1,34 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const deleteAutoReplyFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.auto_reply[0]}/api/autoreply/delete`);
/**
* Delete auto reply
*
* @param id id of auto reply
*
* @note this API used for zBusiness
* @throws {ZaloApiError}
*/
return async function deleteAutoReply(id) {
const params = {
cliLang: ctx.language,
id: id,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
exports.deleteAutoReplyFactory = deleteAutoReplyFactory;
+32
View File
@@ -0,0 +1,32 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const deleteAvatarFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.profile[0]}/api/social/del-avatars`);
/**
* Delete avatar from avatar list
*
* @param photoId avatar photo ID(s) to delete - can be a single string or array of strings
*
* @throws {ZaloApiError}
*/
return async function deleteAvatar(photoId) {
const photoIds = Array.isArray(photoId) ? photoId : [photoId];
const delPhotos = photoIds.map((id) => ({ photoId: id }));
const params = {
delPhotos: JSON.stringify(delPhotos),
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.deleteAvatarFactory = deleteAvatarFactory;
+33
View File
@@ -0,0 +1,33 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const deleteCatalogFactory = utils.apiFactory()((api, _, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.catalog[0]}/api/prodcatalog/catalog/delete`);
/**
* Delete catalog?
*
* @param catalogId catalog id
*
* @note this API is used for zBusiness
* @throws {ZaloApiError}
*/
return async function deleteCatalog(catalogId) {
const params = {
catalog_id: catalogId,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
exports.deleteCatalogFactory = deleteCatalogFactory;
+63
View File
@@ -0,0 +1,63 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
require('../models/AutoReply.cjs');
require('../models/Board.cjs');
var Enum = require('../models/Enum.cjs');
require('../models/FriendEvent.cjs');
require('../models/Group.cjs');
require('../models/GroupEvent.cjs');
require('../models/Reaction.cjs');
require('../models/Reminder.cjs');
require('../models/ZBusiness.cjs');
var utils = require('../utils.cjs');
const deleteChatFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = {
[Enum.ThreadType.User]: utils.makeURL(`${api.zpwServiceMap.chat[0]}/api/message/deleteconver`, {
nretry: 0,
}),
[Enum.ThreadType.Group]: utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/deleteconver`, {
nretry: 0,
}),
};
/**
* Delete chat
*
* @param lastMessage Last message info
* @param threadId Thread ID
* @param type Thread type
*
* @throws {ZaloApiError}
*/
return async function deleteChat(lastMessage, threadId, type = Enum.ThreadType.User) {
const timestampString = Date.now().toString();
const params = type === Enum.ThreadType.User
? {
toid: threadId,
cliMsgId: timestampString,
conver: lastMessage,
onlyMe: 1,
imei: ctx.imei,
}
: {
grid: threadId,
cliMsgId: timestampString,
conver: lastMessage,
onlyMe: 1,
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL[type], {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
exports.deleteChatFactory = deleteChatFactory;
+32
View File
@@ -0,0 +1,32 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const deleteGroupInviteBoxFactory = utils.apiFactory()((api, _, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/inv-box/mdel-inv`);
/**
* Delete group invite box
*
* @param groupId - The group id
* @param blockFutureInvite - Whether to block future invites from this group
*
* @throws {ZaloApiError}
*/
return async function deleteGroupInviteBox(groupId, blockFutureInvite = false) {
const grids = Array.isArray(groupId) ? groupId : [groupId];
const params = {
invitations: JSON.stringify(grids.map((grid) => ({ grid }))),
block: blockFutureInvite ? 1 : 0,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.deleteGroupInviteBoxFactory = deleteGroupInviteBoxFactory;
+65
View File
@@ -0,0 +1,65 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
require('../models/AutoReply.cjs');
require('../models/Board.cjs');
var Enum = require('../models/Enum.cjs');
require('../models/FriendEvent.cjs');
require('../models/Group.cjs');
require('../models/GroupEvent.cjs');
require('../models/Reaction.cjs');
require('../models/Reminder.cjs');
require('../models/ZBusiness.cjs');
var utils = require('../utils.cjs');
const deleteMessageFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = {
[Enum.ThreadType.User]: utils.makeURL(`${api.zpwServiceMap.chat[0]}/api/message/delete`),
[Enum.ThreadType.Group]: utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/deletemsg`),
};
/**
* Delete a message
*
* @param dest Delete target
* @param onlyMe Delete message for only you
*
* @throws {ZaloApiError}
*/
return async function deleteMessage(dest, onlyMe = false) {
const { threadId, type = Enum.ThreadType.User, data } = dest;
const isGroup = type === Enum.ThreadType.Group;
const isSelf = ctx.uid == data.uidFrom;
if (isSelf && onlyMe === false)
throw new ZaloApiError.ZaloApiError("To delete your message for everyone, use undo api instead");
if (!isGroup && onlyMe === false)
throw new ZaloApiError.ZaloApiError("Can't delete message for everyone in a private chat");
const params = {
[isGroup ? "grid" : "toid"]: threadId,
cliMsgId: Date.now(),
msgs: [
{
cliMsgId: data.cliMsgId,
globalMsgId: data.msgId,
ownerId: data.uidFrom,
destId: threadId,
},
],
onlyMe: onlyMe ? 1 : 0,
};
if (!isGroup) {
params.imei = ctx.imei;
}
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt message");
const response = await utils.request(serviceURL[type], {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
exports.deleteMessageFactory = deleteMessageFactory;
+36
View File
@@ -0,0 +1,36 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const deleteProductCatalogFactory = utils.apiFactory()((api, _, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.catalog[0]}/api/prodcatalog/product/mdelete`);
/**
* Delete product catalog?
*
* @param payload payload
*
* @note this API is used for zBusiness
* @throws {ZaloApiError}
*/
return async function deleteProductCatalog(payload) {
if (!Array.isArray(payload.productIds))
payload.productIds = [payload.productIds];
const params = {
product_ids: payload.productIds,
catalog_id: payload.catalogId,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
exports.deleteProductCatalogFactory = deleteProductCatalogFactory;
+29
View File
@@ -0,0 +1,29 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const disableGroupLinkFactory = utils.apiFactory()((api, _ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/link/disable`);
/**
* Disable group link
*
* @param groupId The group id
*
* @throws {ZaloApiError}
*/
return async function disableGroupLink(groupId) {
const params = {
grid: groupId,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.disableGroupLinkFactory = disableGroupLinkFactory;
+33
View File
@@ -0,0 +1,33 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const disperseGroupFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/disperse`);
/**
* Disperse Group
*
* @param groupId Group ID to disperse Group from
*
* @throws {ZaloApiError}
*/
return async function disperseGroup(groupId) {
const params = {
grid: groupId,
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
exports.disperseGroupFactory = disperseGroupFactory;
+51
View File
@@ -0,0 +1,51 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const editNoteFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group_board[0]}/api/board/topic/updatev2`);
/**
* Edit an existing note in a group
*
* @param options Options for editing the note
* @param groupId Group ID to create note from
*
* @throws {ZaloApiError}
*/
return async function editNote(options, groupId) {
const params = {
grid: groupId,
type: 0,
color: -16777216,
emoji: "",
startTime: -1,
duration: -1,
params: JSON.stringify({
title: options.title,
}),
topicId: options.topicId,
repeat: 0,
imei: ctx.imei,
pinAct: options.pinAct ? 1 : 2,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response, (result) => {
const data = result.data;
if (typeof data.params == "string") {
data.params = JSON.parse(data.params);
}
return data;
});
};
});
exports.editNoteFactory = editNoteFactory;
+74
View File
@@ -0,0 +1,74 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
require('../models/AutoReply.cjs');
require('../models/Board.cjs');
var Enum = require('../models/Enum.cjs');
require('../models/FriendEvent.cjs');
require('../models/Group.cjs');
require('../models/GroupEvent.cjs');
require('../models/Reaction.cjs');
require('../models/Reminder.cjs');
require('../models/ZBusiness.cjs');
var utils = require('../utils.cjs');
const editReminderFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = {
[Enum.ThreadType.User]: utils.makeURL(`${api.zpwServiceMap.group_board[0]}/api/board/oneone/update`),
[Enum.ThreadType.Group]: utils.makeURL(`${api.zpwServiceMap.group_board[0]}/api/board/topic/updatev2`),
};
/**
* Edit an existing reminder
*
* @param options Reminder parameters
* @param threadId Thread ID
* @param type Thread type (User/Group)
*
* @throws {ZaloApiError}
*/
return async function editReminder(options, threadId, type = Enum.ThreadType.User) {
var _a, _b, _c, _d, _e, _f;
const requestParams = type === Enum.ThreadType.User
? {
objectData: JSON.stringify({
toUid: threadId,
type: 0,
color: -16777216,
emoji: (_a = options.emoji) !== null && _a !== void 0 ? _a : "",
startTime: (_b = options.startTime) !== null && _b !== void 0 ? _b : Date.now(),
duration: -1,
params: { title: options.title },
needPin: false,
reminderId: options.topicId,
repeat: (_c = options.repeat) !== null && _c !== void 0 ? _c : 0,
}),
}
: {
grid: threadId,
type: 0,
color: -16777216,
emoji: (_d = options.emoji) !== null && _d !== void 0 ? _d : "",
startTime: (_e = options.startTime) !== null && _e !== void 0 ? _e : Date.now(),
duration: -1,
params: JSON.stringify({
title: options.title,
}),
topicId: options.topicId,
repeat: (_f = options.repeat) !== null && _f !== void 0 ? _f : 0,
imei: ctx.imei,
pinAct: 2,
};
const encryptedParams = utils.encodeAES(JSON.stringify(requestParams));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL[type], {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
exports.editReminderFactory = editReminderFactory;
+30
View File
@@ -0,0 +1,30 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const enableGroupLinkFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/link/new`);
/**
* Enable and create new group link
*
* @param groupId The group id
*
* @throws {ZaloApiError}
*/
return async function enableGroupLink(groupId) {
const params = {
grid: groupId,
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.enableGroupLinkFactory = enableGroupLinkFactory;
+15
View File
@@ -0,0 +1,15 @@
'use strict';
var utils = require('../utils.cjs');
const fetchAccountInfoFactory = utils.apiFactory()((api, _, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.profile[0]}/api/social/profile/me-v2`);
return async function fetchAccountInfo() {
const response = await utils.request(serviceURL, {
method: "GET",
});
return utils.resolve(response);
};
});
exports.fetchAccountInfoFactory = fetchAccountInfoFactory;
+55
View File
@@ -0,0 +1,55 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
require('../models/AutoReply.cjs');
require('../models/Board.cjs');
var Enum = require('../models/Enum.cjs');
require('../models/FriendEvent.cjs');
require('../models/Group.cjs');
require('../models/GroupEvent.cjs');
require('../models/Reaction.cjs');
require('../models/Reminder.cjs');
require('../models/ZBusiness.cjs');
const findUserFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.friend[0]}/api/friend/profile/get`);
/**
* Find user by phone number
*
* @param phoneNumber Phone number
* @param avatarSize Avatar size (default: AvatarSize.Large)
*
* @throws {ZaloApiError}
*/
return async function findUser(phoneNumber, avatarSize = Enum.AvatarSize.Large) {
if (!phoneNumber)
throw new ZaloApiError.ZaloApiError("Missing phoneNumber");
if (phoneNumber.startsWith("0")) {
if (ctx.language == "vi")
phoneNumber = "84" + phoneNumber.slice(1);
}
const params = {
phone: phoneNumber,
avatar_size: avatarSize,
language: ctx.language,
imei: ctx.imei,
reqSrc: 40,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt message");
const finalServiceUrl = new URL(serviceURL);
finalServiceUrl.searchParams.append("params", encryptedParams);
const response = await utils.request(utils.makeURL(finalServiceUrl.toString(), {
params: encryptedParams,
}));
return utils.resolve(response, (result) => {
if (result.error && result.error.code != 216)
throw new ZaloApiError.ZaloApiError(result.error.message, result.error.code);
return result.data;
});
};
});
exports.findUserFactory = findUserFactory;
+40
View File
@@ -0,0 +1,40 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
require('../models/AutoReply.cjs');
require('../models/Board.cjs');
var Enum = require('../models/Enum.cjs');
require('../models/FriendEvent.cjs');
require('../models/Group.cjs');
require('../models/GroupEvent.cjs');
require('../models/Reaction.cjs');
require('../models/Reminder.cjs');
require('../models/ZBusiness.cjs');
const findUserByUsernameFactory = utils.apiFactory()((api, _ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.friend[0]}/api/friend/search/by-user-name`);
/**
* Find user by username
*
* @param username username for find
* @param avatarSize Avatar size (default: AvatarSize.Large)
*
* @throws {ZaloApiError}
*/
return async function findUserByUsername(username, avatarSize = Enum.AvatarSize.Large) {
const params = {
user_name: username,
avatar_size: avatarSize,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.findUserByUsernameFactory = findUserByUsernameFactory;
+112
View File
@@ -0,0 +1,112 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
require('../models/AutoReply.cjs');
require('../models/Board.cjs');
var Enum = require('../models/Enum.cjs');
require('../models/FriendEvent.cjs');
require('../models/Group.cjs');
require('../models/GroupEvent.cjs');
require('../models/Reaction.cjs');
require('../models/Reminder.cjs');
require('../models/ZBusiness.cjs');
var utils = require('../utils.cjs');
const forwardMessageFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = {
[Enum.ThreadType.User]: utils.makeURL(`${api.zpwServiceMap.file[0]}/api/message/mforward`),
[Enum.ThreadType.Group]: utils.makeURL(`${api.zpwServiceMap.file[0]}/api/group/mforward`),
};
/**
* Forward message to multiple threads
*
* @param payload Forward message payload
* @param threadId Thread ID(s)
* @param type Thread type (User/Group)
*
* @throws {ZaloApiError}
*/
return async function forwardMessage(payload, threadIds, type = Enum.ThreadType.User) {
var _a, _b;
if (!payload.message)
throw new ZaloApiError.ZaloApiError("Missing message content");
if (!threadIds || threadIds.length === 0)
throw new ZaloApiError.ZaloApiError("Missing thread IDs");
const timestamp = Date.now();
const clientId = timestamp.toString();
const msgInfo = {
message: payload.message,
reference: payload.reference
? JSON.stringify({
type: 3,
data: JSON.stringify(payload.reference),
})
: undefined,
};
const decorLog = payload.reference
? {
fw: {
pmsg: {
st: 1,
ts: payload.reference.ts,
id: payload.reference.id,
},
rmsg: {
st: 1,
ts: payload.reference.ts,
id: payload.reference.id,
},
fwLvl: payload.reference.fwLvl,
},
}
: null;
let params;
if (type === Enum.ThreadType.User) {
params = {
toIds: threadIds.map((threadId) => {
var _a;
return ({
clientId,
toUid: threadId,
ttl: (_a = payload.ttl) !== null && _a !== void 0 ? _a : 0,
});
}),
imei: ctx.imei,
ttl: (_a = payload.ttl) !== null && _a !== void 0 ? _a : 0,
msgType: "1",
totalIds: threadIds.length,
msgInfo: JSON.stringify(msgInfo),
decorLog: JSON.stringify(decorLog),
};
}
else {
params = {
grids: threadIds.map((threadId) => {
var _a;
return ({
clientId,
grid: threadId,
ttl: (_a = payload.ttl) !== null && _a !== void 0 ? _a : 0,
});
}),
ttl: (_b = payload.ttl) !== null && _b !== void 0 ? _b : 0,
msgType: "1",
totalIds: threadIds.length,
msgInfo: JSON.stringify(msgInfo),
decorLog: JSON.stringify(decorLog),
};
}
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL[type], {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
exports.forwardMessageFactory = forwardMessageFactory;
+32
View File
@@ -0,0 +1,32 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const getAliasListFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.alias[0]}/api/alias/list`);
/**
* Get alias list
*
* @param count Page size (default: 100)
* @param page Page number (default: 1)
*
* @throws {ZaloApiError}
*/
return async function getAliasList(count = 100, page = 1) {
const params = {
page,
count,
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.getAliasListFactory = getAliasListFactory;
+47
View File
@@ -0,0 +1,47 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
require('../models/AutoReply.cjs');
require('../models/Board.cjs');
var Enum = require('../models/Enum.cjs');
require('../models/FriendEvent.cjs');
require('../models/Group.cjs');
require('../models/GroupEvent.cjs');
require('../models/Reaction.cjs');
require('../models/Reminder.cjs');
require('../models/ZBusiness.cjs');
const getAllFriendsFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.profile[0]}/api/social/friend/getfriends`);
/**
* Get all friends
*
* @param count Page size (default: 20000)
* @param page Page number (default: 1)
* @param avatarSize Avatar size (default: AvatarSize.Small)
*
* @throws {ZaloApiError}
*/
return async function getAllFriends(count = 20000, page = 1, avatarSize = Enum.AvatarSize.Small) {
const params = {
incInvalid: 1,
page,
count,
avatar_size: avatarSize,
actiontime: 0,
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt message");
const response = await utils.request(utils.makeURL(serviceURL, {
params: encryptedParams,
}), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.getAllFriendsFactory = getAllFriendsFactory;
+15
View File
@@ -0,0 +1,15 @@
'use strict';
var utils = require('../utils.cjs');
const getAllGroupsFactory = utils.apiFactory()((api, _, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group_poll[0]}/api/group/getlg/v4`);
return async function getAllGroups() {
const response = await utils.request(serviceURL, {
method: "GET",
});
return utils.resolve(response);
};
});
exports.getAllGroupsFactory = getAllGroupsFactory;
+28
View File
@@ -0,0 +1,28 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const getArchivedChatListFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.label[0]}/api/archivedchat/list`);
/**
* Get arcnived chat list
*
* @throws {ZaloApiError}
*/
return async function getArchivedChatList() {
const params = {
version: 1,
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.getArchivedChatListFactory = getArchivedChatListFactory;
+26
View File
@@ -0,0 +1,26 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const getAutoDeleteChatFactory = utils.apiFactory()((api, _ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.conversation[0]}/api/conv/autodelete/getConvers`);
/**
* Get auto delete chat
*
* @throws {ZaloApiError}
*
*/
return async function getAutoDeleteChat() {
const params = {};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.getAutoDeleteChatFactory = getAutoDeleteChatFactory;
+29
View File
@@ -0,0 +1,29 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const getAutoReplyListFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.auto_reply[0]}/api/autoreply/list`);
/**
* Get auto reply list
*
* @note this API used for zBusiness
* @throws {ZaloApiError}
*/
return async function getAutoReplyList() {
const params = {
version: 0,
cliLang: ctx.language,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.getAutoReplyListFactory = getAutoReplyListFactory;
+33
View File
@@ -0,0 +1,33 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const getAvatarListFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.profile[0]}/api/social/avatar-list`);
/**
* Get avatar list
*
* @param count The number of avatars to fetch (default: 50)
* @param page The page number to fetch (default: 1)
*
* @throws {ZaloApiError}
*/
return async function getAvatarList(count = 50, page = 1) {
const params = {
page,
albumId: "0",
count,
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.getAvatarListFactory = getAvatarListFactory;
+43
View File
@@ -0,0 +1,43 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
require('../models/AutoReply.cjs');
require('../models/Board.cjs');
var Enum = require('../models/Enum.cjs');
require('../models/FriendEvent.cjs');
require('../models/Group.cjs');
require('../models/GroupEvent.cjs');
require('../models/Reaction.cjs');
require('../models/Reminder.cjs');
require('../models/ZBusiness.cjs');
var utils = require('../utils.cjs');
const getAvatarUrlProfileFactory = utils.apiFactory()((api, _ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.profile[0]}/api/social/profile/avatar-url`);
/**
* Get avatar url profile
*
* @param friendId friend id(s)
* @param avatarSize Avatar size (default: AvatarSize.Large)
*
* @throws {ZaloApiError}
*/
return async function getAvatarUrlProfile(friendIds, avatarSize = Enum.AvatarSize.Large) {
if (!Array.isArray(friendIds))
friendIds = [friendIds];
const params = {
friend_ids: friendIds,
avatar_size: avatarSize,
srcReq: -1,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.getAvatarUrlProfileFactory = getAvatarUrlProfileFactory;
+32
View File
@@ -0,0 +1,32 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const getBizAccountFactory = utils.apiFactory()((api, _ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.profile[0]}/api/social/friend/get-bizacc`);
/**
* Get biz account
*
* @param friendId The friend ID to get biz account
*
* @throws {ZaloApiError}
*/
return async function getBizAccount(friendId) {
const params = {
fid: friendId,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
exports.getBizAccountFactory = getBizAccountFactory;
+37
View File
@@ -0,0 +1,37 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const getCatalogListFactory = utils.apiFactory()((api, _, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.catalog[0]}/api/prodcatalog/catalog/list`);
/**
* Get catalog list?
*
* @param payload payload
*
* @note this API is used for zBusiness
* @throws {ZaloApiError}
*/
return async function getCatalogList(payload) {
var _a, _b, _c;
const params = {
version_list_catalog: 0,
limit: (_a = payload === null || payload === void 0 ? void 0 : payload.limit) !== null && _a !== void 0 ? _a : 20,
last_product_id: (_b = payload === null || payload === void 0 ? void 0 : payload.lastProductId) !== null && _b !== void 0 ? _b : -1,
page: (_c = payload === null || payload === void 0 ? void 0 : payload.page) !== null && _c !== void 0 ? _c : 0,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
exports.getCatalogListFactory = getCatalogListFactory;
+25
View File
@@ -0,0 +1,25 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const getCloseFriendsFactory = utils.apiFactory()((api, _ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.profile[0]}/api/social/friend/getclosedfriends`);
/**
* Get close friends
*
* @throws {ZaloApiError}
*/
return async function getCloseFriends() {
const params = {};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.getCloseFriendsFactory = getCloseFriendsFactory;
+9
View File
@@ -0,0 +1,9 @@
'use strict';
var utils = require('../utils.cjs');
const getContextFactory = utils.apiFactory()((_, ctx) => {
return () => ctx;
});
exports.getContextFactory = getContextFactory;
+14
View File
@@ -0,0 +1,14 @@
'use strict';
var utils = require('../utils.cjs');
const getCookieFactory = utils.apiFactory()((_, ctx) => {
/**
* Get the current cookie string
*/
return function getCookie() {
return ctx.cookie;
};
});
exports.getCookieFactory = getCookieFactory;
+31
View File
@@ -0,0 +1,31 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const getFriendBoardListFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.friend_board[0]}/api/friendboard/list`);
/**
* Get friend board list
*
* @param conversationId conversation id
*
* @throws {ZaloApiError}
*/
return async function getFriendBoardList(conversationId) {
const params = {
conversationId: conversationId,
version: 0,
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.getFriendBoardListFactory = getFriendBoardListFactory;
+40
View File
@@ -0,0 +1,40 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const getFriendOnlinesFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.profile[0]}/api/social/friend/onlines`);
/**
* Get friend onlines?
*
* @throws {ZaloApiError}
*/
return async function getFriendOnlines() {
const params = {
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response, (result) => {
const data = result.data;
if (Array.isArray(data.onlines)) {
for (const online of data.onlines) {
if (typeof online.status === "string") {
const parsed = JSON.parse(online.status);
if (parsed && typeof parsed.status === "string") {
online.status = parsed.status;
}
}
}
}
return data;
});
};
});
exports.getFriendOnlinesFactory = getFriendOnlinesFactory;
+32
View File
@@ -0,0 +1,32 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
exports.FriendRecommendationsType = void 0;
(function (FriendRecommendationsType) {
FriendRecommendationsType[FriendRecommendationsType["RecommendedFriend"] = 1] = "RecommendedFriend";
FriendRecommendationsType[FriendRecommendationsType["ReceivedFriendRequest"] = 2] = "ReceivedFriendRequest";
})(exports.FriendRecommendationsType || (exports.FriendRecommendationsType = {}));
const getFriendRecommendationsFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.friend[0]}/api/friend/recommendsv2/list`);
/**
* Get friend recommendations/received friend requests
*
* @throws {ZaloApiError}
*/
return async function getFriendRecommendations() {
const params = {
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.getFriendRecommendationsFactory = getFriendRecommendationsFactory;
+30
View File
@@ -0,0 +1,30 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const getFriendRequestStatusFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.friend[0]}/api/friend/reqstatus`);
/**
* Get friend request status
*
* @param friendId friend id
*
* @throws {ZaloApiError}
*/
return async function getFriendRequestStatus(friendId) {
const params = {
fid: friendId,
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.getFriendRequestStatusFactory = getFriendRequestStatusFactory;
+30
View File
@@ -0,0 +1,30 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const getFullAvatarFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.profile[0]}/api/social/profile/avatar`);
/**
* Get full avatar
*
* @param friendId friend id
*
* @throws {ZaloApiError}
*/
return async function getFullAvatar(friendId) {
const params = {
fid: friendId,
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.getFullAvatarFactory = getFullAvatarFactory;
+34
View File
@@ -0,0 +1,34 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const getGroupBlockedMemberFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/blockedmems/list`);
/**
* Get group blocked member
*
* @param payload payload
* @param groupId group id
*
* @throws {ZaloApiError}
*/
return async function getGroupBlockedMember(payload, groupId) {
var _a, _b;
const params = {
grid: groupId,
page: (_a = payload.page) !== null && _a !== void 0 ? _a : 1,
count: (_b = payload.count) !== null && _b !== void 0 ? _b : 50,
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.getGroupBlockedMemberFactory = getGroupBlockedMemberFactory;
+50
View File
@@ -0,0 +1,50 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
require('../models/AutoReply.cjs');
require('../models/Board.cjs');
require('../models/Enum.cjs');
require('../models/FriendEvent.cjs');
require('../models/Group.cjs');
require('../models/GroupEvent.cjs');
var Message = require('../models/Message.cjs');
require('../models/Reaction.cjs');
require('../models/Reminder.cjs');
require('../models/ZBusiness.cjs');
const getGroupChatHistoryFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/history`);
/**
* Get group chat history
*
* @param groupId group id
* @param count count of messages to return (default: 50)
*
* @throws {ZaloApiError}
*/
return async function getGroupChatHistory(groupId, count = 50) {
const params = {
grid: groupId,
count: count,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response, (result) => {
let data = result.data;
if (typeof data === "string") {
data = JSON.parse(data);
}
for (let i = 0; i < data.groupMsgs.length; i++) {
data.groupMsgs[i] = new Message.GroupMessage(ctx.uid, data.groupMsgs[i]);
}
return data;
});
};
});
exports.getGroupChatHistoryFactory = getGroupChatHistoryFactory;
+37
View File
@@ -0,0 +1,37 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const getGroupInfoFactory = utils.apiFactory()((api, _, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/getmg-v2`);
/**
* Get group information
*
* @param groupId Group ID or list of group IDs
*
* @throws {ZaloApiError}
*/
return async function getGroupInfo(groupId) {
if (!Array.isArray(groupId))
groupId = [groupId];
const params = {
gridVerMap: JSON.stringify(groupId.reduce((acc, id) => {
acc[id] = 0;
return acc;
}, {})),
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt message");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
exports.getGroupInfoFactory = getGroupInfoFactory;
+43
View File
@@ -0,0 +1,43 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const getGroupInviteBoxInfoFactory = utils.apiFactory()((api, _, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/inv-box/inv-info`);
/**
* Get group invite box info
*
* @param payload - The payload of the request
*
* @throws {ZaloApiError}
*/
return async function getGroupInviteBoxInfo(payload) {
var _a, _b;
const params = {
grId: payload.groupId,
mcount: (_a = payload.mcount) !== null && _a !== void 0 ? _a : 10,
mpage: (_b = payload.mpage) !== null && _b !== void 0 ? _b : 1,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response, (result) => {
const data = result.data;
const topic = data.groupInfo.topic;
if (typeof topic.params == "string") {
const params = JSON.parse(topic.params);
if (typeof params.extra == "string") {
params.extra = JSON.parse(params.extra);
}
topic.params = params;
}
return data;
});
};
});
exports.getGroupInviteBoxInfoFactory = getGroupInviteBoxInfoFactory;
+36
View File
@@ -0,0 +1,36 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const getGroupInviteBoxListFactory = utils.apiFactory()((api, _, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/inv-box/list`);
/**
* Get group invite box list
*
* @param payload - The payload of the request
*
* @throws {ZaloApiError}
*/
return async function getGroupInviteBoxList(payload) {
var _a, _b, _c, _d;
const params = {
mpage: (_a = payload === null || payload === void 0 ? void 0 : payload.mpage) !== null && _a !== void 0 ? _a : 1,
page: (_b = payload === null || payload === void 0 ? void 0 : payload.page) !== null && _b !== void 0 ? _b : 0,
invPerPage: (_c = payload === null || payload === void 0 ? void 0 : payload.invPerPage) !== null && _c !== void 0 ? _c : 12,
mcount: (_d = payload === null || payload === void 0 ? void 0 : payload.mcount) !== null && _d !== void 0 ? _d : 10,
lastGroupId: null, // @TODO: check type
avatar_size: 120,
member_avatar_size: 120,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.getGroupInviteBoxListFactory = getGroupInviteBoxListFactory;
+30
View File
@@ -0,0 +1,30 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const getGroupLinkDetailFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/link/detail`);
/**
* Get group link detail
*
* @param groupId The group id
*
* @throws {ZaloApiError}
*/
return async function getGroupLinkDetail(groupId) {
const params = {
grid: groupId,
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.getGroupLinkDetailFactory = getGroupLinkDetailFactory;
+33
View File
@@ -0,0 +1,33 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const getGroupLinkInfoFactory = utils.apiFactory()((api, _ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/link/ginfo`);
/**
* Get group link info
*
* @param payload - The payload of the request
*
* @throws {ZaloApiError}
*/
return async function getGroupLinkInfo(payload) {
var _a;
const params = {
link: payload.link,
avatar_size: 120,
member_avatar_size: 120,
mpage: (_a = payload.memberPage) !== null && _a !== void 0 ? _a : 1,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.getGroupLinkInfoFactory = getGroupLinkInfoFactory;
+29
View File
@@ -0,0 +1,29 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const getGroupMembersInfoFactory = utils.apiFactory()((api, _, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.profile[0]}/api/social/group/members`);
/**
* Get group information
*
* @param memberId member id or array of member ids
*
* @throws {ZaloApiError}
*/
return async function getGroupMembersInfo(memberId) {
if (!Array.isArray(memberId))
memberId = [memberId];
const params = {
friend_pversion_map: memberId.map((id) => (id.endsWith("_0") ? id : `${id}_0`)),
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt message");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }));
return utils.resolve(response);
};
});
exports.getGroupMembersInfoFactory = getGroupMembersInfoFactory;
+28
View File
@@ -0,0 +1,28 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const getHiddenConversationsFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.conversation[0]}/api/hiddenconvers/get-all`);
/**
* Get hidden conversations
*
* @throws {ZaloApiError}
*
*/
return async function getHiddenConversations() {
const params = {
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.getHiddenConversationsFactory = getHiddenConversationsFactory;
+33
View File
@@ -0,0 +1,33 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const getLabelsFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.label[0]}/api/convlabel/get`);
/**
* Get all labels
*
* @throws {ZaloApiError}
*/
return async function getLabels() {
const params = {
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt message");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }));
return utils.resolve(response, (result) => {
const data = result.data;
const formattedData = {
labelData: JSON.parse(data.labelData),
version: data.version,
lastUpdateTime: data.lastUpdateTime,
};
return formattedData;
});
};
});
exports.getLabelsFactory = getLabelsFactory;
+58
View File
@@ -0,0 +1,58 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
require('../models/AutoReply.cjs');
var Board = require('../models/Board.cjs');
require('../models/Enum.cjs');
require('../models/FriendEvent.cjs');
require('../models/Group.cjs');
require('../models/GroupEvent.cjs');
require('../models/Reaction.cjs');
require('../models/Reminder.cjs');
require('../models/ZBusiness.cjs');
var utils = require('../utils.cjs');
const getListBoardFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group_board[0]}/api/board/list`);
/**
* Get list board items in a group
*
* @param options - The options for the request
* @param groupId - The ID of the group
*
* @throws {ZaloApiError}
*
*/
return async function getListBoard(options, groupId) {
var _a, _b;
const requestParams = {
group_id: groupId,
board_type: 0,
page: (_a = options.page) !== null && _a !== void 0 ? _a : 1,
count: (_b = options.count) !== null && _b !== void 0 ? _b : 20,
last_id: 0,
last_type: 0,
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(requestParams));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response, (result) => {
const data = result.data;
data.items.forEach((item) => {
if (item.boardType != Board.BoardType.Poll) {
const detailData = item.data;
if (typeof detailData.params === "string") {
detailData.params = JSON.parse(detailData.params);
}
}
});
return data;
});
};
});
exports.getListBoardFactory = getListBoardFactory;
+60
View File
@@ -0,0 +1,60 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
require('../models/AutoReply.cjs');
require('../models/Board.cjs');
var Enum = require('../models/Enum.cjs');
require('../models/FriendEvent.cjs');
require('../models/Group.cjs');
require('../models/GroupEvent.cjs');
require('../models/Reaction.cjs');
require('../models/Reminder.cjs');
require('../models/ZBusiness.cjs');
var utils = require('../utils.cjs');
const getListReminderFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = {
[Enum.ThreadType.User]: utils.makeURL(`${api.zpwServiceMap.group_board[0]}/api/board/oneone/list`),
[Enum.ThreadType.Group]: utils.makeURL(`${api.zpwServiceMap.group_board[0]}/api/board/listReminder`),
};
/**
* Get list reminder
*
* @param options - The options for the request
* @param threadId - The ID of the thread
* @param type - The type of the thread (User or Group)
*
* @throws {ZaloApiError}
*/
return async function getListReminder(options, threadId, type = Enum.ThreadType.User) {
var _a, _b, _c, _d;
const requestParams = Object.assign({ objectData: JSON.stringify(type === Enum.ThreadType.User
? {
uid: threadId,
board_type: 1,
page: (_a = options.page) !== null && _a !== void 0 ? _a : 1,
count: (_b = options.count) !== null && _b !== void 0 ? _b : 20,
last_id: 0,
last_type: 0,
}
: {
group_id: threadId,
board_type: 1,
page: (_c = options.page) !== null && _c !== void 0 ? _c : 1,
count: (_d = options.count) !== null && _d !== void 0 ? _d : 20,
last_id: 0,
last_type: 0,
}) }, (type === Enum.ThreadType.Group && { imei: ctx.imei }));
const encryptedParams = utils.encodeAES(JSON.stringify(requestParams));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL[type], { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response, (result) => {
return JSON.parse(result.data);
});
};
});
exports.getListReminderFactory = getListReminderFactory;
+52
View File
@@ -0,0 +1,52 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
require('../models/AutoReply.cjs');
require('../models/Board.cjs');
var Enum = require('../models/Enum.cjs');
require('../models/FriendEvent.cjs');
require('../models/Group.cjs');
require('../models/GroupEvent.cjs');
require('../models/Reaction.cjs');
require('../models/Reminder.cjs');
require('../models/ZBusiness.cjs');
const getMultiUsersByPhonesFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.friend[0]}/api/friend/profile/multiget`);
/**
* Get multiple user(s) by their phone numbers.
*
* @param phoneNumbers Phone number(s)
* @param avatarSize Avatar size (default: AvatarSize.Large)
*
* @throws {ZaloApiError}
*/
return async function getMultiUsersByPhones(phoneNumbers, avatarSize = Enum.AvatarSize.Large) {
if (!phoneNumbers)
throw new ZaloApiError.ZaloApiError("Missing phoneNumbers");
if (!Array.isArray(phoneNumbers))
phoneNumbers = [phoneNumbers];
phoneNumbers = phoneNumbers.map((phone) => {
if (phone.startsWith("0")) {
if (ctx.language == "vi")
phone = "84" + phone.slice(1);
}
return phone;
});
const params = {
phones: phoneNumbers,
avatar_size: avatarSize,
language: ctx.language,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.getMultiUsersByPhonesFactory = getMultiUsersByPhonesFactory;
+27
View File
@@ -0,0 +1,27 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const getMuteFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.profile[0]}/api/social/profile/getmute`);
/**
* Get mute
*
* @throws {ZaloApiError}
*/
return async function getMute() {
const params = {
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.getMuteFactory = getMuteFactory;
+9
View File
@@ -0,0 +1,9 @@
'use strict';
var utils = require('../utils.cjs');
const getOwnIdFactory = utils.apiFactory()((_, ctx) => {
return () => ctx.uid;
});
exports.getOwnIdFactory = getOwnIdFactory;
+32
View File
@@ -0,0 +1,32 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const getPendingGroupMembersFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/pending-mems/list`);
/**
* Get pending group members
*
* @param groupId - The id of the group to get the pending members
*
* @note Only the group leader and deputy group leader can view
*
* @throws {ZaloApiError}
*/
return async function getPendingGroupMembers(groupId) {
const params = {
grid: groupId,
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.getPendingGroupMembersFactory = getPendingGroupMembersFactory;
+27
View File
@@ -0,0 +1,27 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const getPinConversationsFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.conversation[0]}/api/pinconvers/list`);
/**
* Get pin conversations
*
* @throws {ZaloApiError}
*/
return async function getPinConversations() {
const params = {
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.getPinConversationsFactory = getPinConversationsFactory;
+35
View File
@@ -0,0 +1,35 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const getPollDetailFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/poll/detail`);
/**
* Get poll detail
*
* @param pollId Poll ID
*
* @throws {ZaloApiError}
*/
return async function getPollDetail(pollId) {
if (!pollId)
throw new ZaloApiError.ZaloApiError("Missing poll id");
const params = {
poll_id: pollId,
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt message");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
exports.getPollDetailFactory = getPollDetailFactory;
+38
View File
@@ -0,0 +1,38 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const getProductCatalogListFactory = utils.apiFactory()((api, _, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.catalog[0]}/api/prodcatalog/product/list`);
/**
* Get product catalog list?
*
* @param payload payload
*
* @note this API is used for zBusiness
* @throws {ZaloApiError}
*/
return async function getProductCatalogList(payload) {
var _a, _b, _c, _d;
const params = {
catalog_id: payload.catalogId,
limit: (_a = payload.limit) !== null && _a !== void 0 ? _a : 100,
version_catalog: (_b = payload.versionCatalog) !== null && _b !== void 0 ? _b : 0,
last_product_id: (_c = payload.lastProductId) !== null && _c !== void 0 ? _c : -1,
page: (_d = payload.page) !== null && _d !== void 0 ? _d : 0,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
exports.getProductCatalogListFactory = getProductCatalogListFactory;
+34
View File
@@ -0,0 +1,34 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const getQRFactory = utils.apiFactory()((api, _, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.friend[0]}/api/friend/mget-qr`);
/**
* Get QR code for users
*
* @param userId User ID or list of user IDs
*
* @throws {ZaloApiError}
*/
return async function getQR(userId) {
if (typeof userId == "string")
userId = [userId];
const params = {
fids: userId,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
exports.getQRFactory = getQRFactory;
+29
View File
@@ -0,0 +1,29 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const getQuickMessageListFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.quick_message[0]}/api/quickmessage/list`);
/**
* Get quick message list
*
* @throws {ZaloApiError}
*/
return async function getQuickMessageList() {
const params = {
version: 0,
lang: 0,
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.getQuickMessageListFactory = getQuickMessageListFactory;
+35
View File
@@ -0,0 +1,35 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const getRelatedFriendGroupFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.friend[0]}/api/friend/group/related`);
/**
* Get related friend group
*
* @param friendId friend ids
*
* @note this API is used for zBusiness
* @throws {ZaloApiError}
*/
return async function getRelatedFriendGroup(friendId) {
const friendIds = Array.isArray(friendId) ? friendId : [friendId];
const params = {
friend_ids: JSON.stringify(friendIds),
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
exports.getRelatedFriendGroupFactory = getRelatedFriendGroupFactory;
+30
View File
@@ -0,0 +1,30 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const getReminderFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group_board[0]}/api/board/topic/getReminder`);
/**
* Get reminder details from a group
*
* @param reminderId Reminder ID
*
* @throws {ZaloApiError}
*/
return async function getReminder(reminderId) {
const params = {
eventId: reminderId,
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.getReminderFactory = getReminderFactory;
+29
View File
@@ -0,0 +1,29 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const getReminderResponsesFactory = utils.apiFactory()((api, _ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group_board[0]}/api/board/topic/listResponseEvent`);
/**
* Get reminder responses
*
* @param reminderId reminder id
*
* @throws {ZaloApiError}
*/
return async function getReminderResponses(reminderId) {
const params = {
eventId: reminderId,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.getReminderResponsesFactory = getReminderResponsesFactory;
+29
View File
@@ -0,0 +1,29 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const getSentFriendRequestFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.friend[0]}/api/friend/requested/list`);
/**
* Get friend requested
*
* @note Zalo might throw an error with code 112 if you have no friend requests.
*
* @throws {ZaloApiError}
*/
return async function getSentFriendRequest() {
const params = {
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.getSentFriendRequestFactory = getSentFriendRequestFactory;
+25
View File
@@ -0,0 +1,25 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const getSettingsFactory = utils.apiFactory()((_api, _ctx, utils) => {
const serviceURL = utils.makeURL(`https://wpa.chat.zalo.me/api/setting/me`);
/**
* Get my account settings
*
* @throws {ZaloApiError}
*/
return async function getSettings() {
const params = {};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.getSettingsFactory = getSettingsFactory;
+29
View File
@@ -0,0 +1,29 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const getStickerCategoryDetailFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.sticker[0]}/api/message/sticker/category/sticker_detail`);
/**
* Get sticker category detail
*
* @param cateId Sticker category ID
*
* @throws {ZaloApiError}
*/
return async function getStickerCategoryDetail(cateId) {
const params = {
cid: cateId,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.getStickerCategoryDetailFactory = getStickerCategoryDetailFactory;
+45
View File
@@ -0,0 +1,45 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const getStickersFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.sticker}/api/message/sticker`);
/**
* Get stickers by keyword
*
* @param keyword Keyword to search for
* @returns Sticker IDs
*
* @throws {ZaloApiError}
*/
return async function getStickers(keyword) {
if (!keyword)
throw new ZaloApiError.ZaloApiError("Missing keyword");
const params = {
keyword: keyword,
gif: 1,
guggy: 0,
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt message");
const finalServiceUrl = new URL(serviceURL);
finalServiceUrl.pathname = finalServiceUrl.pathname + "/suggest/stickers";
const response = await utils.request(utils.makeURL(finalServiceUrl.toString(), {
params: encryptedParams,
}));
return utils.resolve(response, (result) => {
const suggestions = result.data;
const stickerIds = [];
// @TODO: Implement these
// suggestions.sugg_guggy, suggestions.sugg_gif
if (suggestions.sugg_sticker)
suggestions.sugg_sticker.forEach((sticker) => stickerIds.push(sticker.sticker_id));
return stickerIds;
});
};
});
exports.getStickersFactory = getStickersFactory;
+45
View File
@@ -0,0 +1,45 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const getStickersDetailFactory = utils.apiFactory()((api, ctx, utils$1) => {
const serviceURL = utils$1.makeURL(`${api.zpwServiceMap.sticker}/api/message/sticker/sticker_detail`);
/**
* Get stickers detail by sticker IDs
*
* @param stickerIds Sticker IDs to search for
*
* @throws {ZaloApiError}
*/
return async function getStickersDetail(stickerIds) {
if (!stickerIds)
throw new ZaloApiError.ZaloApiError("Missing sticker id");
if (!Array.isArray(stickerIds))
stickerIds = [stickerIds];
if (stickerIds.length == 0)
throw new ZaloApiError.ZaloApiError("Missing sticker id");
const stickers = [];
const tasks = stickerIds.map((stickerId) => getStickerDetail(stickerId));
const tasksResult = await Promise.allSettled(tasks);
tasksResult.forEach((result) => {
if (result.status === "fulfilled")
stickers.push(result.value);
});
return stickers;
};
async function getStickerDetail(stickerId) {
const params = {
sid: stickerId,
};
const encryptedParams = utils$1.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt message");
const response = await utils$1.request(utils$1.makeURL(serviceURL, {
params: encryptedParams,
}));
return utils.resolveResponse(ctx, response);
}
});
exports.getStickersDetailFactory = getStickersDetailFactory;
+35
View File
@@ -0,0 +1,35 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const getUnreadMarkFactory = utils.apiFactory()((api, _, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.conversation[0]}/api/conv/getUnreadMark`);
/**
* Get unread mark
*
* @throws {ZaloApiError}
*
*/
return async function getUnreadMark() {
const params = {};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response, (result) => {
const data = result.data;
if (typeof data.data === "string") {
return {
data: JSON.parse(data.data),
status: data.status,
};
}
return data;
});
};
});
exports.getUnreadMarkFactory = getUnreadMarkFactory;
+57
View File
@@ -0,0 +1,57 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
require('../models/AutoReply.cjs');
require('../models/Board.cjs');
var Enum = require('../models/Enum.cjs');
require('../models/FriendEvent.cjs');
require('../models/Group.cjs');
require('../models/GroupEvent.cjs');
require('../models/Reaction.cjs');
require('../models/Reminder.cjs');
require('../models/ZBusiness.cjs');
const getUserInfoFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.profile[0]}/api/social/friend/getprofiles/v2`);
/**
* Get user info using user id
*
* @param userId User id(s)
* @param avatarSize Avatar size (default: AvatarSize.Small)
*
* @throws {ZaloApiError}
*/
return async function getUserInfo(userId, avatarSize = Enum.AvatarSize.Small) {
if (!userId)
throw new ZaloApiError.ZaloApiError("Missing user id");
if (!Array.isArray(userId))
userId = [userId];
userId = userId.map((id) => {
if (id.split("_").length > 1) {
return id;
}
return `${id}_0`;
});
const params = {
phonebook_version: ctx.extraVer.phonebook,
friend_pversion_map: userId,
avatar_size: avatarSize,
language: ctx.language,
show_online_status: 1,
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
exports.getUserInfoFactory = getUserInfoFactory;
+35
View File
@@ -0,0 +1,35 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const inviteUserToGroupsFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/invite/multi`);
/**
* Invite user to group
*
* @param groupId group ID(s)
* @param memberId member ID
*
* @throws {ZaloApiError}
*
*/
return async function inviteUserToGroups(userId, groupId) {
const params = {
grids: Array.isArray(groupId) ? groupId : [groupId],
member: userId,
memberType: -1,
srcInteraction: 2,
clientLang: ctx.language,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.inviteUserToGroupsFactory = inviteUserToGroupsFactory;
+30
View File
@@ -0,0 +1,30 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const joinGroupInviteBoxFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/inv-box/join`);
/**
* Join group invite box
*
* @param groupId - The group id
*
* @throws {ZaloApiError}
*/
return async function joinGroupInviteBox(groupId) {
const params = {
grid: groupId,
lang: ctx.language,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.joinGroupInviteBoxFactory = joinGroupInviteBoxFactory;
+32
View File
@@ -0,0 +1,32 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const joinGroupLinkFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/link/join`);
/**
* Join group via invite link
*
* @note Zalo might throw an error with code 240 if the group enabled membership approval, 178 if you are already a member.
*
* @param link - The link join group
*
* @throws {ZaloApiError}
*/
return async function joinGroupLink(link) {
const params = {
link: link,
clientLang: ctx.language,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.joinGroupLinkFactory = joinGroupLinkFactory;
+27
View File
@@ -0,0 +1,27 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const keepAliveFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.chat[0]}/keepalive`);
/**
* Keep Alive?
*
* @throws {ZaloApiError}
*/
return async function keepAlive() {
const params = {
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response, undefined, false);
};
});
exports.keepAliveFactory = keepAliveFactory;
+31
View File
@@ -0,0 +1,31 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const lastOnlineFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.profile[0]}/api/social/profile/lastOnline`);
/**
* Get last online
*
* @param uid User ID
*
* @throws {ZaloApiError}
*/
return async function lastOnline(uid) {
const params = {
uid: uid,
conv_type: 1,
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.lastOnlineFactory = lastOnlineFactory;
+38
View File
@@ -0,0 +1,38 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const leaveGroupFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/leave`);
/**
* Leave group
*
* @param groupId - groupId to leave
* @param silent - Turn on/off silent leave group
*
* @note Zalo might throw an error with code 166 if you are not a member of the group
*
* @throws {ZaloApiError}
*/
return async function leaveGroup(groupId, silent = false) {
const requestParams = {
grids: [groupId], // API only supports leaving one group at a time
imei: ctx.imei,
silent: silent ? 1 : 0,
language: ctx.language,
};
const encryptedParams = utils.encodeAES(JSON.stringify(requestParams));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
exports.leaveGroupFactory = leaveGroupFactory;
+439
View File
@@ -0,0 +1,439 @@
'use strict';
var EventEmitter = require('events');
var WebSocket = require('ws');
var FriendEvent = require('../models/FriendEvent.cjs');
var GroupEvent = require('../models/GroupEvent.cjs');
require('../models/AutoReply.cjs');
require('../models/Board.cjs');
var DeliveredMessage = require('../models/DeliveredMessage.cjs');
var Enum = require('../models/Enum.cjs');
require('../models/Group.cjs');
var Message = require('../models/Message.cjs');
var Reaction = require('../models/Reaction.cjs');
require('../models/Reminder.cjs');
var SeenMessage = require('../models/SeenMessage.cjs');
var Typing = require('../models/Typing.cjs');
var Undo = require('../models/Undo.cjs');
require('../models/ZBusiness.cjs');
var utils = require('../utils.cjs');
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
exports.CloseReason = void 0;
(function (CloseReason) {
CloseReason[CloseReason["ManualClosure"] = 1000] = "ManualClosure";
CloseReason[CloseReason["AbnormalClosure"] = 1006] = "AbnormalClosure";
CloseReason[CloseReason["DuplicateConnection"] = 3000] = "DuplicateConnection";
CloseReason[CloseReason["KickConnection"] = 3003] = "KickConnection";
})(exports.CloseReason || (exports.CloseReason = {}));
class Listener extends EventEmitter {
constructor(ctx, urls) {
super();
this.ctx = ctx;
this.urls = urls;
this.id = 0;
if (!ctx.cookie)
throw new ZaloApiError.ZaloApiError("Cookie is not available");
if (!ctx.userAgent)
throw new ZaloApiError.ZaloApiError("User agent is not available");
this.wsURL = utils.makeURL(this.ctx, this.urls[0], {
t: Date.now(),
});
this.retryCount = {};
this.rotateCount = 0;
for (const retry in ctx.settings.features.socket.retries) {
const { times, max } = ctx.settings.features.socket.retries[retry];
this.retryCount[retry] = {
count: 0,
max: max || 0,
times: typeof times === "number" ? [times] : times,
};
}
this.cookie = ctx.cookie.getCookieStringSync("https://chat.zalo.me");
this.userAgent = ctx.userAgent;
this.selfListen = ctx.options.selfListen;
this.ws = null;
this.onConnectedCallback = () => { };
this.onClosedCallback = () => { };
this.onErrorCallback = () => { };
this.onMessageCallback = () => { };
}
/**
* @deprecated Use `on` method instead
*/
onConnected(cb) {
this.onConnectedCallback = cb;
}
/**
* @deprecated Use `on` method instead
*/
onClosed(cb) {
this.onClosedCallback = cb;
}
/**
* @deprecated Use `on` method instead
*/
onError(cb) {
this.onErrorCallback = cb;
}
/**
* @deprecated Use `on` method instead
*/
onMessage(cb) {
this.onMessageCallback = cb;
}
canRetry(code) {
if (!this.ctx.settings.features.socket.close_and_retry_codes.includes(code))
return false;
if (this.retryCount[code.toString()].count >= this.retryCount[code.toString()].max)
return false;
this.retryCount[code.toString()].count++;
const { count, max, times } = this.retryCount[code.toString()];
const retryTime = count - 1 < times.length ? times[count - 1] : times[times.length - 1];
utils.logger(this.ctx).verbose(`Retry for code ${code} in ${retryTime}ms (${count}/${max})`);
return retryTime;
}
shouldRotate(code) {
if (!this.ctx.settings.features.socket.rotate_error_codes.includes(code))
return false;
if (this.rotateCount >= this.urls.length - 1)
return false;
return true;
}
rotateEndpoint() {
this.rotateCount++;
this.wsURL = utils.makeURL(this.ctx, this.urls[this.rotateCount], {
t: Date.now(),
});
utils.logger(this.ctx).verbose(`Rotating endpoint to ${this.wsURL}`);
}
start({ retryOnClose = false } = {}) {
if (this.ws)
throw new ZaloApiError.ZaloApiError("Already started");
const ws = new WebSocket(this.wsURL, {
headers: {
"accept-encoding": "gzip, deflate, br, zstd",
"accept-language": "en-US,en;q=0.9",
"cache-control": "no-cache",
connection: "Upgrade",
host: new URL(this.wsURL).host,
origin: "https://chat.zalo.me",
prgama: "no-cache",
"sec-websocket-extensions": "permessage-deflate; client_max_window_bits",
"sec-websocket-version": "13",
upgrade: "websocket",
"user-agent": this.userAgent,
cookie: this.cookie,
},
agent: this.ctx.options.agent
});
this.ws = ws;
ws.onopen = () => {
this.onConnectedCallback();
this.emit("connected");
};
ws.onclose = (event) => {
this.reset();
this.emit("disconnected", event.code, event.reason);
const retry = retryOnClose && this.canRetry(event.code);
if (retry && retryOnClose) {
const shouldRotate = this.shouldRotate(event.code);
if (shouldRotate) {
this.rotateEndpoint();
}
setTimeout(() => {
this.start({ retryOnClose: true });
}, retry);
}
else {
this.onClosedCallback(event.code, event.reason);
this.emit("closed", event.code, event.reason);
}
};
ws.onerror = (event) => {
this.onErrorCallback(event);
this.emit("error", event);
};
ws.onmessage = async (event) => {
const { data } = event;
if (!(data instanceof Buffer))
return;
const encodedHeader = data.subarray(0, 4);
const [version, cmd, subCmd] = getHeader(encodedHeader);
try {
const dataToDecode = data.subarray(4);
const decodedData = new TextDecoder("utf-8").decode(dataToDecode);
if (decodedData.length == 0)
return;
const parsed = JSON.parse(decodedData);
if (version == 1 && cmd == 1 && subCmd == 1 && utils.hasOwn(parsed, "key")) {
this.cipherKey = parsed.key;
this.emit("cipher_key", parsed.key);
if (this.pingInterval)
clearInterval(this.pingInterval);
const ping = () => {
const payload = {
version: 1,
cmd: 2,
subCmd: 1,
data: { eventId: Date.now() },
};
this.sendWs(payload, false);
};
this.pingInterval = setInterval(() => {
ping();
}, this.ctx.settings.features.socket.ping_interval);
}
if (version == 1 && cmd == 501 && subCmd == 0) {
const parsedData = (await utils.decodeEventData(parsed, this.cipherKey)).data;
const { msgs } = parsedData;
for (const msg of msgs) {
if (typeof msg.content == "object" && utils.hasOwn(msg.content, "deleteMsg")) {
const undoObject = new Undo.Undo(this.ctx.uid, msg, false);
if (undoObject.isSelf && !this.selfListen)
continue;
this.emit("undo", undoObject);
}
else {
const messageObject = new Message.UserMessage(this.ctx.uid, msg);
if (messageObject.isSelf && !this.selfListen)
continue;
this.onMessageCallback(messageObject);
this.emit("message", messageObject);
}
}
}
if (version == 1 && cmd == 521 && subCmd == 0) {
const parsedData = (await utils.decodeEventData(parsed, this.cipherKey)).data;
const { groupMsgs } = parsedData;
for (const msg of groupMsgs) {
if (typeof msg.content == "object" && utils.hasOwn(msg.content, "deleteMsg")) {
const undoObject = new Undo.Undo(this.ctx.uid, msg, true);
if (undoObject.isSelf && !this.selfListen)
continue;
this.emit("undo", undoObject);
}
else {
const messageObject = new Message.GroupMessage(this.ctx.uid, msg);
if (messageObject.isSelf && !this.selfListen)
continue;
this.onMessageCallback(messageObject);
this.emit("message", messageObject);
}
}
}
if (version == 1 && cmd == 601 && subCmd == 0) {
const parsedData = (await utils.decodeEventData(parsed, this.cipherKey)).data;
const { controls } = parsedData;
for (const control of controls) {
if (control.content.act_type == "file_done") {
const data = {
fileUrl: control.content.data.url,
fileId: control.content.fileId,
};
const uploadCallback = this.ctx.uploadCallbacks.get(String(control.content.fileId));
if (uploadCallback)
uploadCallback(data);
this.ctx.uploadCallbacks.delete(String(control.content.fileId));
this.emit("upload_attachment", data);
}
else if (control.content.act_type == "group") {
// 31/08/2024
// for some reason, Zalo send both join and join_reject event when admin approve join requests
// Zalo itself doesn't seem to handle this properly either, so we gonna ignore the join_reject event
if (control.content.act == "join_reject")
continue;
const groupEventData = typeof control.content.data == "string"
? JSON.parse(control.content.data)
: control.content.data;
const groupEvent = GroupEvent.initializeGroupEvent(this.ctx.uid, groupEventData, utils.getGroupEventType(control.content.act), control.content.act);
if (groupEvent.isSelf && !this.selfListen)
continue;
this.emit("group_event", groupEvent);
}
else if (control.content.act_type == "fr") {
// 28/02/2025
// Zalo send both req and req_v2 event when user send friend request
// Zalo itself doesn't seem to handle this properly either, so we gonna ignore the req event
if (control.content.act == "req")
continue;
const friendEventData = typeof control.content.data == "string"
? JSON.parse(control.content.data)
: control.content.data;
// Handles the case when act is "pin_create" and params is a string
if (typeof friendEventData == "object" &&
"topic" in friendEventData &&
typeof friendEventData.topic == "object" &&
"params" in friendEventData.topic) {
friendEventData.topic.params = JSON.parse(`${friendEventData.topic.params}`);
}
const friendEvent = FriendEvent.initializeFriendEvent(this.ctx.uid, typeof friendEventData == "number" ? control.content.data : friendEventData, utils.getFriendEventType(control.content.act));
if (friendEvent.isSelf && !this.selfListen)
continue;
this.emit("friend_event", friendEvent);
}
}
}
if (cmd == 612) {
const parsedData = (await utils.decodeEventData(parsed, this.cipherKey)).data;
const { reacts, reactGroups } = parsedData;
for (const react of reacts) {
react.content = JSON.parse(react.content);
const reactionObject = new Reaction.Reaction(this.ctx.uid, react, false);
if (reactionObject.isSelf && !this.selfListen)
continue;
this.emit("reaction", reactionObject);
}
for (const reactGroup of reactGroups) {
reactGroup.content = JSON.parse(reactGroup.content);
const reactionObject = new Reaction.Reaction(this.ctx.uid, reactGroup, true);
if (reactionObject.isSelf && !this.selfListen)
continue;
this.emit("reaction", reactionObject);
}
}
if (cmd == 610 || cmd == 611) {
const parsedData = (await utils.decodeEventData(parsed, this.cipherKey)).data;
const isGroup = cmd == 611;
const reacts = parsedData[isGroup ? "reactGroups" : "reacts"];
const reactionObjects = reacts.map((react) => new Reaction.Reaction(this.ctx.uid, react, isGroup));
this.emit("old_reactions", reactionObjects, isGroup);
}
if (cmd == 510 && subCmd == 1) {
const parsedData = (await utils.decodeEventData(parsed, this.cipherKey)).data;
const msgs = parsedData.msgs;
const responseMsgs = msgs.map((msg) => new Message.UserMessage(this.ctx.uid, msg));
this.emit("old_messages", responseMsgs, Enum.ThreadType.User);
}
if (cmd == 511 && subCmd == 1) {
const parsedData = (await utils.decodeEventData(parsed, this.cipherKey)).data;
const groupMsgs = parsedData.groupMsgs;
const responseMsgs = groupMsgs.map((msg) => new Message.GroupMessage(this.ctx.uid, msg));
this.emit("old_messages", responseMsgs, Enum.ThreadType.Group);
}
if (cmd == 602 && subCmd == 0) {
const parsedData = (await utils.decodeEventData(parsed, this.cipherKey)).data;
const { actions } = parsedData;
for (const action of actions) {
if (action.act_type == "typing") {
const data = JSON.parse(`{${action.data}}`);
if (action.act == "typing") {
const typingObject = new Typing.UserTyping(data);
this.emit("typing", typingObject);
}
else if (action.act == "gtyping") {
// 26/02/2025
// For a group with only two people, Zalo doesn't send a typing event.
const typingObject = new Typing.GroupTyping(data);
this.emit("typing", typingObject);
}
}
}
}
if (cmd == 502 && subCmd == 0) {
const parsedData = (await utils.decodeEventData(parsed, this.cipherKey)).data;
const { delivereds: deliveredMsgs, seens: seenMsgs } = parsedData;
if (Array.isArray(deliveredMsgs) && deliveredMsgs.length > 0) {
const deliveredObjects = deliveredMsgs.map((delivered) => new DeliveredMessage.UserDeliveredMessage(delivered));
this.emit("delivered_messages", deliveredObjects);
}
if (Array.isArray(seenMsgs) && seenMsgs.length > 0) {
const seenObjects = seenMsgs.map((seen) => new SeenMessage.UserSeenMessage(seen));
this.emit("seen_messages", seenObjects);
}
}
if (cmd == 522 && subCmd == 0) {
const parsedData = (await utils.decodeEventData(parsed, this.cipherKey)).data;
const { delivereds: deliveredMsgs, groupSeens: groupSeenMsgs } = parsedData;
if (Array.isArray(deliveredMsgs) && deliveredMsgs.length > 0) {
let deliveredObjects = deliveredMsgs.map((delivered) => new DeliveredMessage.GroupDeliveredMessage(this.ctx.uid, delivered));
if (!this.selfListen)
deliveredObjects = deliveredObjects.filter((delivered) => !delivered.isSelf);
this.emit("delivered_messages", deliveredObjects);
}
if (Array.isArray(groupSeenMsgs) && groupSeenMsgs.length > 0) {
let seenObjects = groupSeenMsgs.map((seen) => new SeenMessage.GroupSeenMessage(this.ctx.uid, seen));
if (!this.selfListen)
seenObjects = seenObjects.filter((seen) => !seen.isSelf);
this.emit("seen_messages", seenObjects);
}
}
if (version == 1 && cmd == 3000 && subCmd == 0) {
utils.logger(this.ctx).error();
utils.logger(this.ctx).error("Another connection is opened, closing this one");
utils.logger(this.ctx).error();
if (ws.readyState !== WebSocket.CLOSED)
ws.close(exports.CloseReason.DuplicateConnection);
}
}
catch (error) {
this.onErrorCallback(error);
this.emit("error", error);
}
};
}
stop() {
if (this.ws) {
this.ws.close(exports.CloseReason.ManualClosure);
this.reset();
}
}
sendWs(payload, requireId = true) {
if (this.ws) {
if (requireId)
payload.data["req_id"] = `req_${this.id++}`;
const encodedData = new TextEncoder().encode(JSON.stringify(payload.data));
const dataLength = encodedData.length;
const data = new DataView(Buffer.alloc(4 + dataLength).buffer);
data.setUint8(0, payload.version);
data.setInt32(1, payload.cmd, true);
data.setInt8(3, payload.subCmd);
encodedData.forEach((e, i) => {
data.setUint8(4 + i, e);
});
this.ws.send(data);
}
}
/**
* Request old messages
*
* @param lastMsgId
*/
requestOldMessages(threadType, lastMsgId = null) {
const payload = {
version: 1,
cmd: threadType === Enum.ThreadType.User ? 510 : 511,
subCmd: 1,
data: { first: true, lastId: lastMsgId, preIds: [] },
};
this.sendWs(payload);
}
/**
* Request old messages
*
* @param lastMsgId
*/
requestOldReactions(threadType, lastMsgId = null) {
const payload = {
version: 1,
cmd: threadType === Enum.ThreadType.User ? 610 : 611,
subCmd: 1,
data: { first: true, lastId: lastMsgId, preIds: [] },
};
this.sendWs(payload);
}
reset() {
this.ws = null;
this.cipherKey = undefined;
if (this.pingInterval)
clearInterval(this.pingInterval);
}
}
function getHeader(buffer) {
if (buffer.byteLength < 4) {
throw new ZaloApiError.ZaloApiError("Invalid header");
}
return [buffer[0], buffer.readUInt16LE(1), buffer[3]];
}
exports.Listener = Listener;
+33
View File
@@ -0,0 +1,33 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const lockPollFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/poll/end`);
/**
* Lock a poll, preventing further votes.
*
* @param pollId Poll id to lock
*
* @throws {ZaloApiError}
*/
return async function lockPoll(pollId) {
const params = {
poll_id: pollId,
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
exports.lockPollFactory = lockPollFactory;
+102
View File
@@ -0,0 +1,102 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
async function login(ctx, encryptParams) {
const encryptedParams = await getEncryptParam(ctx, encryptParams, "getlogininfo");
try {
const response = await utils.request(ctx, utils.makeURL(ctx, "https://wpa.chat.zalo.me/api/login/getLoginInfo", Object.assign(Object.assign({}, encryptedParams.params), { nretry: 0 })));
if (!response.ok)
throw new ZaloApiError.ZaloApiError("Failed to fetch login info: " + response.statusText);
const data = await response.json();
if (encryptedParams.enk) {
const decryptedData = utils.decryptResp(encryptedParams.enk, data.data);
return decryptedData != null && typeof decryptedData != "string" ? decryptedData : null;
}
return null;
}
catch (error) {
utils.logger(ctx).error("Login failed:", error);
throw error;
}
}
async function getServerInfo(ctx, encryptParams) {
const encryptedParams = await getEncryptParam(ctx, encryptParams, "getserverinfo");
if (!encryptedParams.params.signkey || typeof encryptedParams.params.signkey !== "string")
throw new ZaloApiError.ZaloApiError("Missing signkey");
const response = await utils.request(ctx, utils.makeURL(ctx, "https://wpa.chat.zalo.me/api/login/getServerInfo", {
imei: ctx.imei,
type: ctx.API_TYPE,
client_version: ctx.API_VERSION,
computer_name: "Web",
signkey: encryptedParams.params.signkey,
}, false));
if (!response.ok)
throw new ZaloApiError.ZaloApiError("Failed to fetch server info: " + response.statusText);
const data = await response.json();
if (data.data == null)
throw new ZaloApiError.ZaloApiError("Failed to fetch server info: " + data.error_message);
return data.data;
}
async function getEncryptParam(ctx, encryptParams, type) {
const params = {};
const data = {
computer_name: "Web",
imei: ctx.imei,
language: ctx.language,
ts: Date.now(),
};
const encryptedData = await _encryptParam(ctx, data, encryptParams);
if (encryptedData == null)
Object.assign(params, data);
else {
const { encrypted_params, encrypted_data } = encryptedData;
Object.assign(params, encrypted_params);
params.params = encrypted_data;
}
params.type = ctx.API_TYPE;
params.client_version = ctx.API_VERSION;
params.signkey =
type == "getserverinfo"
? utils.getSignKey(type, {
imei: ctx.imei,
type: ctx.API_TYPE,
client_version: ctx.API_VERSION,
computer_name: "Web",
})
: utils.getSignKey(type, params);
return {
params,
enk: encryptedData ? encryptedData.enk : null,
};
}
async function _encryptParam(ctx, data, encryptParams) {
if (encryptParams) {
const encryptor = new utils.ParamsEncryptor({
type: ctx.API_TYPE,
imei: data.imei,
firstLaunchTime: Date.now(),
});
try {
const stringifiedData = JSON.stringify(data);
const encryptedKey = encryptor.getEncryptKey();
const encodedData = utils.ParamsEncryptor.encodeAES(encryptedKey, stringifiedData, "base64", false);
const params = encryptor.getParams();
return params
? {
encrypted_data: encodedData,
encrypted_params: params,
enk: encryptedKey,
}
: null;
}
catch (error) {
throw new ZaloApiError.ZaloApiError("Failed to encrypt params: " + error);
}
}
return null;
}
exports.getServerInfo = getServerInfo;
exports.login = login;
+370
View File
@@ -0,0 +1,370 @@
'use strict';
var toughCookie = require('tough-cookie');
var fs = require('node:fs/promises');
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
var ZaloApiLoginQRAborted = require('../Errors/ZaloApiLoginQRAborted.cjs');
var ZaloApiLoginQRDeclined = require('../Errors/ZaloApiLoginQRDeclined.cjs');
exports.LoginQRCallbackEventType = void 0;
(function (LoginQRCallbackEventType) {
LoginQRCallbackEventType[LoginQRCallbackEventType["QRCodeGenerated"] = 0] = "QRCodeGenerated";
LoginQRCallbackEventType[LoginQRCallbackEventType["QRCodeExpired"] = 1] = "QRCodeExpired";
LoginQRCallbackEventType[LoginQRCallbackEventType["QRCodeScanned"] = 2] = "QRCodeScanned";
LoginQRCallbackEventType[LoginQRCallbackEventType["QRCodeDeclined"] = 3] = "QRCodeDeclined";
LoginQRCallbackEventType[LoginQRCallbackEventType["GotLoginInfo"] = 4] = "GotLoginInfo";
})(exports.LoginQRCallbackEventType || (exports.LoginQRCallbackEventType = {}));
async function loadLoginPage(ctx) {
const response = await utils.request(ctx, "https://id.zalo.me/account?continue=https%3A%2F%2Fchat.zalo.me%2F", {
headers: {
accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
"accept-language": "vi-VN,vi;q=0.9,fr-FR;q=0.8,fr;q=0.7,en-US;q=0.6,en;q=0.5",
"cache-control": "max-age=0",
priority: "u=0, i",
"sec-ch-ua": '"Chromium";v="130", "Google Chrome";v="130", "Not?A_Brand";v="99"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": '"Windows"',
"sec-fetch-dest": "document",
"sec-fetch-mode": "navigate",
"sec-fetch-site": "same-site",
"sec-fetch-user": "?1",
"upgrade-insecure-requests": "1",
Referer: "https://chat.zalo.me/",
"Referrer-Policy": "strict-origin-when-cross-origin",
},
method: "GET",
});
const html = await response.text();
const regex = /https:\/\/stc-zlogin\.zdn\.vn\/main-([\d.]+)\.js/;
const match = html.match(regex);
return match === null || match === void 0 ? void 0 : match[1];
}
async function getLoginInfo(ctx, version) {
const form = new URLSearchParams();
form.append("continue", "https://zalo.me/pc");
form.append("v", version);
return await utils.request(ctx, "https://id.zalo.me/account/logininfo", {
headers: {
accept: "*/*",
"accept-language": "vi-VN,vi;q=0.9,fr-FR;q=0.8,fr;q=0.7,en-US;q=0.6,en;q=0.5",
"content-type": "application/x-www-form-urlencoded",
priority: "u=1, i",
"sec-ch-ua": '"Chromium";v="130", "Google Chrome";v="130", "Not?A_Brand";v="99"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": '"Windows"',
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-origin",
Referer: "https://id.zalo.me/account?continue=https%3A%2F%2Fzalo.me%2Fpc",
"Referrer-Policy": "strict-origin-when-cross-origin",
},
body: form,
method: "POST",
})
.then((res) => res.json())
.catch(utils.logger(ctx).error);
}
async function verifyClient(ctx, version) {
const form = new URLSearchParams();
form.append("type", "device");
form.append("continue", "https://zalo.me/pc");
form.append("v", version);
return await utils.request(ctx, "https://id.zalo.me/account/verify-client", {
headers: {
accept: "*/*",
"accept-language": "vi-VN,vi;q=0.9,fr-FR;q=0.8,fr;q=0.7,en-US;q=0.6,en;q=0.5",
"content-type": "application/x-www-form-urlencoded",
priority: "u=1, i",
"sec-ch-ua": '"Chromium";v="130", "Google Chrome";v="130", "Not?A_Brand";v="99"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": '"Windows"',
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-origin",
Referer: "https://id.zalo.me/account?continue=https%3A%2F%2Fzalo.me%2Fpc",
"Referrer-Policy": "strict-origin-when-cross-origin",
},
body: form,
method: "POST",
})
.then((res) => res.json())
.catch(utils.logger(ctx).error);
}
async function generate(ctx, version) {
const form = new URLSearchParams();
form.append("continue", "https://zalo.me/pc");
form.append("v", version);
return await utils.request(ctx, "https://id.zalo.me/account/authen/qr/generate", {
headers: {
accept: "*/*",
"accept-language": "vi-VN,vi;q=0.9,fr-FR;q=0.8,fr;q=0.7,en-US;q=0.6,en;q=0.5",
"content-type": "application/x-www-form-urlencoded",
priority: "u=1, i",
"sec-ch-ua": '"Chromium";v="130", "Google Chrome";v="130", "Not?A_Brand";v="99"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": '"Windows"',
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-origin",
Referer: "https://id.zalo.me/account?continue=https%3A%2F%2Fzalo.me%2Fpc",
"Referrer-Policy": "strict-origin-when-cross-origin",
},
body: form,
method: "POST",
})
.then((res) => res.json())
.catch(utils.logger(ctx).error);
}
async function saveQRCodeToFile(filepath, imageData) {
await fs.writeFile(filepath, imageData, "base64");
}
async function waitingScan(ctx, version, code, signal) {
const form = new URLSearchParams();
form.append("code", code);
form.append("continue", "https://chat.zalo.me/");
form.append("v", version);
return await utils.request(ctx, "https://id.zalo.me/account/authen/qr/waiting-scan", {
headers: {
accept: "*/*",
"accept-language": "vi-VN,vi;q=0.9,fr-FR;q=0.8,fr;q=0.7,en-US;q=0.6,en;q=0.5",
"content-type": "application/x-www-form-urlencoded",
priority: "u=1, i",
"sec-ch-ua": '"Chromium";v="130", "Google Chrome";v="130", "Not?A_Brand";v="99"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": '"Windows"',
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-origin",
Referer: "https://id.zalo.me/account?continue=https%3A%2F%2Fchat.zalo.me%2F",
"Referrer-Policy": "strict-origin-when-cross-origin",
},
body: form,
method: "POST",
signal,
})
.then((res) => res.json())
.then((data) => {
if (data.error_code == 8) {
return waitingScan(ctx, version, code, signal);
}
return data;
})
.catch((e) => {
if (!signal.aborted)
utils.logger(ctx).error(e);
});
}
async function waitingConfirm(ctx, version, code, signal) {
const form = new URLSearchParams();
form.append("code", code);
form.append("gToken", "");
form.append("gAction", "CONFIRM_QR");
form.append("continue", "https://chat.zalo.me/");
form.append("v", version);
utils.logger(ctx).info("Please confirm on your phone");
return await utils.request(ctx, "https://id.zalo.me/account/authen/qr/waiting-confirm", {
headers: {
accept: "*/*",
"accept-language": "vi-VN,vi;q=0.9,fr-FR;q=0.8,fr;q=0.7,en-US;q=0.6,en;q=0.5",
"content-type": "application/x-www-form-urlencoded",
priority: "u=1, i",
"sec-ch-ua": '"Chromium";v="130", "Google Chrome";v="130", "Not?A_Brand";v="99"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": '"Windows"',
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-origin",
Referer: "https://id.zalo.me/account?continue=https%3A%2F%2Fchat.zalo.me%2F",
"Referrer-Policy": "strict-origin-when-cross-origin",
},
body: form,
method: "POST",
signal,
})
.then((res) => res.json())
.then((data) => {
if (data.error_code == 8) {
return waitingConfirm(ctx, version, code, signal);
}
return data;
})
.catch((e) => {
if (!signal.aborted)
utils.logger(ctx).error(e);
});
}
async function checkSession(ctx) {
return await utils.request(ctx, "https://id.zalo.me/account/checksession?continue=https%3A%2F%2Fchat.zalo.me%2Findex.html", {
headers: {
accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
"accept-language": "vi-VN,vi;q=0.9,fr-FR;q=0.8,fr;q=0.7,en-US;q=0.6,en;q=0.5",
priority: "u=0, i",
"sec-ch-ua": '"Chromium";v="130", "Google Chrome";v="130", "Not?A_Brand";v="99"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": '"Windows"',
"sec-fetch-dest": "document",
"sec-fetch-mode": "navigate",
"sec-fetch-site": "same-origin",
"upgrade-insecure-requests": "1",
Referer: "https://id.zalo.me/account?continue=https%3A%2F%2Fchat.zalo.me%2F",
"Referrer-Policy": "strict-origin-when-cross-origin",
},
redirect: "manual",
method: "GET",
}).catch(utils.logger(ctx).error);
}
async function getUserInfo(ctx) {
return await utils.request(ctx, "https://jr.chat.zalo.me/jr/userinfo", {
headers: {
accept: "*/*",
"accept-language": "vi-VN,vi;q=0.9,fr-FR;q=0.8,fr;q=0.7,en-US;q=0.6,en;q=0.5",
priority: "u=1, i",
"sec-ch-ua": '"Chromium";v="130", "Google Chrome";v="130", "Not?A_Brand";v="99"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": '"Windows"',
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-site",
Referer: "https://chat.zalo.me/",
"Referrer-Policy": "strict-origin-when-cross-origin",
},
method: "GET",
})
.then((res) => res.json())
.catch(utils.logger(ctx).error);
}
async function loginQR(ctx, options, callback) {
ctx.cookie = new toughCookie.CookieJar();
ctx.userAgent = options.userAgent;
return new Promise(async (resolve, reject) => {
var _a;
const controller = new AbortController();
let qrTimeout = null;
function cleanUp() {
controller.abort();
if (qrTimeout) {
clearTimeout(qrTimeout);
qrTimeout = null;
}
}
try {
function retry() {
cleanUp();
return resolve(loginQR(ctx, options, callback));
}
function abort() {
cleanUp();
return reject(new ZaloApiLoginQRAborted.ZaloApiLoginQRAborted());
}
if (ctx.options.logging)
console.log();
const loginVersion = await loadLoginPage(ctx);
if (!loginVersion)
throw new ZaloApiError.ZaloApiError("Cannot get API login version");
utils.logger(ctx).info("Got login version:", loginVersion);
await getLoginInfo(ctx, loginVersion);
await verifyClient(ctx, loginVersion);
const qrGenResult = await generate(ctx, loginVersion);
if (!qrGenResult || !qrGenResult.data)
throw new ZaloApiError.ZaloApiError(`Unable to generate QRCode\nResponse: ${JSON.stringify(qrGenResult, null, 2)}`);
const qrData = qrGenResult.data;
if (callback) {
callback({
type: exports.LoginQRCallbackEventType.QRCodeGenerated,
data: Object.assign(Object.assign({}, qrGenResult.data), { image: qrGenResult.data.image.replace(/^data:image\/png;base64,/, "") }),
actions: {
async saveToFile(qrPath) {
var _a;
if (qrPath === void 0) { qrPath = (_a = options.qrPath) !== null && _a !== void 0 ? _a : "qr.png"; }
await saveQRCodeToFile(qrPath, qrData.image.replace(/^data:image\/png;base64,/, ""));
utils.logger(ctx).info("Scan the QR code at", `'${qrPath}'`, "to proceed with login");
},
retry,
abort,
},
});
}
else {
const qrPath = (_a = options.qrPath) !== null && _a !== void 0 ? _a : "qr.png";
await saveQRCodeToFile(qrPath, qrData.image.replace(/^data:image\/png;base64,/, ""));
utils.logger(ctx).info("Scan the QR code at", `'${qrPath}'`, "to proceed with login");
}
qrTimeout = setTimeout(() => {
cleanUp();
utils.logger(ctx).info("QR expired!");
if (callback) {
callback({
type: exports.LoginQRCallbackEventType.QRCodeExpired,
data: null,
actions: {
retry,
abort,
},
});
}
else {
retry();
}
}, 100000);
const scanResult = await waitingScan(ctx, loginVersion, qrGenResult.data.code, controller.signal);
if (!scanResult || !scanResult.data)
throw new ZaloApiError.ZaloApiError("Cannot get scan result");
if (callback) {
callback({
type: exports.LoginQRCallbackEventType.QRCodeScanned,
data: scanResult.data,
actions: {
retry,
abort,
},
});
}
const confirmResult = await waitingConfirm(ctx, loginVersion, qrGenResult.data.code, controller.signal);
if (!confirmResult)
throw new ZaloApiError.ZaloApiError("Cannot get confirm result");
clearTimeout(qrTimeout);
if (confirmResult.error_code == -13) {
if (callback) {
callback({
type: exports.LoginQRCallbackEventType.QRCodeDeclined,
data: {
code: qrData.code,
},
actions: {
retry,
abort,
},
});
}
else {
utils.logger(ctx).error("QRCode login declined");
throw new ZaloApiLoginQRDeclined.ZaloApiLoginQRDeclined();
}
return;
}
else if (confirmResult.error_code != 0) {
throw new ZaloApiError.ZaloApiError(`An error has occurred.\nResponse: ${JSON.stringify(confirmResult, null, 2)}`);
}
const checkSessionResult = await checkSession(ctx);
if (!checkSessionResult)
throw new ZaloApiError.ZaloApiError("Cannot get session, login failed");
utils.logger(ctx).info("Successfully logged into the account", scanResult.data.display_name);
const userInfo = await getUserInfo(ctx);
if (!userInfo || !userInfo.data)
throw new ZaloApiError.ZaloApiError("Can't get account info");
if (!userInfo.data.logged)
throw new ZaloApiError.ZaloApiError("Can't login");
resolve({
cookies: ctx.cookie.toJSON().cookies,
userInfo: userInfo.data.info,
});
}
catch (error) {
cleanUp();
reject(error);
}
});
}
exports.loginQR = loginQR;
+32
View File
@@ -0,0 +1,32 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const parseLinkFactory = utils.apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.file[0]}/api/message/parselink`);
/**
* Parse link
*
* @param link link to parse
*
* @throws {ZaloApiError}
*
*/
return async function parseLink(link) {
const params = {
link,
version: 1, // version 0 is not available errorMaps || version 1 is errorMaps (for response)
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
exports.parseLinkFactory = parseLinkFactory;
+32
View File
@@ -0,0 +1,32 @@
'use strict';
var ZaloApiError = require('../Errors/ZaloApiError.cjs');
var utils = require('../utils.cjs');
const rejectFriendRequestFactory = utils.apiFactory()((api, _ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.friend[0]}/api/friend/reject`);
/**
* Reject a friend request from a User
*
* @param friendId
*
* @throws {ZaloApiError}
*/
return async function rejectFriendRequest(friendId) {
const params = {
fid: friendId,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
exports.rejectFriendRequestFactory = rejectFriendRequestFactory;

Some files were not shown because too many files have changed in this diff Show More