mirror of
https://github.com/Maks1mS/nestjs-telegraf.git
synced 2025-03-28 20:33:44 +03:00
feat(): add middleware support & refactor
This commit is contained in:
parent
306f239603
commit
3e585859d0
@ -1,8 +1,8 @@
|
||||
import { createUpdateDecorator } from '../../helpers/create-update-decorator.helper';
|
||||
import { createUpdateListenerDecorator } from '../../helpers';
|
||||
|
||||
/**
|
||||
* Registers middleware for handling callback_data actions with regular expressions.
|
||||
*
|
||||
* @see https://telegraf.js.org/#/?id=action
|
||||
*/
|
||||
export const Action = createUpdateDecorator('action');
|
||||
export const Action = createUpdateListenerDecorator('action');
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { createUpdateDecorator } from '../../helpers/create-update-decorator.helper';
|
||||
import { createUpdateListenerDecorator } from '../../helpers';
|
||||
|
||||
/**
|
||||
* Cashtag handling.
|
||||
*
|
||||
* @see https://telegraf.js.org/#/?id=cashtag
|
||||
*/
|
||||
export const Cashtag = createUpdateDecorator('cashtag');
|
||||
export const Cashtag = createUpdateListenerDecorator('cashtag');
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { createUpdateDecorator } from '../../helpers/create-update-decorator.helper';
|
||||
import { createUpdateListenerDecorator } from '../../helpers';
|
||||
|
||||
/**
|
||||
* Command handling.
|
||||
*
|
||||
* @see https://telegraf.js.org/#/?id=command
|
||||
*/
|
||||
export const Command = createUpdateDecorator('command');
|
||||
export const Command = createUpdateListenerDecorator('command');
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { createUpdateDecorator } from '../../helpers/create-update-decorator.helper';
|
||||
import { createUpdateListenerDecorator } from '../../helpers';
|
||||
|
||||
/**
|
||||
* Registers middleware for handling messages with email entity.
|
||||
*
|
||||
* @see https://telegraf.js.org/#/?id=telegraf-email
|
||||
*/
|
||||
export const Email = createUpdateDecorator('email');
|
||||
export const Email = createUpdateListenerDecorator('email');
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { createUpdateDecorator } from '../../helpers/create-update-decorator.helper';
|
||||
import { createUpdateListenerDecorator } from '../../helpers';
|
||||
|
||||
/**
|
||||
* Registers middleware for handling callback_data actions with game query.
|
||||
*
|
||||
* @see https://telegraf.js.org/#/?id=inlinequery
|
||||
*/
|
||||
export const GameQuery = createUpdateDecorator('gameQuery');
|
||||
export const GameQuery = createUpdateListenerDecorator('gameQuery');
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { createUpdateDecorator } from '../../helpers/create-update-decorator.helper';
|
||||
import { createUpdateListenerDecorator } from '../../helpers';
|
||||
|
||||
/**
|
||||
* Hashtag handling.
|
||||
*
|
||||
* @see https://telegraf.js.org/#/?id=hashtag
|
||||
*/
|
||||
export const Hashtag = createUpdateDecorator('hashtag');
|
||||
export const Hashtag = createUpdateListenerDecorator('hashtag');
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { createUpdateDecorator } from '../../helpers/create-update-decorator.helper';
|
||||
import { createUpdateListenerDecorator } from '../../helpers';
|
||||
|
||||
/**
|
||||
* Registers middleware for handling text messages.
|
||||
*
|
||||
* @see https://telegraf.js.org/#/?id=hears
|
||||
*/
|
||||
export const Hears = createUpdateDecorator('hears');
|
||||
export const Hears = createUpdateListenerDecorator('hears');
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { createUpdateDecorator } from '../../helpers/create-update-decorator.helper';
|
||||
import { createUpdateListenerDecorator } from '../../helpers';
|
||||
|
||||
/**
|
||||
* Handler for /help command.
|
||||
*
|
||||
* @see https://telegraf.js.org/#/?id=help
|
||||
*/
|
||||
export const Help = createUpdateDecorator('help');
|
||||
export const Help = createUpdateListenerDecorator('help');
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { createUpdateDecorator } from '../../helpers/create-update-decorator.helper';
|
||||
import { createUpdateListenerDecorator } from '../../helpers';
|
||||
|
||||
/**
|
||||
* Registers middleware for handling inline_query actions with regular expressions.
|
||||
*
|
||||
* @see https://telegraf.js.org/#/?id=inlinequery
|
||||
*/
|
||||
export const InlineQuery = createUpdateDecorator('inlineQuery');
|
||||
export const InlineQuery = createUpdateListenerDecorator('inlineQuery');
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { createUpdateDecorator } from '../../helpers/create-update-decorator.helper';
|
||||
import { createUpdateListenerDecorator } from '../../helpers';
|
||||
|
||||
/**
|
||||
* Mention handling.
|
||||
*
|
||||
* @see https://telegraf.js.org/#/?id=mention
|
||||
*/
|
||||
export const Mention = createUpdateDecorator('mention');
|
||||
export const Mention = createUpdateListenerDecorator('mention');
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { createUpdateDecorator } from '../../helpers/create-update-decorator.helper';
|
||||
import { createUpdateListenerDecorator } from '../../helpers';
|
||||
|
||||
/**
|
||||
* Registers middleware for provided update type.
|
||||
*
|
||||
* @see https://telegraf.js.org/#/?id=on
|
||||
*/
|
||||
export const On = createUpdateDecorator('on');
|
||||
export const On = createUpdateListenerDecorator('on');
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { createUpdateDecorator } from '../../helpers/create-update-decorator.helper';
|
||||
import { createUpdateListenerDecorator } from '../../helpers';
|
||||
|
||||
/**
|
||||
* Phone number handling.
|
||||
*
|
||||
* @see https://telegraf.js.org/#/?id=phone
|
||||
*/
|
||||
export const Phone = createUpdateDecorator('phone');
|
||||
export const Phone = createUpdateListenerDecorator('phone');
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { createUpdateDecorator } from '../../helpers/create-update-decorator.helper';
|
||||
import { createUpdateListenerDecorator } from '../../helpers';
|
||||
|
||||
/**
|
||||
* Handler for /settings command.
|
||||
*
|
||||
* @see https://telegraf.js.org/#/?id=settings
|
||||
*/
|
||||
export const Settings = createUpdateDecorator('settings');
|
||||
export const Settings = createUpdateListenerDecorator('settings');
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { createUpdateDecorator } from '../../helpers/create-update-decorator.helper';
|
||||
import { createUpdateListenerDecorator } from '../../helpers';
|
||||
|
||||
/**
|
||||
* Handler for /start command.
|
||||
*
|
||||
* @see https://telegraf.js.org/#/?id=start
|
||||
*/
|
||||
export const Start = createUpdateDecorator('start');
|
||||
export const Start = createUpdateListenerDecorator('start');
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { createUpdateDecorator } from '../../helpers/create-update-decorator.helper';
|
||||
import { createUpdateListenerDecorator } from '../../helpers';
|
||||
|
||||
/**
|
||||
* Registers middleware for handling messages with text_link entity.
|
||||
*
|
||||
* @see https://telegraf.js.org/#/?id=telegraf-textlink
|
||||
*/
|
||||
export const TextLink = createUpdateDecorator('textLink');
|
||||
export const TextLink = createUpdateListenerDecorator('textLink');
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { createUpdateDecorator } from '../../helpers/create-update-decorator.helper';
|
||||
import { createUpdateListenerDecorator } from '../../helpers';
|
||||
|
||||
/**
|
||||
* Registers middleware for handling messages with text_mention entity.
|
||||
*
|
||||
* @see https://telegraf.js.org/#/?id=telegraf-textlink
|
||||
*/
|
||||
export const TextMention = createUpdateDecorator('textMention');
|
||||
export const TextMention = createUpdateListenerDecorator('textMention');
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { createUpdateDecorator } from '../../helpers/create-update-decorator.helper';
|
||||
import { createUpdateListenerDecorator } from '../../helpers';
|
||||
|
||||
/**
|
||||
* Registers middleware for handling messages with url entity.
|
||||
*
|
||||
* @see https://telegraf.js.org/#/?id=telegraf-url
|
||||
*/
|
||||
export const Url = createUpdateDecorator('url');
|
||||
export const Url = createUpdateListenerDecorator('url');
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { createUpdateDecorator } from '../../helpers/create-update-decorator.helper';
|
||||
import { createUpdateListenerDecorator } from '../../helpers';
|
||||
|
||||
/**
|
||||
* Registers a middleware.
|
||||
*
|
||||
* @see https://telegraf.js.org/#/?id=use
|
||||
*/
|
||||
export const Use = createUpdateDecorator('use');
|
||||
export const Use = createUpdateListenerDecorator('use');
|
||||
|
@ -1,6 +1,3 @@
|
||||
import { SetMetadata } from '@nestjs/common';
|
||||
import { SCENE_LISTENER_METADATA } from '../../telegraf.constants';
|
||||
import { SceneEventType } from '../../enums/scene-event-type.enum';
|
||||
import { createSceneListenerDecorator } from '../../helpers';
|
||||
|
||||
export const SceneEnter = (): MethodDecorator =>
|
||||
SetMetadata(SCENE_LISTENER_METADATA, SceneEventType.Enter);
|
||||
export const SceneEnter = createSceneListenerDecorator('enter');
|
||||
|
@ -1,6 +1,3 @@
|
||||
import { SetMetadata } from '@nestjs/common';
|
||||
import { SCENE_LISTENER_METADATA } from '../../telegraf.constants';
|
||||
import { SceneEventType } from '../../enums/scene-event-type.enum';
|
||||
import { createSceneListenerDecorator } from '../../helpers';
|
||||
|
||||
export const SceneLeave = (): MethodDecorator =>
|
||||
SetMetadata(SCENE_LISTENER_METADATA, SceneEventType.Leave);
|
||||
export const SceneLeave = createSceneListenerDecorator('leave');
|
||||
|
@ -1,4 +0,0 @@
|
||||
export enum SceneEventType {
|
||||
Enter = 'enter',
|
||||
Leave = 'leave',
|
||||
}
|
@ -3,17 +3,21 @@ import { DiscoveryService } from '@nestjs/core';
|
||||
import { MetadataScanner } from '@nestjs/core/metadata-scanner';
|
||||
import { InstanceWrapper } from '@nestjs/core/injector/instance-wrapper';
|
||||
import { BaseScene as Scene, Stage, Telegraf } from 'telegraf';
|
||||
import { TelegrafMetadataAccessor } from './telegraf.metadata-accessor';
|
||||
import { TelegrafMetadataAccessor } from '../telegraf.metadata-accessor';
|
||||
|
||||
@Injectable()
|
||||
export class TelegrafSceneExplorer implements OnModuleInit {
|
||||
private readonly stage = new Stage();
|
||||
|
||||
constructor(
|
||||
@Inject(Telegraf)
|
||||
private readonly telegraf: Telegraf,
|
||||
private readonly discoveryService: DiscoveryService,
|
||||
private readonly metadataAccessor: TelegrafMetadataAccessor,
|
||||
private readonly metadataScanner: MetadataScanner,
|
||||
) {}
|
||||
) {
|
||||
this.telegraf.use(this.stage.middleware());
|
||||
}
|
||||
|
||||
onModuleInit(): void {
|
||||
this.explore();
|
||||
@ -21,7 +25,6 @@ export class TelegrafSceneExplorer implements OnModuleInit {
|
||||
|
||||
private explore(): void {
|
||||
const sceneClasses = this.filterSceneClasses();
|
||||
const stage = new Stage();
|
||||
|
||||
sceneClasses.forEach((wrapper) => {
|
||||
const { instance } = wrapper;
|
||||
@ -30,7 +33,7 @@ export class TelegrafSceneExplorer implements OnModuleInit {
|
||||
instance.constructor,
|
||||
);
|
||||
const scene = new Scene(sceneId);
|
||||
stage.register(scene);
|
||||
this.stage.register(scene);
|
||||
|
||||
const prototype = Object.getPrototypeOf(instance);
|
||||
this.metadataScanner.scanFromPrototype(
|
||||
@ -39,11 +42,7 @@ export class TelegrafSceneExplorer implements OnModuleInit {
|
||||
(methodKey: string) =>
|
||||
this.registerIfListener(scene, instance, methodKey),
|
||||
);
|
||||
|
||||
stage.register(scene);
|
||||
});
|
||||
|
||||
this.telegraf.use(stage.middleware());
|
||||
}
|
||||
|
||||
private filterSceneClasses(): InstanceWrapper[] {
|
@ -3,7 +3,7 @@ import { DiscoveryService } from '@nestjs/core';
|
||||
import { MetadataScanner } from '@nestjs/core/metadata-scanner';
|
||||
import { InstanceWrapper } from '@nestjs/core/injector/instance-wrapper';
|
||||
import { Telegraf } from 'telegraf';
|
||||
import { TelegrafMetadataAccessor } from './telegraf.metadata-accessor';
|
||||
import { TelegrafMetadataAccessor } from '../telegraf.metadata-accessor';
|
||||
|
||||
@Injectable()
|
||||
export class TelegrafUpdateExplorer implements OnModuleInit {
|
18
lib/helpers/create-scene-listener-decorator.helper.ts
Normal file
18
lib/helpers/create-scene-listener-decorator.helper.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { SetMetadata } from '@nestjs/common';
|
||||
import { BaseScene as Scene } from 'telegraf';
|
||||
import { ComposerMethodArgs, SceneMethods } from '../telegraf.types';
|
||||
import { UPDATE_LISTENER_METADATA } from '../telegraf.constants';
|
||||
import { ListenerMetadata } from '../interfaces';
|
||||
|
||||
export function createSceneListenerDecorator<Method extends SceneMethods>(
|
||||
method: Method,
|
||||
) {
|
||||
return (
|
||||
...args: ComposerMethodArgs<Scene<never>, Method>
|
||||
): MethodDecorator => {
|
||||
return SetMetadata(UPDATE_LISTENER_METADATA, {
|
||||
method,
|
||||
args,
|
||||
} as ListenerMetadata);
|
||||
};
|
||||
}
|
@ -1,12 +1,15 @@
|
||||
import { SetMetadata } from '@nestjs/common';
|
||||
import { UpdateMethodArgs, UpdateMethods } from '../telegraf.types';
|
||||
import { Composer } from 'telegraf';
|
||||
import { ComposerMethodArgs, UpdateMethods } from '../telegraf.types';
|
||||
import { UPDATE_LISTENER_METADATA } from '../telegraf.constants';
|
||||
import { ListenerMetadata } from '../interfaces';
|
||||
|
||||
export function createUpdateDecorator<Method extends UpdateMethods>(
|
||||
export function createUpdateListenerDecorator<Method extends UpdateMethods>(
|
||||
method: Method,
|
||||
) {
|
||||
return (...args: UpdateMethodArgs<Method>): MethodDecorator => {
|
||||
return (
|
||||
...args: ComposerMethodArgs<Composer<never>, Method>
|
||||
): MethodDecorator => {
|
||||
return SetMetadata(UPDATE_LISTENER_METADATA, {
|
||||
method,
|
||||
args,
|
@ -1 +1,2 @@
|
||||
export * from './create-update-decorator.helper';
|
||||
export * from './create-update-listener-decorator.helper';
|
||||
export * from './create-scene-listener-decorator.helper';
|
||||
|
@ -1,6 +1,4 @@
|
||||
import { UpdateMethods } from '../telegraf.types';
|
||||
|
||||
export interface ListenerMetadata {
|
||||
method: UpdateMethods;
|
||||
method: string;
|
||||
args: unknown[];
|
||||
}
|
||||
|
@ -1,10 +1,12 @@
|
||||
import { ModuleMetadata, Type } from '@nestjs/common/interfaces';
|
||||
import { Middleware, Context } from 'telegraf';
|
||||
import { TelegrafLaunchOption, TelegrafOption } from '../telegraf.types';
|
||||
|
||||
export interface TelegrafModuleOptions {
|
||||
export interface TelegrafModuleOptions<C extends Context = Context> {
|
||||
token: string;
|
||||
options?: TelegrafOption;
|
||||
launchOptions?: TelegrafLaunchOption;
|
||||
middlewares?: Middleware<C>[];
|
||||
}
|
||||
|
||||
export interface TelegrafOptionsFactory {
|
||||
|
@ -4,4 +4,3 @@ export const UPDATE_METADATA = 'UPDATE_METADATA';
|
||||
export const UPDATE_LISTENER_METADATA = 'UPDATE_LISTENER_METADATA';
|
||||
|
||||
export const SCENE_METADATA = 'SCENE_METADATA';
|
||||
export const SCENE_LISTENER_METADATA = 'SCENE_LISTENER_METADATA';
|
||||
|
@ -15,8 +15,8 @@ import {
|
||||
} from './interfaces';
|
||||
import { TELEGRAF_MODULE_OPTIONS } from './telegraf.constants';
|
||||
import { TelegrafMetadataAccessor } from './telegraf.metadata-accessor';
|
||||
import { TelegrafUpdateExplorer } from './telegraf-update.explorer';
|
||||
import { TelegrafSceneExplorer } from './telegraf-scene.explorer';
|
||||
import { TelegrafUpdateExplorer } from './explorers/telegraf-update.explorer';
|
||||
import { TelegrafSceneExplorer } from './explorers/telegraf-scene.explorer';
|
||||
import { createProviders, TelegrafProvider } from './telegraf.providers';
|
||||
|
||||
@Module({
|
||||
|
@ -5,11 +5,12 @@ import { TelegrafModuleOptions } from './interfaces';
|
||||
|
||||
export const TelegrafProvider = {
|
||||
provide: Telegraf,
|
||||
inject: [TELEGRAF_MODULE_OPTIONS],
|
||||
useFactory: (options: TelegrafModuleOptions) => {
|
||||
const telegraf = new Telegraf(options.token, options.options);
|
||||
telegraf.use(...options.middlewares);
|
||||
return telegraf;
|
||||
},
|
||||
inject: [TELEGRAF_MODULE_OPTIONS],
|
||||
};
|
||||
|
||||
export function createProviders(options: TelegrafModuleOptions): Provider[] {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Composer, Middleware, Telegraf } from 'telegraf';
|
||||
import { Composer, Middleware, BaseScene, Telegraf } from 'telegraf';
|
||||
|
||||
export type Filter<T extends any[], F> = T extends []
|
||||
? []
|
||||
@ -8,14 +8,22 @@ export type Filter<T extends any[], F> = T extends []
|
||||
: [Head, ...Filter<Tail, F>]
|
||||
: [];
|
||||
|
||||
export type UpdateMethods = Exclude<
|
||||
keyof Composer<never>,
|
||||
'middleware' | 'guard' | 'filter' | 'drop'
|
||||
>;
|
||||
export type UpdateMethodArgs<T extends UpdateMethods> = Filter<
|
||||
Parameters<Composer<never>[T]>,
|
||||
Middleware<any>
|
||||
>;
|
||||
export type OnlyFunctionPropertyNames<T> = {
|
||||
[K in keyof T]: T[K] extends (...args: any) => any ? K : never;
|
||||
}[keyof T];
|
||||
|
||||
// export type FilterComposerMethods<T extends string> = Exclude<
|
||||
// T,
|
||||
// 'middleware' | 'guard' | 'filter' | 'drop'
|
||||
// >;
|
||||
|
||||
export type ComposerMethodArgs<
|
||||
T extends Composer<never>,
|
||||
U extends OnlyFunctionPropertyNames<T> = OnlyFunctionPropertyNames<T>
|
||||
> = Filter<Parameters<T[U]>, Middleware<never>>;
|
||||
|
||||
export type UpdateMethods = OnlyFunctionPropertyNames<Composer<never>>;
|
||||
export type SceneMethods = OnlyFunctionPropertyNames<BaseScene<never>>;
|
||||
|
||||
export type TelegrafOption = ConstructorParameters<typeof Telegraf>[1];
|
||||
export type TelegrafLaunchOption = Parameters<Telegraf['launch']>[0];
|
||||
|
@ -3,11 +3,13 @@ import { TelegrafModule } from '../lib';
|
||||
import { EchoService } from './echo.service';
|
||||
import { AppUpdate } from './app.update';
|
||||
import { HelloScene } from './scenes/hello.scene';
|
||||
import { sessionMiddleware } from './middleware/session.middleware';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
TelegrafModule.forRoot({
|
||||
token: '1467731595:AAHCvH65H9VQYKF9jE-E8c2rXsQBVAYseg8', // Don't steal >:(
|
||||
middlewares: [sessionMiddleware],
|
||||
}),
|
||||
],
|
||||
providers: [EchoService, AppUpdate, HelloScene],
|
||||
|
3
sample/middleware/session.middleware.ts
Normal file
3
sample/middleware/session.middleware.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import { session } from 'telegraf';
|
||||
|
||||
export const sessionMiddleware = session();
|
@ -11,7 +11,7 @@ export class HelloScene {
|
||||
}
|
||||
|
||||
@SceneLeave()
|
||||
async onSceneLeave(): Promise<void> {
|
||||
async onSceneLeave(ctx: Context): Promise<void> {
|
||||
console.log('Leave from scene');
|
||||
await ctx.reply('Bye Bye 👋');
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user