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.
106 lines • 4.37 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.CatchUpManager = void 0;
exports.resolveCatchUpThreadTypes = resolveCatchUpThreadTypes;
exports.requestCatchUp = requestCatchUp;
exports.registerCatchUp = registerCatchUp;
const constants_1 = require("./constants");
const ZCA_THREAD_TYPE_USER = 0;
const ZCA_THREAD_TYPE_GROUP = 1;
class CatchUpManager {
constructor(cooldownMs = constants_1.CATCH_UP_COOLDOWN_MS) {
this.cooldownMs = cooldownMs;
this.lastRunAt = 0;
}
shouldRun(now = Date.now()) {
return now - this.lastRunAt >= this.cooldownMs;
}
markRun(now = Date.now()) {
this.lastRunAt = now;
}
remainingCooldown(now = Date.now()) {
return Math.max(0, this.cooldownMs - (now - this.lastRunAt));
}
}
exports.CatchUpManager = CatchUpManager;
function resolveCatchUpThreadTypes(threadTypes) {
if (!threadTypes || threadTypes.length === 0) {
return [ZCA_THREAD_TYPE_USER, ZCA_THREAD_TYPE_GROUP];
}
const types = [];
if (threadTypes.includes('user'))
types.push(ZCA_THREAD_TYPE_USER);
if (threadTypes.includes('group'))
types.push(ZCA_THREAD_TYPE_GROUP);
return types;
}
function requestCatchUp(apiInstance, threadTypes) {
const listener = apiInstance === null || apiInstance === void 0 ? void 0 : apiInstance.listener;
if (typeof (listener === null || listener === void 0 ? void 0 : listener.requestOldMessages) !== 'function') {
console.warn('[ZaloMessageTrigger] requestOldMessages không khả dụng — bỏ qua kéo bù');
return false;
}
let requested = false;
for (const threadType of threadTypes) {
try {
listener.requestOldMessages(threadType, null);
requested = true;
}
catch (error) {
console.warn(`[ZaloMessageTrigger] Kéo bù thất bại cho threadType=${threadType}:`, error);
}
}
return requested;
}
function registerCatchUp(hookFunctions, apiInstance, webhookData, filter, threadTypes, manager = new CatchUpManager()) {
const webhookUrl = hookFunctions.getNodeWebhookUrl('default');
const zcaThreadTypes = resolveCatchUpThreadTypes(threadTypes);
const listener = apiInstance.listener;
listener.on('old_messages', async (messages, threadType) => {
if (!Array.isArray(messages) || messages.length === 0) {
return;
}
const isGroup = threadType === ZCA_THREAD_TYPE_GROUP;
console.log(`[ZaloMessageTrigger] Kéo bù: nhận ${messages.length} tin ${isGroup ? 'nhóm' : 'cá nhân'}`);
for (const message of messages) {
if (message && message.type === undefined) {
message.type = isGroup ? constants_1.ThreadTypeValue.Group : constants_1.ThreadTypeValue.User;
}
if (!filter.shouldProcessMessage(message)) {
continue;
}
const event = {
type: constants_1.EVENT_TYPES.MESSAGE,
data: message,
timestamp: Date.now(),
isCatchUp: true,
};
await hookFunctions.helpers
.httpRequest({
method: 'POST',
url: webhookUrl,
body: event,
headers: { 'Content-Type': 'application/json' },
})
.catch((error) => {
console.error('[ZaloMessageTrigger] Failed to trigger webhook (catch-up):', error);
});
}
});
listener.on('connected', () => {
var _a;
webhookData.connectCount = ((_a = webhookData.connectCount) !== null && _a !== void 0 ? _a : 0) + 1;
const now = Date.now();
if (!manager.shouldRun(now)) {
console.log(`[ZaloMessageTrigger] Bỏ qua kéo bù, còn chờ ${Math.ceil(manager.remainingCooldown(now) / 1000)}s`);
return;
}
if (requestCatchUp(apiInstance, zcaThreadTypes)) {
manager.markRun(now);
webhookData.lastCatchUpTime = now;
const reason = webhookData.connectCount === 1 ? 'kích hoạt workflow' : 'nối lại kết nối';
console.log(`[ZaloMessageTrigger] Đã yêu cầu kéo bù sau khi ${reason}`);
}
});
}
//# sourceMappingURL=CatchUpManager.js.map