n8n-nodes-zalo-nnt
Version:
Unofficial Zalo integration for n8n - Send messages, manage groups, user operations with QR login. No API key required, works via browser simulation.
819 lines • 41.1 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ZaloUser = void 0;
const n8n_workflow_1 = require("n8n-workflow");
const ZaloUserDescription_1 = require("./ZaloUserDescription");
const zca_js_1 = require("zca-js");
let api;
class ZaloUser {
constructor() {
this.description = {
displayName: 'Zalo Người dùng by diginno.net',
name: 'zaloUser',
icon: 'file:../shared/image.svg',
group: ['Zalo'],
version: 1,
subtitle: '={{$parameter["resource"] + ": " + $parameter["operation"]}}',
description: 'Quản lý người dùng Zalo by diginno.net',
defaults: {
name: 'Zalo Người dùng by diginno.net',
},
inputs: ['main'],
outputs: ['main'],
credentials: [
{
name: 'zaloApi',
required: true,
displayName: 'Zalo Credential to connect with',
},
],
properties: ZaloUserDescription_1.zaloUserProperties,
};
}
async execute() {
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
const items = this.getInputData();
const returnData = [];
const resource = this.getNodeParameter('resource', 0);
const operation = this.getNodeParameter('operation', 0);
const zaloCred = await this.getCredentials('zaloApi');
let cookieFromCred = zaloCred.cookie;
try {
cookieFromCred = JSON.parse(zaloCred.cookie);
}
catch {
}
const imeiFromCred = zaloCred.imei;
const userAgentFromCred = zaloCred.userAgent;
const cookie = cookieFromCred !== null && cookieFromCred !== void 0 ? cookieFromCred : (_a = items.find((x) => x.json.cookie)) === null || _a === void 0 ? void 0 : _a.json.cookie;
const imei = imeiFromCred !== null && imeiFromCred !== void 0 ? imeiFromCred : (_b = items.find((x) => x.json.imei)) === null || _b === void 0 ? void 0 : _b.json.imei;
const userAgent = userAgentFromCred !== null && userAgentFromCred !== void 0 ? userAgentFromCred : (_c = items.find((x) => x.json.userAgent)) === null || _c === void 0 ? void 0 : _c.json.userAgent;
const isConnectionCheck = resource === 'system' && operation === 'checkConnection';
const checkedAt = new Date().toISOString();
const zalo = new zca_js_1.Zalo();
let loginError = null;
try {
const _api = await zalo.login({ cookie: cookie, imei, userAgent });
api = _api;
}
catch (error) {
if (!isConnectionCheck) {
throw error;
}
loginError = error;
}
if (isConnectionCheck) {
for (let i = 0; i < items.length; i++) {
if (loginError || !api) {
returnData.push({
json: {
alive: false,
status: 'Mất kết nối',
checkedAt,
error: (loginError === null || loginError === void 0 ? void 0 : loginError.message) || 'No API instance returned from login',
},
pairedItem: { item: i },
});
continue;
}
try {
const accountInfo = await api.fetchAccountInfo();
returnData.push({
json: { alive: true, status: 'Đang kết nối', checkedAt, accountInfo },
pairedItem: { item: i },
});
}
catch (checkError) {
returnData.push({
json: {
alive: false,
status: 'Mất kết nối',
checkedAt,
error: checkError.message,
},
pairedItem: { item: i },
});
}
}
return [returnData];
}
if (!api) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'No API instance found. Please make sure to provide valid credentials.');
}
for (let i = 0; i < items.length; i++) {
try {
if (resource === 'friend') {
if (operation === 'rejectFriendRequest') {
const userId = this.getNodeParameter('userId', i);
const response = await api.rejectFriendRequest(userId);
returnData.push({
json: {
status: 'Thành công',
message: 'Đã từ chối lời mời kết bạn',
userId: userId,
response: response,
},
pairedItem: { item: i },
});
}
else if (operation === 'undoFriendRequest') {
const userId = this.getNodeParameter('userId', i);
const response = await api.undoFriendRequest(userId);
returnData.push({
json: {
status: 'Thành công',
message: 'Đã hủy lời mời kết bạn',
userId: userId,
response: response,
},
pairedItem: { item: i },
});
}
else if (operation === 'getSentFriendRequest') {
try {
const response = await api.getSentFriendRequest();
const sentRequests = Object.values(response || {});
returnData.push({
json: {
status: 'Thành công',
totalRequests: sentRequests.length,
requests: sentRequests,
},
pairedItem: { item: i },
});
}
catch (error) {
if (error.message && error.message.includes('112')) {
returnData.push({
json: {
status: 'Thành công',
totalRequests: 0,
requests: [],
message: 'Không có lời mời kết bạn nào đang chờ xử lý',
},
pairedItem: { item: i },
});
}
else {
throw error;
}
}
}
else if (operation === 'removeFriend') {
const userId = this.getNodeParameter('userId', i);
const response = await api.removeFriend(userId);
returnData.push({
json: {
status: 'Thành công',
message: 'Đã xóa người dùng khỏi danh sách bạn bè',
userId: userId,
response: response,
},
pairedItem: { item: i },
});
}
else if (operation === 'getFriendRequestStatus') {
const userId = this.getNodeParameter('userId', i);
const response = await api.getFriendRequestStatus(userId);
returnData.push({
json: {
status: 'Thành công',
userId: userId,
friendStatus: response,
},
pairedItem: { item: i },
});
}
else if (operation === 'getFriendOnlines') {
const response = await api.getFriendOnlines();
returnData.push({
json: {
status: 'Thành công',
ownerStatus: response.ownerStatus,
onlines: response.onlines,
totalOnline: ((_d = response.onlines) === null || _d === void 0 ? void 0 : _d.length) || 0,
},
pairedItem: { item: i },
});
}
else if (operation === 'getRelatedFriendGroup') {
const userId = this.getNodeParameter('userId', i);
const response = await api.getRelatedFriendGroup(userId);
returnData.push({
json: {
status: 'Thành công',
userId: userId,
groupRelateds: response.groupRelateds,
},
pairedItem: { item: i },
});
}
else if (operation === 'acceptFriendRequest') {
const userId = this.getNodeParameter('userId', i);
const response = await api.acceptFriendRequest(userId);
returnData.push({
json: {
status: 'Thành công',
response: response,
},
pairedItem: {
item: i,
},
});
}
else if (operation === 'sendFriendRequest') {
const userId = this.getNodeParameter('userId', i);
const message = this.getNodeParameter('message', i);
const response = await api.sendFriendRequest(message, userId);
returnData.push({
json: {
status: 'Thành công',
response: response,
},
pairedItem: {
item: i,
},
});
}
else if (operation === 'getAllFriends') {
const limit = this.getNodeParameter('limit', i);
const response = await api.getAllFriends();
const friends = response.slice(0, limit) || [];
returnData.push({
json: {
friends: friends,
},
pairedItem: {
item: i,
},
});
}
else if (operation === 'findUser') {
const phoneNumber = this.getNodeParameter('phoneNumber', i);
const response = await api.findUser(phoneNumber);
returnData.push({
json: response,
pairedItem: {
item: i,
},
});
}
else if (operation === 'getCloseFriends') {
const limit = this.getNodeParameter('limit', i, 50);
const offset = this.getNodeParameter('offset', i, 0);
const allCloseFriends = await api.getCloseFriends();
const friends = allCloseFriends.slice(offset, offset + limit);
returnData.push({
json: {
status: 'Thành công',
friends: friends,
totalReturned: friends.length,
},
pairedItem: {
item: i,
},
});
}
else if (operation === 'findUserByUsername') {
const username = this.getNodeParameter('username', i);
const response = await api.findUserByUsername(username);
returnData.push({
json: response,
pairedItem: {
item: i,
},
});
}
else if (operation === 'getMultiUsersByPhones') {
const phonesStr = this.getNodeParameter('phones', i);
const phones = phonesStr
.split(',')
.map((p) => p.trim())
.filter((p) => p);
if (phones.length > 50) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Tối đa 50 số điện thoại được phép tìm kiếm cùng lúc', { itemIndex: i });
}
const response = await api.getMultiUsersByPhones(phones);
const users = Object.values(response || {});
returnData.push({
json: {
status: 'Thành công',
users: users,
totalRequested: phones.length,
totalFound: users.length,
},
pairedItem: {
item: i,
},
});
}
else if (operation === 'getFriendRecommendations') {
const response = await api.getFriendRecommendations();
returnData.push({
json: {
status: 'Thành công',
totalItems: ((_e = response.recommItems) === null || _e === void 0 ? void 0 : _e.length) || 0,
recommendations: response.recommItems || [],
expiredDuration: response.expiredDuration,
},
pairedItem: {
item: i,
},
});
}
}
else if (resource === 'account') {
if (operation === 'getUserInfo') {
const userId = this.getNodeParameter('userId', i);
const response = await api.getUserInfo(userId);
returnData.push({
json: response,
pairedItem: {
item: i,
},
});
}
else if (operation === 'fetchAccountInfo') {
const response = await api.fetchAccountInfo();
returnData.push({
json: {
status: 'Thành công',
accountInfo: response,
},
pairedItem: { item: i },
});
}
else if (operation === 'changeAccountSetting') {
const name = this.getNodeParameter('name', i);
const dob = this.getNodeParameter('dob', i);
const gender = this.getNodeParameter('gender', i);
const response = await api.updateProfile({
profile: {
name,
dob: dob,
gender: gender,
},
});
returnData.push({
json: {
status: 'Thành công',
response: response,
},
pairedItem: {
item: i,
},
});
}
else if (operation === 'updateLang') {
const language = this.getNodeParameter('language', i);
const response = await api.updateLang(language);
returnData.push({
json: {
status: 'Thành công',
message: `Đã đổi ngôn ngữ sang ${language}`,
language: language,
response: response,
},
pairedItem: { item: i },
});
}
else if (operation === 'updateProfileBio') {
const bio = this.getNodeParameter('bio', i);
const response = await api.updateProfileBio(bio);
returnData.push({
json: {
status: 'Thành công',
bio,
response,
},
pairedItem: { item: i },
});
}
else if (operation === 'changeAccountAvatar') {
const avatarUrl = this.getNodeParameter('avatarUrl', i);
const response = await api.changeAccountAvatar(avatarUrl);
returnData.push({
json: {
status: 'Thành công',
avatarUrl,
response,
},
pairedItem: { item: i },
});
}
else if (operation === 'getSettings') {
const response = await api.getSettings();
returnData.push({
json: {
status: 'Thành công',
settings: response,
},
pairedItem: { item: i },
});
}
else if (operation === 'updateSettings') {
const settingType = this.getNodeParameter('settingType', i);
const settingValue = this.getNodeParameter('settingValue', i);
const response = await api.updateSettings(settingType, settingValue);
returnData.push({
json: {
status: 'Thành công',
settingType,
settingValue,
response,
},
pairedItem: { item: i },
});
}
else if (operation === 'updateActiveStatus') {
const active = this.getNodeParameter('active', i);
const response = await api.updateActiveStatus(active);
returnData.push({
json: {
status: 'Thành công',
active,
response,
},
pairedItem: { item: i },
});
}
}
else if (resource === 'privacy') {
if (operation === 'blockUser') {
const userId = this.getNodeParameter('userId', i);
const response = await api.blockUser(userId);
returnData.push({
json: {
status: 'Thành công',
response: response,
},
pairedItem: {
item: i,
},
});
}
else if (operation === 'unblockUser') {
const userId = this.getNodeParameter('userId', i);
const response = await api.unblockUser(userId);
returnData.push({
json: {
status: 'Thành công',
response: response,
},
pairedItem: {
item: i,
},
});
}
else if (operation === 'blockViewFeed') {
const userId = this.getNodeParameter('userId', i);
const isBlockFeed = this.getNodeParameter('isBlockFeed', i);
const response = await api.blockViewFeed(isBlockFeed, userId);
returnData.push({
json: {
status: 'Thành công',
message: isBlockFeed
? 'Đã chặn người dùng xem bảng tin'
: 'Đã bỏ chặn người dùng xem bảng tin',
userId: userId,
isBlocked: isBlockFeed,
response: response,
},
pairedItem: { item: i },
});
}
else if (operation === 'sendReport') {
const threadId = this.getNodeParameter('reportThreadId', i);
const threadTypeNumber = this.getNodeParameter('reportThreadType', i, 0);
const type = threadTypeNumber === 1 ? zca_js_1.ThreadType.Group : zca_js_1.ThreadType.User;
const reason = this.getNodeParameter('reportReason', i);
const options = reason === zca_js_1.ReportReason.Other
? { reason: zca_js_1.ReportReason.Other, content: this.getNodeParameter('reportContent', i, '') }
: { reason };
const response = await api.sendReport(options, threadId, type);
returnData.push({
json: {
status: 'Thành công',
threadId,
reason,
response,
},
pairedItem: { item: i },
});
}
}
else if (resource === 'alias') {
if (operation === 'changeAliasName') {
const userId = this.getNodeParameter('userId', i);
const aliasName = this.getNodeParameter('aliasName', i);
const response = await api.changeFriendAlias(aliasName, userId);
returnData.push({
json: {
status: 'Thành công',
response: response,
},
pairedItem: {
item: i,
},
});
}
else if (operation === 'removeFriendAlias') {
const userId = this.getNodeParameter('userId', i);
const response = await api.removeFriendAlias(userId);
returnData.push({
json: {
status: 'Thành công',
message: 'Đã xóa tên gợi nhớ',
userId: userId,
response: response,
},
pairedItem: { item: i },
});
}
else if (operation === 'getAliasList') {
const count = this.getNodeParameter('count', i);
const page = this.getNodeParameter('page', i);
const response = await api.getAliasList(count, page);
returnData.push({
json: {
status: 'Thành công',
totalItems: ((_f = response.items) === null || _f === void 0 ? void 0 : _f.length) || 0,
updateTime: response.updateTime,
items: response.items || [],
},
pairedItem: { item: i },
});
}
}
else if (resource === 'avatar') {
if (operation === 'getAvatarList') {
const count = this.getNodeParameter('count', i);
const page = this.getNodeParameter('page', i);
const response = await api.getAvatarList(count, page);
returnData.push({
json: {
status: 'Thành công',
albumId: response.albumId,
hasMore: response.hasMore === 1,
totalPhotos: ((_g = response.photos) === null || _g === void 0 ? void 0 : _g.length) || 0,
photos: response.photos || [],
},
pairedItem: { item: i },
});
}
else if (operation === 'getAvatarUrlProfile') {
const userId = this.getNodeParameter('userId', i);
const useLargeAvatar = this.getNodeParameter('avatarSize', i, false);
const response = await api.getAvatarUrlProfile(userId, useLargeAvatar ? zca_js_1.AvatarSize.Large : zca_js_1.AvatarSize.Small);
returnData.push({
json: {
status: 'Thành công',
userId: userId,
avatarUrl: (_h = response[userId]) === null || _h === void 0 ? void 0 : _h.avatar,
},
pairedItem: { item: i },
});
}
else if (operation === 'getFullAvatar') {
const userId = this.getNodeParameter('userId', i);
const response = await api.getFullAvatar(userId);
returnData.push({
json: {
status: 'Thành công',
userId: userId,
avatarData: response,
},
pairedItem: { item: i },
});
}
else if (operation === 'reuseAvatar') {
const photoId = this.getNodeParameter('photoId', i);
const response = await api.reuseAvatar(photoId);
returnData.push({
json: {
status: 'Thành công',
message: 'Đã đổi lại ảnh đại diện cũ',
photoId: photoId,
response: response,
},
pairedItem: { item: i },
});
}
else if (operation === 'deleteAvatar') {
const photoIds = this.getNodeParameter('photoIds', i);
const photoIdArray = photoIds
.split(',')
.map((id) => id.trim())
.filter((id) => id);
const response = await api.deleteAvatar(photoIdArray);
const successCount = ((_j = response.delPhotoIds) === null || _j === void 0 ? void 0 : _j.length) || 0;
const failedIds = Object.keys(response.errMap || {});
returnData.push({
json: {
status: successCount > 0 ? 'Thành công' : 'Thất bại',
totalRequested: photoIdArray.length,
successCount: successCount,
failedCount: failedIds.length,
deletedPhotoIds: response.delPhotoIds || [],
errors: response.errMap || {},
},
pairedItem: { item: i },
});
}
}
else if (resource === 'message') {
if (operation === 'undoMessage') {
const threadId = this.getNodeParameter('threadId', i);
const type = this.getNodeParameter('threadType', i);
const msgId = this.getNodeParameter('msgId', i);
const cliMsgId = this.getNodeParameter('cliMsgId', i);
const UndoOptions = {
msgId: msgId,
cliMsgId: cliMsgId,
};
const response = await api.undo(UndoOptions, threadId, type);
returnData.push({
json: {
status: 'Thành công',
response: response,
},
pairedItem: {
item: i,
},
});
}
else if (operation === 'addReaction') {
const threadId = this.getNodeParameter('reactionThreadId', i);
const threadTypeNumber = this.getNodeParameter('reactionThreadType', i, 0);
const type = threadTypeNumber === 1 ? zca_js_1.ThreadType.Group : zca_js_1.ThreadType.User;
const msgId = this.getNodeParameter('reactionMsgId', i);
const cliMsgId = this.getNodeParameter('reactionCliMsgId', i);
const icon = this.getNodeParameter('reactionIcon', i);
const response = await api.addReaction(zca_js_1.Reactions[icon], {
data: { msgId, cliMsgId },
threadId,
type,
});
returnData.push({
json: {
status: 'Thành công',
threadId,
icon,
response,
},
pairedItem: { item: i },
});
}
else if (operation === 'forwardMessage') {
const message = this.getNodeParameter('forwardMessageContent', i);
const threadIdsRaw = this.getNodeParameter('forwardThreadIds', i);
const threadTypeNumber = this.getNodeParameter('forwardThreadType', i, 0);
const type = threadTypeNumber === 1 ? zca_js_1.ThreadType.Group : zca_js_1.ThreadType.User;
const threadIds = threadIdsRaw
.split(',')
.map((id) => id.trim())
.filter((id) => id);
if (!message || message.trim() === '') {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Nội dung tin nhắn không được để trống', {
itemIndex: i,
});
}
if (threadIds.length === 0) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Danh sách ID đích không được để trống', { itemIndex: i });
}
const response = await api.forwardMessage({ message }, threadIds, type);
returnData.push({
json: {
status: 'Thành công',
threadIds,
success: response.success,
fail: response.fail,
},
pairedItem: { item: i },
});
}
else if (operation === 'deleteMessage') {
const threadId = this.getNodeParameter('deleteThreadId', i);
const threadTypeNumber = this.getNodeParameter('deleteThreadType', i, 0);
const type = threadTypeNumber === 1 ? zca_js_1.ThreadType.Group : zca_js_1.ThreadType.User;
const msgId = this.getNodeParameter('deleteMsgId', i);
const cliMsgId = this.getNodeParameter('deleteCliMsgId', i);
const uidFrom = this.getNodeParameter('deleteUidFrom', i);
const onlyMe = this.getNodeParameter('deleteOnlyMe', i, true);
const response = await api.deleteMessage({
data: { cliMsgId, msgId, uidFrom },
threadId,
type,
}, onlyMe);
returnData.push({
json: {
status: 'Thành công',
threadId,
msgId,
onlyMe,
response,
},
pairedItem: { item: i },
});
}
else if (operation === 'sendSeenEvent') {
const threadTypeNumber = this.getNodeParameter('seenThreadType', i, 0);
const type = threadTypeNumber === 1 ? zca_js_1.ThreadType.Group : zca_js_1.ThreadType.User;
const messages = this.getNodeParameter('seenMessages', i);
const response = await api.sendSeenEvent(messages, type);
returnData.push({
json: {
status: 'Thành công',
response,
},
pairedItem: { item: i },
});
}
else if (operation === 'sendDeliveredEvent') {
const threadTypeNumber = this.getNodeParameter('deliveredThreadType', i, 0);
const type = threadTypeNumber === 1 ? zca_js_1.ThreadType.Group : zca_js_1.ThreadType.User;
const isSeen = this.getNodeParameter('deliveredIsSeen', i, false);
const messages = this.getNodeParameter('deliveredMessages', i);
const response = await api.sendDeliveredEvent(isSeen, messages, type);
returnData.push({
json: {
status: 'Thành công',
isSeen,
response,
},
pairedItem: { item: i },
});
}
}
else if (resource === 'system') {
if (operation === 'keepAlive') {
const response = await api.keepAlive();
returnData.push({
json: {
status: 'Thành công',
message: 'Session đã được làm mới',
response: response,
},
pairedItem: { item: i },
});
}
else if (operation === 'lastOnline') {
const userId = this.getNodeParameter('userId', i);
const response = await api.lastOnline(userId);
returnData.push({
json: {
status: 'Thành công',
userId: userId,
lastOnline: response,
},
pairedItem: { item: i },
});
}
else if (operation === 'parseLink') {
const link = this.getNodeParameter('linkToParse', i);
const response = await api.parseLink(link);
returnData.push({
json: {
status: 'Thành công',
link,
data: response.data,
errorMaps: response.error_maps,
},
pairedItem: { item: i },
});
}
else if (operation === 'getCookie') {
const cookieJar = api.getCookie().toJSON();
returnData.push({
json: {
status: 'Thành công',
warning: 'Cookie này cấp quyền truy cập đầy đủ vào tài khoản Zalo. Không chia sẻ, không lưu vào workflow công khai, và lưu ý nó sẽ tồn tại dạng plaintext trong execution log của n8n.',
cookie: cookieJar,
},
pairedItem: { item: i },
});
}
}
}
catch (error) {
if (this.continueOnFail()) {
returnData.push({
json: {
error: error.message,
},
pairedItem: {
item: i,
},
});
continue;
}
throw new n8n_workflow_1.NodeOperationError(this.getNode(), error, {
itemIndex: i,
});
}
}
return [returnData];
}
}
exports.ZaloUser = ZaloUser;
//# sourceMappingURL=ZaloUser.node.js.map