2020-03-19 16:21:35 +03:00
|
|
|
import { Injectable, OnModuleInit } from '@nestjs/common';
|
|
|
|
import { DiscoveryService, ModuleRef } from '@nestjs/core';
|
|
|
|
import { MetadataScanner } from '@nestjs/core/metadata-scanner';
|
2020-12-26 16:11:09 +03:00
|
|
|
import { TelegrafMetadataAccessor } from './telegraf.metadata-accessor';
|
2020-03-19 16:21:35 +03:00
|
|
|
import { TelegrafProvider } from './telegraf.provider';
|
2020-12-26 14:54:10 +03:00
|
|
|
import { ListenerType } from './enums';
|
2020-03-19 18:20:07 +03:00
|
|
|
import {
|
2020-08-14 12:42:57 +03:00
|
|
|
ActionOptions,
|
|
|
|
CashtagOptions,
|
|
|
|
CommandOptions,
|
2020-12-25 23:11:16 +03:00
|
|
|
EmailOptions,
|
2020-08-14 12:42:57 +03:00
|
|
|
HashtagOptions,
|
|
|
|
HearsOptions,
|
|
|
|
InlineQueryOptions,
|
|
|
|
MentionOptions,
|
|
|
|
OnOptions,
|
|
|
|
PhoneOptions,
|
2020-12-25 23:11:16 +03:00
|
|
|
TextLinkOptions,
|
|
|
|
TextMentionOptions,
|
|
|
|
UrlOptions,
|
2020-03-19 18:20:07 +03:00
|
|
|
} from './decorators';
|
2020-12-26 16:11:09 +03:00
|
|
|
import { InstanceWrapper } from '@nestjs/core/injector/instance-wrapper';
|
2020-03-19 16:21:35 +03:00
|
|
|
|
|
|
|
@Injectable()
|
|
|
|
export class TelegrafExplorer implements OnModuleInit {
|
|
|
|
constructor(
|
|
|
|
private readonly moduleRef: ModuleRef,
|
|
|
|
private readonly discoveryService: DiscoveryService,
|
|
|
|
private readonly metadataAccessor: TelegrafMetadataAccessor,
|
|
|
|
private readonly metadataScanner: MetadataScanner,
|
|
|
|
) {}
|
|
|
|
|
2020-09-09 22:46:25 +03:00
|
|
|
private telegraf: TelegrafProvider;
|
|
|
|
|
2020-12-25 23:11:16 +03:00
|
|
|
onModuleInit(): void {
|
2020-12-26 14:54:10 +03:00
|
|
|
this.telegraf = this.moduleRef.get<TelegrafProvider>(TelegrafProvider, {
|
2020-09-09 22:46:25 +03:00
|
|
|
strict: false,
|
|
|
|
});
|
2020-03-19 16:21:35 +03:00
|
|
|
this.explore();
|
|
|
|
}
|
|
|
|
|
2020-12-25 23:11:16 +03:00
|
|
|
explore(): void {
|
2020-12-26 16:11:09 +03:00
|
|
|
const updateInstanceWrappers = this.filterUpdateClass();
|
|
|
|
|
|
|
|
updateInstanceWrappers.forEach((wrapper) => {
|
|
|
|
const { instance } = wrapper;
|
2020-12-25 23:11:16 +03:00
|
|
|
|
2020-12-26 16:11:09 +03:00
|
|
|
const prototype = Object.getPrototypeOf(instance);
|
|
|
|
this.metadataScanner.scanFromPrototype(
|
|
|
|
instance,
|
|
|
|
prototype,
|
|
|
|
(methodKey: string) =>
|
|
|
|
this.registerIfUpdateListener(instance, methodKey),
|
|
|
|
);
|
|
|
|
});
|
2020-12-25 23:11:16 +03:00
|
|
|
}
|
|
|
|
|
2020-12-26 16:11:09 +03:00
|
|
|
private filterUpdateClass(): InstanceWrapper[] {
|
|
|
|
return this.discoveryService
|
|
|
|
.getProviders()
|
|
|
|
.filter((wrapper) => wrapper.instance)
|
|
|
|
.filter((wrapper) => this.metadataAccessor.isUpdate(wrapper.instance));
|
2020-12-26 14:54:10 +03:00
|
|
|
}
|
|
|
|
|
2020-12-26 16:11:09 +03:00
|
|
|
private registerIfUpdateListener(
|
2020-12-25 23:11:16 +03:00
|
|
|
instance: Record<string, Function>,
|
|
|
|
methodKey: string,
|
|
|
|
): void {
|
|
|
|
const methodRef = instance[methodKey];
|
|
|
|
const middlewareFn = methodRef.bind(instance);
|
|
|
|
|
|
|
|
const listenerType = this.metadataAccessor.getListenerType(methodRef);
|
|
|
|
if (!listenerType) return;
|
|
|
|
|
|
|
|
const listenerOptions = this.metadataAccessor.getListenerOptions(methodRef);
|
|
|
|
|
|
|
|
switch (listenerType) {
|
|
|
|
case ListenerType.On: {
|
|
|
|
const { updateTypes } = listenerOptions as OnOptions;
|
|
|
|
this.telegraf.on(updateTypes, middlewareFn);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case ListenerType.Use: {
|
|
|
|
this.telegraf.use(middlewareFn);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case ListenerType.Start: {
|
|
|
|
this.telegraf.start(middlewareFn);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case ListenerType.Help: {
|
|
|
|
this.telegraf.help(middlewareFn);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case ListenerType.Settings: {
|
|
|
|
this.telegraf.settings(middlewareFn);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case ListenerType.Hears: {
|
|
|
|
const { triggers } = listenerOptions as HearsOptions;
|
|
|
|
this.telegraf.hears(triggers, middlewareFn);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case ListenerType.Command: {
|
|
|
|
const { command } = listenerOptions as CommandOptions;
|
|
|
|
this.telegraf.command(command, middlewareFn);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case ListenerType.Action: {
|
|
|
|
const { triggers } = listenerOptions as ActionOptions;
|
|
|
|
this.telegraf.action(triggers, middlewareFn);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case ListenerType.Mention: {
|
|
|
|
const { mention } = listenerOptions as MentionOptions;
|
|
|
|
this.telegraf.mention(mention, middlewareFn);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case ListenerType.Phone: {
|
|
|
|
const { phone } = listenerOptions as PhoneOptions;
|
|
|
|
this.telegraf.phone(phone, middlewareFn);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case ListenerType.Hashtag: {
|
|
|
|
const { hashtag } = listenerOptions as HashtagOptions;
|
|
|
|
this.telegraf.hashtag(hashtag, middlewareFn);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case ListenerType.Cashtag: {
|
|
|
|
const { cashtag } = listenerOptions as CashtagOptions;
|
|
|
|
this.telegraf.cashtag(cashtag, middlewareFn);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case ListenerType.Email: {
|
|
|
|
const { email } = listenerOptions as EmailOptions;
|
|
|
|
this.telegraf.email(email, middlewareFn);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case ListenerType.Url: {
|
|
|
|
const { url } = listenerOptions as UrlOptions;
|
|
|
|
this.telegraf.url(url, middlewareFn);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case ListenerType.TextLink: {
|
|
|
|
const { link } = listenerOptions as TextLinkOptions;
|
|
|
|
this.telegraf.textLink(link, middlewareFn);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case ListenerType.TextMention: {
|
|
|
|
const { mention } = listenerOptions as TextMentionOptions;
|
|
|
|
this.telegraf.textMention(mention, middlewareFn);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case ListenerType.InlineQuery: {
|
|
|
|
const { triggers } = listenerOptions as InlineQueryOptions;
|
|
|
|
this.telegraf.inlineQuery(triggers, middlewareFn);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case ListenerType.GameQuery: {
|
|
|
|
this.telegraf.gameQuery(middlewareFn);
|
|
|
|
break;
|
2020-03-19 16:21:35 +03:00
|
|
|
}
|
2020-09-10 11:23:04 +03:00
|
|
|
}
|
2020-03-19 17:25:47 +03:00
|
|
|
}
|
2020-03-19 16:21:35 +03:00
|
|
|
}
|