UNPKG

airship-server

Version:

Airship is a framework for Node.JS & TypeScript that helps you to write big, scalable and maintainable API servers.

165 lines 8.06 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const VKApiError_1 = require("../../vkApi/VKApiError"); /** * HHEventsNotificationsSender sends output messages in 25 item batches */ class HHEventsNotificationsSender { constructor(tokensProvider, outputMessagesProvider, outputMessageSender, bannedEndpointsCache, logger) { this._tokensProvider = tokensProvider; this._outputMessagesProvider = outputMessagesProvider; this._outputMessageSender = outputMessageSender; this._bannedEndpointsCache = bannedEndpointsCache; this._logger = logger; this._groupsMessagesQueues = []; this._groupsTimeouts = []; this._outputMessagesProvider.getMessages((outputMessage, ack) => { this.handleMessage(outputMessage, ack); }); } handleMessage(message, ack) { return __awaiter(this, void 0, void 0, function* () { let isEmpty = this._outputMessageSender.isEmpty(message); if (isEmpty) { console.log('Empty message', message); ack(); return; } let isBannedGroup = yield this._bannedEndpointsCache.get(message.groupId * -1); let isBannedUser = yield this._bannedEndpointsCache.get(message.userId); if (isBannedGroup) { this._logger.warn(`Group ${message.groupId} is banned`); ack(); return; } if (isBannedUser) { this._logger.warn(`No permissions to send to user ${message.userId}`); ack(); return; } if (!this._groupsMessagesQueues[message.groupId]) this._groupsMessagesQueues[message.groupId] = []; this._groupsMessagesQueues[message.groupId].push({ message, ack }); if (this._groupsMessagesQueues[message.groupId].length == 1) { this._groupsTimeouts[message.groupId] = setTimeout(() => { clearTimeout(this._groupsTimeouts[message.groupId]); this._groupsTimeouts[message.groupId] = null; let batch = this._groupsMessagesQueues[message.groupId].slice(0, 25); this._groupsMessagesQueues[message.groupId] = this._groupsMessagesQueues[message.groupId].slice(25); this.sendByTimeout(batch); }, 600); } else if (this._groupsMessagesQueues[message.groupId].length >= 25) { let batch = this._groupsMessagesQueues[message.groupId].slice(0, 25); this._groupsMessagesQueues[message.groupId] = this._groupsMessagesQueues[message.groupId].slice(25); clearTimeout(this._groupsTimeouts[message.groupId]); this._groupsTimeouts[message.groupId] = null; let token = yield this._tokensProvider.getToken(message); yield this.sendBatch(batch, token); } }); } sendByTimeout(messages) { return __awaiter(this, void 0, void 0, function* () { let token = yield this._tokensProvider.getToken(messages[0].message); yield this.sendBatch(messages, token); }); } sendBatch(messages, token) { return __awaiter(this, void 0, void 0, function* () { function retry(message, ack) { setTimeout(() => { this.handleMessage(message, ack); }, 1000); } try { let response = yield this._outputMessageSender.sendBatch(messages.map(m => m.message), token); if (response['execute_errors']) { let errorIndex = 0; let i = 0; for (let responseCode of response['response']) { // vk api sometimes returns 0 for some reason if (responseCode === false) { let error = response['execute_errors'][errorIndex]; if (error['error_code'] == 6 || //error['error_code'] == 9 || error['error_code'] == 10) { retry.bind(this)(messages[i].message, messages[i].ack); } else if (error['error_code'] == 901) { // no permissions to send to user this._logger.warn(`no permissions to send to user userId: ${messages[i].message.userId} groupId: ${messages[i].message.groupId}`); //await this._bannedEndpointsCache.cache(messages[i].message.userId, true, 1000 * 60 * 5) messages[i].ack(); } else if (error['error_code'] == 5) { // group is banned yield this._bannedEndpointsCache.cache(messages[i].message.groupId * -1, true, 1000 * 60 * 60); messages[i].ack(); } else { messages[i].ack(); } errorIndex++; } else { messages[i].ack(); } i++; } } else { for (let i = 0; i <= response['response'].length - 1; i++) { messages[i].ack(); } } } catch (e) { console.log(e); if (e.message == 'no messages to send') { for (let i = 0; i <= messages.length - 1; i++) { messages[i].ack(); } } else if (e instanceof VKApiError_1.default) { if (e.errorCode == 6) { setTimeout(() => { for (let i = 0; i <= messages.length - 1; i++) { this.handleMessage(messages[i].message, messages[i].ack); } //this.sendBatch(messages, token) }, 300); } else if (e.errorCode == 5) { yield this._bannedEndpointsCache.cache(messages[0].message.groupId * -1, true, 1000 * 60 * 60); for (let i = 0; i <= messages.length - 1; i++) { messages[i].ack(); } } else { this._logger.error('Strange vk bug'); for (let i = 0; i <= messages.length - 1; i++) { messages[i].ack(); } } } else { this._logger.error('Very bad bug'); for (let i = 0; i <= messages.length - 1; i++) { messages[i].ack(); } } } }); } } exports.default = HHEventsNotificationsSender; //# sourceMappingURL=HHEventsNotificationsSender.js.map