n8n-nodes-zalo-tools
Version:
Các node hỗ trợ Zalo cho n8n
212 lines • 9.58 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ZaloLoginByQr = void 0;
const n8n_workflow_1 = require("n8n-workflow");
const zca_js_1 = require("zca-js");
const axios_1 = __importDefault(require("axios"));
class ZaloLoginByQr {
constructor() {
this.description = {
displayName: 'Zalo Login Via QR Code',
name: 'zaloLoginByQr',
group: ['Zalo'],
version: 2,
description: 'Đăng nhập Zalo bằng QR code và lưu thông tin vào Credential',
defaults: {
name: 'Zalo Login Via QR Code',
},
inputs: ["main"],
outputs: ["main"],
icon: 'file:../shared/zalo.svg',
credentials: [
{
name: 'zaloApi',
required: false,
displayName: 'Zalo Credential to connect with',
},
{
name: 'n8nZaloApi',
required: true,
displayName: 'n8n Account Credential',
},
],
properties: [
{
displayName: 'Proxy',
name: 'proxy',
type: 'string',
default: '',
placeholder: 'https://user:pass@host:port',
description: 'HTTP proxy to use for Zalo API requests',
},
{
displayName: 'QR Code File Path',
name: 'qrPath',
type: 'string',
default: '/tmp/zalo-qr.png',
description: 'Path where the QR code image will also be saved to disk (backup). The QR code is returned as binary output.',
},
],
};
}
async execute() {
const returnData = [];
const proxy = this.getNodeParameter('proxy', 0, '');
const qrPath = this.getNodeParameter('qrPath', 0, '/tmp/zalo-qr.png');
let n8nCredential;
try {
n8nCredential = await this.getCredentials('n8nZaloApi');
}
catch (error) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'n8n API credential is required to save Zalo login credentials.');
}
let zaloCredential;
try {
zaloCredential = await this.getCredentials('zaloApi');
}
catch (_error) {
}
try {
const zaloOptions = { selfListen: true, logging: true };
if (proxy)
zaloOptions.proxy = proxy;
const zalo = new zca_js_1.Zalo(zaloOptions);
if ((zaloCredential === null || zaloCredential === void 0 ? void 0 : zaloCredential.cookie) && (zaloCredential === null || zaloCredential === void 0 ? void 0 : zaloCredential.imei) && (zaloCredential === null || zaloCredential === void 0 ? void 0 : zaloCredential.userAgent)) {
this.logger.info('Attempting login with existing Zalo credentials...');
try {
const cookieFromCred = JSON.parse(zaloCredential.cookie);
const api = await zalo.login({
cookie: cookieFromCred,
imei: zaloCredential.imei,
userAgent: zaloCredential.userAgent,
});
if (api) {
returnData.push({
json: {
success: true,
message: 'Logged in successfully using existing Zalo credentials.',
loginMethod: 'cookie',
},
});
return [returnData];
}
}
catch (loginError) {
this.logger.warn(`Existing credentials login failed: ${loginError.message}. Falling back to QR login.`);
}
}
this.logger.info('Starting Zalo QR login process...');
let qrReadyResolve;
let qrReadyReject;
const qrReadyPromise = new Promise((resolve, reject) => {
qrReadyResolve = resolve;
qrReadyReject = reject;
});
const n8nApiUrl = n8nCredential.url || 'http://localhost:5678';
const n8nApiKey = n8nCredential.apiKey;
const capturedProxy = proxy;
let loginInfo;
const loginQRPromise = zalo.loginQR({ qrPath }, (qrEvent) => {
var _a, _b;
switch (qrEvent.type) {
case 0:
qrReadyResolve(qrEvent.data.image);
break;
case 1:
console.warn('[ZaloLoginByQr] QR code expired. Re-run the node to get a new QR code.');
qrEvent.actions.abort();
break;
case 2:
console.info(`[ZaloLoginByQr] QR code scanned by: ${(_b = (_a = qrEvent.data) === null || _a === void 0 ? void 0 : _a.display_name) !== null && _b !== void 0 ? _b : 'unknown'}`);
break;
case 3:
console.warn('[ZaloLoginByQr] QR code declined by user on phone.');
qrEvent.actions.abort();
break;
case 4:
if (qrEvent.data) {
loginInfo = {
cookie: qrEvent.data.cookie || [],
imei: qrEvent.data.imei || '',
userAgent: qrEvent.data.userAgent || '',
};
console.info('[ZaloLoginByQr] Login credentials received from Zalo.');
}
break;
default:
console.warn(`[ZaloLoginByQr] Unknown QR event type: ${qrEvent.type}`);
}
});
loginQRPromise.catch((err) => {
try {
qrReadyReject(err);
}
catch (_) {
}
});
loginQRPromise
.then(async () => {
var _a, _b;
if (!loginInfo || (!loginInfo.cookie.length && !loginInfo.imei)) {
console.error('[ZaloLoginByQr] Login succeeded but no credentials were captured — NOT saved.');
return;
}
try {
const response = await axios_1.default.post(`${n8nApiUrl}/api/v1/credentials`, {
name: 'Zalo API Credentials',
type: 'zaloApi',
data: {
cookie: JSON.stringify(loginInfo.cookie),
imei: loginInfo.imei,
userAgent: loginInfo.userAgent,
proxy: capturedProxy || '',
},
}, {
headers: {
'Content-Type': 'application/json',
'X-N8N-API-KEY': n8nApiKey,
},
});
console.info(`[ZaloLoginByQr] Credentials saved successfully. Credential ID: ${(_b = (_a = response.data) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : 'unknown'}`);
}
catch (err) {
console.error(`[ZaloLoginByQr] Failed to save credentials via n8n API: ${err.message}`);
}
})
.catch((err) => {
if (err.name !== 'ZaloApiLoginQRAborted') {
console.error(`[ZaloLoginByQr] QR login failed in background: ${err.message}`);
}
});
const qrImage = await qrReadyPromise;
this.logger.info(`QR code generated and saved to: ${qrPath}. Scan it with your Zalo app. Credentials will be saved automatically after you confirm login on your phone.`);
const binaryData = Buffer.from(qrImage, 'base64');
returnData.push({
json: {
success: true,
message: 'QR code generated. Scan the image below with your Zalo app. Credentials will be saved automatically once you confirm login on your phone.',
qrPath,
loginMethod: 'qr',
},
binary: {
data: await this.helpers.prepareBinaryData(binaryData, 'zalo-qr-code.png', 'image/png'),
},
});
return [returnData];
}
catch (error) {
if (this.continueOnFail()) {
const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray({ error: error.message }), { itemData: { item: 0 } });
return [executionData];
}
else {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), error);
}
}
}
}
exports.ZaloLoginByQr = ZaloLoginByQr;
//# sourceMappingURL=ZaloLoginByQr.node.js.map