feat(wip): rework listener decorators

This commit is contained in:
unknown 2020-12-23 21:35:40 +03:00
parent 23ea7632e1
commit b1a6fc3319
33 changed files with 318 additions and 268 deletions

View File

@ -1,19 +0,0 @@
import { SetMetadata } from '@nestjs/common';
import { DECORATORS } from '../telegraf.constants';
import { HearsTriggers } from 'telegraf/typings/composer';
import { Context } from '../interfaces';
export type TelegrafActionTriggers = HearsTriggers<Context>;
export interface ActionOptions {
triggers: TelegrafActionTriggers;
}
/**
* Registers middleware for handling callback_data actions with regular expressions.
*
* @see https://telegraf.js.org/#/?id=action
*/
export const Action = (triggers: TelegrafActionTriggers): MethodDecorator => {
return SetMetadata(DECORATORS.ACTION, { triggers });
};

View File

@ -1,17 +0,0 @@
import { SetMetadata } from '@nestjs/common';
import { DECORATORS } from '../telegraf.constants';
export type TelegrafCashtagCashtag = string | string[];
export interface CashtagOptions {
cashtag: TelegrafCashtagCashtag;
}
/**
* Cashtag handling.
*
* @see https://telegraf.js.org/#/?id=cashtag
*/
export const Cashtag = (cashtag: TelegrafCashtagCashtag): MethodDecorator => {
return SetMetadata(DECORATORS.CASHTAG, { cashtag });
};

View File

@ -1,17 +0,0 @@
import { SetMetadata } from '@nestjs/common';
import { DECORATORS } from '../telegraf.constants';
export type TelegrafCommandCommands = string | string[];
export interface CommandOptions {
commands: TelegrafCommandCommands;
}
/**
* Command handling.
*
* @see https://telegraf.js.org/#/?id=command
*/
export const Command = (commands: TelegrafCommandCommands): MethodDecorator => {
return SetMetadata(DECORATORS.COMMAND, { commands });
};

View File

@ -1,8 +1,8 @@
import { SetMetadata } from '@nestjs/common'; import { SetMetadata } from '@nestjs/common';
import { DECORATORS } from '../telegraf.constants'; import { TELEGRAF_UPDATE } from '../../telegraf.constants';
/** /**
* `@Update` decorator, it's like NestJS `@Controller` decorator, * `@Update` decorator, it's like NestJS `@Controller` decorator,
* but for Telegram Bot API updates. * but for Telegram Bot API updates.
*/ */
export const Update = (): ClassDecorator => SetMetadata(DECORATORS.UPDATE, {}); export const Update = (): ClassDecorator => SetMetadata(TELEGRAF_UPDATE, true);

View File

@ -1,22 +0,0 @@
import { SetMetadata } from '@nestjs/common';
import { DECORATORS } from '../telegraf.constants';
export type TelegrafEntityEntity =
| string
| string[]
| RegExp
| RegExp[]
| Function;
export interface EntityOptions {
entity: TelegrafEntityEntity;
}
/**
* Entity handling.
*
* @see https://telegraf.js.org/#/?id=entity
*/
export const Entity = (entity: TelegrafEntityEntity): MethodDecorator => {
return SetMetadata(DECORATORS.ENTITY, { entity });
};

View File

@ -1,17 +0,0 @@
import { SetMetadata } from '@nestjs/common';
import { DECORATORS } from '../telegraf.constants';
export type TelegrafHashtagHashtag = string | string[];
export interface HashtagOptions {
hashtag: TelegrafHashtagHashtag;
}
/**
* Hashtag handling.
*
* @see https://telegraf.js.org/#/?id=hashtag
*/
export const Hashtag = (hashtag: TelegrafHashtagHashtag): MethodDecorator => {
return SetMetadata(DECORATORS.HASHTAG, { hashtag });
};

View File

@ -1,19 +0,0 @@
import { SetMetadata } from '@nestjs/common';
import { DECORATORS } from '../telegraf.constants';
import { HearsTriggers } from 'telegraf/typings/composer';
import { Context } from '../interfaces';
export type TelegrafHearsTriggers = HearsTriggers<Context>;
export interface HearsOptions {
triggers: TelegrafHearsTriggers;
}
/**
* Registers middleware for handling text messages.
*
* @see https://telegraf.js.org/#/?id=hears
*/
export const Hears = (triggers: TelegrafHearsTriggers): MethodDecorator => {
return SetMetadata(DECORATORS.HEARS, { triggers: triggers });
};

View File

@ -1,11 +0,0 @@
import { SetMetadata } from '@nestjs/common';
import { DECORATORS } from '../telegraf.constants';
/**
* Handler for /help command.
*
* @see https://telegraf.js.org/#/?id=help
*/
export const Help = (): MethodDecorator => {
return SetMetadata(DECORATORS.HELP, {});
};

View File

@ -1,28 +0,0 @@
import { SetMetadata } from '@nestjs/common';
import { DECORATORS } from '../telegraf.constants';
import * as tt from 'telegraf/typings/telegram-types';
export type TelegrafInlineQueryTriggers = string | string[] | RegExp | RegExp[];
export interface InlineQueryOptions {
triggers?: TelegrafInlineQueryTriggers;
updateType:
| tt.UpdateType
| tt.UpdateType[]
| tt.MessageSubTypes
| tt.MessageSubTypes[];
}
/**
* Registers middleware for handling inline_query actions with regular expressions.
*
* @see https://telegraf.js.org/#/?id=inlinequery
*/
export const InlineQuery = (
triggers?: TelegrafInlineQueryTriggers,
): MethodDecorator => {
return SetMetadata(DECORATORS.INLINE_QUERY, {
triggers,
updateType: 'inline_query',
});
};

View File

@ -0,0 +1,25 @@
import { applyDecorators, SetMetadata } from '@nestjs/common';
import {
TELEGRAF_LISTENER_OPTIONS,
TELEGRAF_LISTENER_TYPE,
} from '../../telegraf.constants';
import { TelegrafActionTriggers } from '../../telegraf.types';
import { ListenerType } from '../../enums/listener-type.enum';
export interface ActionOptions {
triggers: TelegrafActionTriggers;
}
/**
* Registers middleware for handling callback_data actions with regular expressions.
*
* @see https://telegraf.js.org/#/?id=action
*/
export const Action = (triggers: TelegrafActionTriggers): MethodDecorator => {
return applyDecorators(
SetMetadata(TELEGRAF_LISTENER_TYPE, ListenerType.Action),
SetMetadata(TELEGRAF_LISTENER_OPTIONS, {
triggers,
} as ActionOptions),
);
};

View File

@ -0,0 +1,25 @@
import { applyDecorators, SetMetadata } from '@nestjs/common';
import {
TELEGRAF_LISTENER_OPTIONS,
TELEGRAF_LISTENER_TYPE,
} from '../../telegraf.constants';
import { TelegrafCashtag } from '../../telegraf.types';
import { ListenerType } from '../../enums/listener-type.enum';
export interface CashtagOptions {
cashtag: TelegrafCashtag;
}
/**
* Cashtag handling.
*
* @see https://telegraf.js.org/#/?id=cashtag
*/
export const Cashtag = (cashtag: TelegrafCashtag): MethodDecorator => {
return applyDecorators(
SetMetadata(TELEGRAF_LISTENER_TYPE, ListenerType.Cashtag),
SetMetadata(TELEGRAF_LISTENER_OPTIONS, {
cashtag,
} as CashtagOptions),
);
};

View File

@ -0,0 +1,25 @@
import { applyDecorators, SetMetadata } from '@nestjs/common';
import {
TELEGRAF_LISTENER_OPTIONS,
TELEGRAF_LISTENER_TYPE,
} from '../../telegraf.constants';
import { ListenerType } from '../../enums/listener-type.enum';
import { TelegrafCommand } from '../../telegraf.types';
export interface CommandOptions {
commands: TelegrafCommand;
}
/**
* Command handling.
*
* @see https://telegraf.js.org/#/?id=command
*/
export const Command = (commands: TelegrafCommand): MethodDecorator => {
return applyDecorators(
SetMetadata(TELEGRAF_LISTENER_TYPE, ListenerType.Command),
SetMetadata(TELEGRAF_LISTENER_OPTIONS, {
commands,
} as CommandOptions),
);
};

View File

@ -1,5 +1,6 @@
import { SetMetadata } from '@nestjs/common'; import { SetMetadata } from '@nestjs/common';
import { DECORATORS } from '../telegraf.constants'; import { TELEGRAF_LISTENER_TYPE } from '../../telegraf.constants';
import { ListenerType } from '../../enums/listener-type.enum';
/** /**
* Registers middleware for handling callback_data actions with game query. * Registers middleware for handling callback_data actions with game query.
@ -7,5 +8,5 @@ import { DECORATORS } from '../telegraf.constants';
* @see https://telegraf.js.org/#/?id=inlinequery * @see https://telegraf.js.org/#/?id=inlinequery
*/ */
export const GameQuery = (): MethodDecorator => { export const GameQuery = (): MethodDecorator => {
return SetMetadata(DECORATORS.GAME_QUERY, {}); return SetMetadata(TELEGRAF_LISTENER_TYPE, ListenerType.GameQuery);
}; };

View File

@ -0,0 +1,25 @@
import { applyDecorators, SetMetadata } from '@nestjs/common';
import {
TELEGRAF_LISTENER_OPTIONS,
TELEGRAF_LISTENER_TYPE,
} from '../../telegraf.constants';
import { ListenerType } from '../../enums/listener-type.enum';
import { TelegrafHashtag } from '../../telegraf.types';
export interface HashtagOptions {
hashtag: TelegrafHashtag;
}
/**
* Hashtag handling.
*
* @see https://telegraf.js.org/#/?id=hashtag
*/
export const Hashtag = (hashtag: TelegrafHashtag): MethodDecorator => {
return applyDecorators(
SetMetadata(TELEGRAF_LISTENER_TYPE, ListenerType.Hashtag),
SetMetadata(TELEGRAF_LISTENER_OPTIONS, {
hashtag,
} as HashtagOptions),
);
};

View File

@ -0,0 +1,25 @@
import { applyDecorators, SetMetadata } from '@nestjs/common';
import {
TELEGRAF_LISTENER_OPTIONS,
TELEGRAF_LISTENER_TYPE,
} from '../../telegraf.constants';
import { ListenerType } from '../../enums/listener-type.enum';
import { TelegrafHearsTriggers } from '../../telegraf.types';
export interface HearsOptions {
triggers: TelegrafHearsTriggers;
}
/**
* Registers middleware for handling text messages.
*
* @see https://telegraf.js.org/#/?id=hears
*/
export const Hears = (triggers: TelegrafHearsTriggers): MethodDecorator => {
return applyDecorators(
SetMetadata(TELEGRAF_LISTENER_TYPE, ListenerType.Hears),
SetMetadata(TELEGRAF_LISTENER_OPTIONS, {
triggers,
} as HearsOptions),
);
};

View File

@ -0,0 +1,12 @@
import { SetMetadata } from '@nestjs/common';
import { TELEGRAF_LISTENER_TYPE } from '../../telegraf.constants';
import { ListenerType } from '../../enums/listener-type.enum';
/**
* Handler for /help command.
*
* @see https://telegraf.js.org/#/?id=help
*/
export const Help = (): MethodDecorator => {
return SetMetadata(TELEGRAF_LISTENER_TYPE, ListenerType.Help);
};

View File

@ -0,0 +1,27 @@
import { applyDecorators, SetMetadata } from '@nestjs/common';
import {
TELEGRAF_LISTENER_OPTIONS,
TELEGRAF_LISTENER_TYPE,
} from '../../telegraf.constants';
import { ListenerType } from '../../enums/listener-type.enum';
import { TelegrafInlineQueryTriggers } from '../../telegraf.types';
export interface InlineQueryOptions {
triggers: TelegrafInlineQueryTriggers;
}
/**
* Registers middleware for handling inline_query actions with regular expressions.
*
* @see https://telegraf.js.org/#/?id=inlinequery
*/
export const InlineQuery = (
triggers: TelegrafInlineQueryTriggers,
): MethodDecorator => {
return applyDecorators(
SetMetadata(TELEGRAF_LISTENER_TYPE, ListenerType.InlineQuery),
SetMetadata(TELEGRAF_LISTENER_OPTIONS, {
triggers,
} as InlineQueryOptions),
);
};

View File

@ -0,0 +1,25 @@
import { applyDecorators, SetMetadata } from '@nestjs/common';
import {
TELEGRAF_LISTENER_OPTIONS,
TELEGRAF_LISTENER_TYPE,
} from '../../telegraf.constants';
import { ListenerType } from '../../enums/listener-type.enum';
import { TelegrafMention } from '../../telegraf.types';
export interface MentionOptions {
mention: TelegrafMention;
}
/**
* Mention handling.
*
* @see https://telegraf.js.org/#/?id=mention
*/
export const Mention = (mention: TelegrafMention): MethodDecorator => {
return applyDecorators(
SetMetadata(TELEGRAF_LISTENER_TYPE, ListenerType.Mention),
SetMetadata(TELEGRAF_LISTENER_OPTIONS, {
mention,
} as MentionOptions),
);
};

View File

@ -0,0 +1,25 @@
import { applyDecorators, SetMetadata } from '@nestjs/common';
import {
TELEGRAF_LISTENER_OPTIONS,
TELEGRAF_LISTENER_TYPE,
} from '../../telegraf.constants';
import { ListenerType } from '../../enums/listener-type.enum';
import { TelegrafUpdateType } from '../../telegraf.types';
export interface OnOptions {
updateTypes: TelegrafUpdateType;
}
/**
* Registers middleware for provided update type.
*
* @see https://telegraf.js.org/#/?id=on
*/
export const On = (updateTypes: TelegrafUpdateType): MethodDecorator => {
return applyDecorators(
SetMetadata(TELEGRAF_LISTENER_TYPE, ListenerType.On),
SetMetadata(TELEGRAF_LISTENER_OPTIONS, {
updateTypes,
} as OnOptions),
);
};

View File

@ -0,0 +1,25 @@
import { applyDecorators, SetMetadata } from '@nestjs/common';
import {
TELEGRAF_LISTENER_OPTIONS,
TELEGRAF_LISTENER_TYPE,
} from '../../telegraf.constants';
import { ListenerType } from '../../enums/listener-type.enum';
import { TelegrafPhone } from '../../telegraf.types';
export interface PhoneOptions {
phone: TelegrafPhone;
}
/**
* Phone number handling.
*
* @see https://telegraf.js.org/#/?id=phone
*/
export const Phone = (phone: TelegrafPhone): MethodDecorator => {
return applyDecorators(
SetMetadata(TELEGRAF_LISTENER_TYPE, ListenerType.Phone),
SetMetadata(TELEGRAF_LISTENER_OPTIONS, {
phone,
} as PhoneOptions),
);
};

View File

@ -0,0 +1,12 @@
import { SetMetadata } from '@nestjs/common';
import { TELEGRAF_LISTENER_TYPE } from '../../telegraf.constants';
import { ListenerType } from '../../enums/listener-type.enum';
/**
* Handler for /settings command.
*
* @see https://telegraf.js.org/#/?id=settings
*/
export const Settings = (): MethodDecorator => {
return SetMetadata(TELEGRAF_LISTENER_TYPE, ListenerType.Settings);
};

View File

@ -0,0 +1,12 @@
import { SetMetadata } from '@nestjs/common';
import { TELEGRAF_LISTENER_TYPE } from '../../telegraf.constants';
import { ListenerType } from '../../enums/listener-type.enum';
/**
* Handler for /start command.
*
* @see https://telegraf.js.org/#/?id=start
*/
export const Start = (): MethodDecorator => {
return SetMetadata(TELEGRAF_LISTENER_TYPE, ListenerType.Start);
};

View File

@ -0,0 +1,12 @@
import { SetMetadata } from '@nestjs/common';
import { TELEGRAF_LISTENER_TYPE } from '../../telegraf.constants';
import { ListenerType } from '../../enums/listener-type.enum';
/**
* Registers a middleware.
*
* @see https://telegraf.js.org/#/?id=use
*/
export const Use = (): MethodDecorator => {
return SetMetadata(TELEGRAF_LISTENER_TYPE, ListenerType.Use);
};

View File

@ -1,17 +0,0 @@
import { SetMetadata } from '@nestjs/common';
import { DECORATORS } from '../telegraf.constants';
export type TelegrafMentionUsername = string | string[];
export interface MentionOptions {
username: TelegrafMentionUsername;
}
/**
* Mention handling.
*
* @see https://telegraf.js.org/#/?id=mention
*/
export const Mention = (username: TelegrafMentionUsername): MethodDecorator => {
return SetMetadata(DECORATORS.MENTION, { username });
};

View File

@ -1,22 +0,0 @@
import { SetMetadata } from '@nestjs/common';
import { DECORATORS } from '../telegraf.constants';
import { UpdateType, MessageSubTypes } from 'telegraf/typings/telegram-types';
export type TelegrafOnUpdateTypes =
| UpdateType
| UpdateType[]
| MessageSubTypes
| MessageSubTypes[];
export interface OnOptions {
updateTypes: TelegrafOnUpdateTypes;
}
/**
* Registers middleware for provided update type.
*
* @see https://telegraf.js.org/#/?id=on
*/
export const On = (updateTypes: TelegrafOnUpdateTypes): MethodDecorator => {
return SetMetadata(DECORATORS.ON, { updateTypes: updateTypes });
};

View File

@ -1,17 +0,0 @@
import { SetMetadata } from '@nestjs/common';
import { DECORATORS } from '../telegraf.constants';
export type TelegrafPhonePhone = string | string[];
export interface PhoneOptions {
phone: TelegrafPhonePhone;
}
/**
* Phone number handling.
*
* @see https://telegraf.js.org/#/?id=phone
*/
export const Phone = (phone: TelegrafPhonePhone): MethodDecorator => {
return SetMetadata(DECORATORS.PHONE, { phone });
};

View File

@ -1,11 +0,0 @@
import { SetMetadata } from '@nestjs/common';
import { DECORATORS } from '../telegraf.constants';
/**
* Handler for /settings command.
*
* @see https://telegraf.js.org/#/?id=settings
*/
export const Settings = (): MethodDecorator => {
return SetMetadata(DECORATORS.SETTINGS, {});
};

View File

@ -1,11 +0,0 @@
import { SetMetadata } from '@nestjs/common';
import { DECORATORS } from '../telegraf.constants';
/**
* Handler for /start command.
*
* @see https://telegraf.js.org/#/?id=start
*/
export const Start = (): MethodDecorator => {
return SetMetadata(DECORATORS.START, {});
};

View File

@ -1,11 +0,0 @@
import { SetMetadata } from '@nestjs/common';
import { DECORATORS } from '../telegraf.constants';
/**
* Registers a middleware.
*
* @see https://telegraf.js.org/#/?id=use
*/
export const Use = (): MethodDecorator => {
return SetMetadata(DECORATORS.USE, {});
};

View File

@ -0,0 +1,16 @@
export enum ListenerType {
Use = 'use',
On = 'on',
Hears = 'hears',
Command = 'command',
Start = 'start',
Help = 'help',
Settings = 'settings',
Mention = 'mention',
Phone = 'phone',
Hashtag = 'hashtag',
Cashtag = 'cashtag',
Action = 'action',
InlineQuery = 'inlineQuery',
GameQuery = 'gameQuery',
}

View File

@ -1,23 +1,6 @@
export const TELEGRAF_MODULE_OPTIONS = 'TELEGRAF_MODULE_OPTIONS'; export const TELEGRAF_MODULE_OPTIONS = 'TELEGRAF_MODULE_OPTIONS';
export const TELEGRAF_PROVIDER = 'TelegrafProvider'; export const TELEGRAF_PROVIDER = 'TelegrafProvider';
export const DECORATORS_PREFIX = 'TELEGRAF'; export const TELEGRAF_UPDATE = 'TELEGRAF_UPDATE';
export const DECORATORS = { export const TELEGRAF_LISTENER_TYPE = 'TELEGRAF_LISTENER_TYPE';
USE: `${DECORATORS_PREFIX}/USE`, export const TELEGRAF_LISTENER_OPTIONS = 'TELEGRAF_LISTENER_OPTIONS';
ON: `${DECORATORS_PREFIX}/ON`,
HEARS: `${DECORATORS_PREFIX}/HEARS`,
COMMAND: `${DECORATORS_PREFIX}/COMMAND`,
START: `${DECORATORS_PREFIX}/START`,
HELP: `${DECORATORS_PREFIX}/HELP`,
SETTINGS: `${DECORATORS_PREFIX}/SETTINGS`,
ENTITY: `${DECORATORS_PREFIX}/ENTITY`,
MENTION: `${DECORATORS_PREFIX}/MENTION`,
PHONE: `${DECORATORS_PREFIX}/PHONE`,
HASHTAG: `${DECORATORS_PREFIX}/HASHTAG`,
CASHTAG: `${DECORATORS_PREFIX}/CASHTAG`,
ACTION: `${DECORATORS_PREFIX}/ACTION`,
INLINE_QUERY: `${DECORATORS_PREFIX}/INLINE_QUERY`,
GAME_QUERY: `${DECORATORS_PREFIX}/GAME_QUERY`,
UPDATE: `${DECORATORS_PREFIX}/UPDATE`,
UPDATE_HOOK: `${DECORATORS_PREFIX}/UPDATE_HOOK`,
};

View File

@ -10,7 +10,8 @@ import { Context, TelegrafModuleOptions } from './interfaces';
import { TELEGRAF_MODULE_OPTIONS } from './telegraf.constants'; import { TELEGRAF_MODULE_OPTIONS } from './telegraf.constants';
@Injectable() @Injectable()
export class TelegrafProvider extends Telegraf<Context> export class TelegrafProvider<C extends Context = Context>
extends Telegraf<C>
implements OnApplicationBootstrap, OnApplicationShutdown { implements OnApplicationBootstrap, OnApplicationShutdown {
private logger = new Logger('Telegraf'); private logger = new Logger('Telegraf');
private readonly launchOptions; private readonly launchOptions;
@ -20,18 +21,18 @@ export class TelegrafProvider extends Telegraf<Context>
this.launchOptions = options.launchOptions; this.launchOptions = options.launchOptions;
} }
async onApplicationBootstrap() { async onApplicationBootstrap(): Promise<void> {
this.catch((err, ctx: Context) => { this.catch(async (err, ctx) => {
this.logger.error( this.logger.error(
`Encountered an error for ${ctx.updateType} update type`, `Encountered an error for ${ctx.updateType} update type`,
err, err as string,
); );
}); });
await this.launch(this.launchOptions); await this.launch(this.launchOptions);
} }
async onApplicationShutdown() { async onApplicationShutdown(): Promise<void> {
await this.stop(); await this.stop();
} }
} }

13
lib/telegraf.types.ts Normal file
View File

@ -0,0 +1,13 @@
import { Context, Composer } from 'telegraf';
export type TelegrafActionTriggers = Parameters<Composer<Context>['action']>[0];
export type TelegrafHearsTriggers = Parameters<Composer<Context>['hears']>[0];
export type TelegrafInlineQueryTriggers = Parameters<
Composer<Context>['inlineQuery']
>[0];
export type TelegrafCashtag = Parameters<Composer<Context>['cashtag']>[0];
export type TelegrafHashtag = Parameters<Composer<Context>['hashtag']>[0];
export type TelegrafCommand = Parameters<Composer<Context>['command']>[0];
export type TelegrafMention = Parameters<Composer<Context>['mention']>[0];
export type TelegrafPhone = Parameters<Composer<Context>['phone']>[0];
export type TelegrafUpdateType = Parameters<Composer<Context>['on']>[0];