yagop / node-telegram-bot-api

Telegram Bot API for NodeJS
MIT License
8.45k stars 1.53k forks source link

[Feature] Middleware in message handlers #893

Closed Mohanbarman closed 3 years ago

Mohanbarman commented 3 years ago

There is a feature in telegraf library which lets you specify middleware for your message listeners. I did a small hack and created a function for the same

// types
type TBotMiddlewareFun = (msg: Message, meta: any, sendMessage: TSendMessage, next?: TBotNextFun) => any;
type TBotNextFun = () => any;
type TSendMessage = (message: string) => Promise<Message>;

// middleware creator
export const applyBotMiddleware = (...fns: Array<TBotMiddlewareFun>) => <T>(msg: Message, meta: T) => {
    const callNext = (fn: TBotMiddlewareFun, fnIndex: number) => {
      // exit when there is no next middleware
      if (fnIndex > fns.length - 1) return;

      fn(
         msg, meta,
         // A small helper to reply to current user  
         (message: string) =>  telegramApi.api.sendMessage(msg.chat.id, message),
         // this calls the next middleware
         async () => { callNext(fns[++fnIndex], fnIndex) }
      );
    };
    // calling first middleware
    callNext(fns[0], 0);
  };

// You can now use this function in on handlers like this
api.onText(/\/start (.+)/, applyBotMiddleware(isBlocked, skipAuthorizedUsers, startController)); 

// function signature of middleware
function middleware(ctx: Message, match: RegExpMatchArray, reply: TSendMessage, next: TBotNextFun);

Feel free to improve the solution

kamikazechaser commented 3 years ago

I'll close and pin this.