UNPKG

@puregram/hear

Version:

simple implementation of hearing messages system for puregram

131 lines (130 loc) 5.62 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.HearManager = void 0; require("reflect-metadata"); const puregram_1 = require("puregram"); const middleware_io_1 = require("middleware-io"); const helpers_1 = require("./helpers"); class HearManager { constructor() { this.composer = puregram_1.Composer.builder(); this.fallbackHandler = middleware_io_1.skipMiddleware; this.recompose(); } get length() { return this.composer.length; } get middleware() { return (context, next) => this.composed(context, next); } hear(hearConditions, handler) { const rawConditions = !Array.isArray(hearConditions) ? [hearConditions] : hearConditions; const hasConditions = rawConditions.every(Boolean); if (!hasConditions) { throw new Error('condition should be not empty'); } if (typeof handler !== 'function') { throw new TypeError('handler must be a function'); } let textCondition = false; let functionCondition = false; const conditions = rawConditions.map((condition) => { if (typeof condition === 'object' && !(condition instanceof RegExp)) { functionCondition = true; const entries = Object.entries(condition) .map(([path, value]) => [(0, helpers_1.splitPath)(path), (0, helpers_1.unifyCondition)(value)]); return (text, context) => (entries.every(([selectors, callback]) => { const value = (0, helpers_1.getObjectValue)(context, selectors); return callback(value, context); })); } if (typeof condition === 'function') { functionCondition = true; return condition; } textCondition = true; if (condition instanceof RegExp) { return (text, context) => { if (text === undefined) { return false; } const passed = condition.test(text); if (passed) { context.$match = text.match(condition); } return passed; }; } const stringCondition = String(condition); return (text) => text === stringCondition; }); const needText = textCondition && !functionCondition; this.composer.use((context, next) => { var _a, _b, _c; if (needText && !((_a = context.hasText) === null || _a === void 0 ? void 0 : _a.call(context)) && !((_b = context.hasCaption) === null || _b === void 0 ? void 0 : _b.call(context))) { return next(); } const text = (_c = context.text) !== null && _c !== void 0 ? _c : context.caption; const hasSome = conditions.some(condition => condition(text, context)); return hasSome ? handler(context, next) : next(); }); this.recompose(); return this; } command(command, handler) { if (!command) { throw new Error('command should not be empty'); } if (typeof handler !== 'function') { throw new TypeError('handler must be a function'); } this.composer.use((context, next) => { var _a, _b, _c, _d; if (!((_a = context.hasText) === null || _a === void 0 ? void 0 : _a.call(context)) && !((_b = context.hasCaption) === null || _b === void 0 ? void 0 : _b.call(context))) { return next(); } const text = (_c = context.text) !== null && _c !== void 0 ? _c : context.caption; const firstWord = text.split(/\s/)[0]; // INFO: starts with a '/' followed by a bunch of symbols (might have '@' and a bunch of symbols ending with 'bot') // INFO: /foo_bar@username_bot if (/^\/\w+(?:@\w+bot)?/.test(firstWord)) { // INFO: 't' for 'text' const [tCommandRaw, tUsername] = firstWord.split('@'); const hasUsername = tUsername !== undefined; const contextHasBotInfo = ((_d = context.telegram.bot) === null || _d === void 0 ? void 0 : _d.username) !== undefined; // INFO: we have '@<username>' part but we don't have info about our bot if (hasUsername && !contextHasBotInfo) { return next(); } // INFO: we have '@<username>' part but usernames do not match if (hasUsername && tUsername.toLowerCase() !== context.telegram.bot.username.toLowerCase()) { return next(); } // INFO: since command starts with '/' and we don't have that in [command] we need to slice that const tCommand = tCommandRaw.slice(1); if (tCommand !== command) { return next(); } return handler(context, next); } }); this.recompose(); return this; } /** A handler that is called when handlers are not found */ onFallback(handler) { this.fallbackHandler = handler; this.recompose(); return this; } recompose() { this.composed = this.composer.clone() .use(this.fallbackHandler) .compose(); } } exports.HearManager = HearManager;