2021-01-02 01:27:01 +03:00
|
|
|
import { DiscoveryModule, ModuleRef } from '@nestjs/core';
|
|
|
|
import {
|
|
|
|
Module,
|
|
|
|
DynamicModule,
|
|
|
|
Provider,
|
|
|
|
Type,
|
|
|
|
Global,
|
|
|
|
Inject,
|
|
|
|
OnApplicationShutdown,
|
2021-01-02 02:00:10 +03:00
|
|
|
Logger,
|
2021-01-02 01:27:01 +03:00
|
|
|
} from '@nestjs/common';
|
2020-03-19 16:21:35 +03:00
|
|
|
import {
|
|
|
|
TelegrafModuleOptions,
|
|
|
|
TelegrafModuleAsyncOptions,
|
|
|
|
TelegrafOptionsFactory,
|
2021-01-02 02:00:10 +03:00
|
|
|
Context,
|
2020-03-19 16:21:35 +03:00
|
|
|
} from './interfaces';
|
|
|
|
import {
|
2021-01-02 01:27:01 +03:00
|
|
|
TELEGRAF_BOT_NAME,
|
2020-03-19 16:21:35 +03:00
|
|
|
TELEGRAF_MODULE_OPTIONS,
|
|
|
|
} from './telegraf.constants';
|
2021-01-02 01:27:01 +03:00
|
|
|
import { MetadataAccessorService, UpdatesExplorerService } from './services';
|
|
|
|
import { getBotToken } from './utils';
|
|
|
|
import { Telegraf } from 'telegraf';
|
|
|
|
import { defer } from 'rxjs';
|
2020-03-19 16:21:35 +03:00
|
|
|
|
2021-01-02 01:27:01 +03:00
|
|
|
@Global()
|
2020-03-19 16:21:35 +03:00
|
|
|
@Module({
|
|
|
|
imports: [DiscoveryModule],
|
2021-01-02 01:27:01 +03:00
|
|
|
providers: [UpdatesExplorerService, MetadataAccessorService],
|
2020-03-19 16:21:35 +03:00
|
|
|
})
|
2021-01-02 01:27:01 +03:00
|
|
|
export class TelegrafCoreModule implements OnApplicationShutdown {
|
2021-01-02 02:00:10 +03:00
|
|
|
private static logger = new Logger(TelegrafCoreModule.name);
|
|
|
|
|
2021-01-02 01:27:01 +03:00
|
|
|
constructor(
|
|
|
|
@Inject(TELEGRAF_BOT_NAME) private readonly botName: string,
|
|
|
|
private readonly moduleRef: ModuleRef,
|
2021-01-02 01:32:49 +03:00
|
|
|
) {}
|
2021-01-02 01:27:01 +03:00
|
|
|
|
2020-03-19 16:21:35 +03:00
|
|
|
public static forRoot(options: TelegrafModuleOptions): DynamicModule {
|
2021-01-02 01:27:01 +03:00
|
|
|
const telegrafBotName = getBotToken(options.botName);
|
|
|
|
|
|
|
|
const telegrafBotProvider = {
|
|
|
|
provide: telegrafBotName,
|
|
|
|
useFactory: async (): Promise<any> =>
|
|
|
|
await defer(async () => {
|
2021-01-02 02:00:10 +03:00
|
|
|
const bot = new Telegraf<Context>(options.token);
|
2021-01-02 01:27:01 +03:00
|
|
|
this.applyBotMiddlewares(bot, options.middlewares);
|
2021-01-02 02:00:10 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Backward compatibility with versions < 1.4.0,
|
|
|
|
* TODO: remove that on next major release,
|
|
|
|
* after exception filters has been added
|
|
|
|
*/
|
|
|
|
if (!options.disableGlobalCatch) {
|
|
|
|
bot.catch((err, ctx: Context) => {
|
|
|
|
this.logger.error(
|
|
|
|
`Encountered an error for ${ctx.updateType} update type`,
|
|
|
|
err,
|
|
|
|
);
|
|
|
|
});
|
|
|
|
}
|
2021-01-02 01:27:01 +03:00
|
|
|
await bot.launch(options.launchOptions);
|
|
|
|
return bot;
|
|
|
|
}).toPromise(),
|
2020-03-19 19:23:51 +03:00
|
|
|
};
|
2021-01-02 01:27:01 +03:00
|
|
|
|
2020-03-19 16:21:35 +03:00
|
|
|
return {
|
|
|
|
module: TelegrafCoreModule,
|
2020-03-19 19:23:51 +03:00
|
|
|
providers: [
|
2021-01-02 01:27:01 +03:00
|
|
|
{
|
|
|
|
provide: TELEGRAF_MODULE_OPTIONS,
|
|
|
|
useValue: options,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
provide: TELEGRAF_BOT_NAME,
|
|
|
|
useValue: telegrafBotName,
|
|
|
|
},
|
|
|
|
telegrafBotProvider,
|
2020-03-19 19:23:51 +03:00
|
|
|
],
|
2021-01-02 01:27:01 +03:00
|
|
|
exports: [telegrafBotProvider],
|
2020-03-19 16:21:35 +03:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
public static forRootAsync(
|
|
|
|
options: TelegrafModuleAsyncOptions,
|
|
|
|
): DynamicModule {
|
2021-01-02 01:27:01 +03:00
|
|
|
const telegrafBotName = getBotToken(options.botName);
|
|
|
|
|
|
|
|
const telegrafBotProvider = {
|
|
|
|
provide: telegrafBotName,
|
|
|
|
useFactory: async (
|
|
|
|
telegrafModuleOptions: TelegrafModuleOptions,
|
|
|
|
): Promise<any> => {
|
|
|
|
const { botName, ...telegrafOptions } = telegrafModuleOptions;
|
|
|
|
|
|
|
|
return await defer(async () => {
|
2021-01-02 02:00:10 +03:00
|
|
|
const bot = new Telegraf<Context>(telegrafOptions.token);
|
2021-01-02 01:27:01 +03:00
|
|
|
this.applyBotMiddlewares(bot, telegrafOptions.middlewares);
|
2021-01-02 02:00:10 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Backward compatibility with versions < 1.4.0,
|
|
|
|
* TODO: remove that on next major release,
|
|
|
|
* after exception filters has been added
|
|
|
|
*/
|
|
|
|
if (!telegrafOptions.disableGlobalCatch) {
|
|
|
|
bot.catch((err, ctx: Context) => {
|
|
|
|
this.logger.error(
|
|
|
|
`Encountered an error for ${ctx.updateType} update type`,
|
|
|
|
err,
|
|
|
|
);
|
|
|
|
});
|
|
|
|
}
|
2021-01-02 01:27:01 +03:00
|
|
|
await bot.launch(telegrafOptions.launchOptions);
|
|
|
|
return bot;
|
|
|
|
}).toPromise();
|
|
|
|
},
|
2020-03-19 16:21:35 +03:00
|
|
|
inject: [TELEGRAF_MODULE_OPTIONS],
|
|
|
|
};
|
2021-01-02 01:27:01 +03:00
|
|
|
|
2020-03-19 16:21:35 +03:00
|
|
|
const asyncProviders = this.createAsyncProviders(options);
|
|
|
|
return {
|
|
|
|
module: TelegrafCoreModule,
|
|
|
|
imports: options.imports,
|
2021-01-02 01:27:01 +03:00
|
|
|
providers: [
|
|
|
|
...asyncProviders,
|
|
|
|
{
|
|
|
|
provide: TELEGRAF_BOT_NAME,
|
|
|
|
useValue: telegrafBotName,
|
|
|
|
},
|
|
|
|
telegrafBotProvider,
|
|
|
|
],
|
|
|
|
exports: [telegrafBotProvider],
|
2020-03-19 16:21:35 +03:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2021-01-02 01:27:01 +03:00
|
|
|
private static applyBotMiddlewares(bot, middlewares) {
|
|
|
|
if (middlewares) {
|
|
|
|
middlewares.forEach((middleware) => {
|
|
|
|
bot.use(middleware);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-19 16:21:35 +03:00
|
|
|
private static createAsyncProviders(
|
|
|
|
options: TelegrafModuleAsyncOptions,
|
|
|
|
): Provider[] {
|
|
|
|
if (options.useExisting || options.useFactory) {
|
|
|
|
return [this.createAsyncOptionsProvider(options)];
|
|
|
|
}
|
|
|
|
const useClass = options.useClass as Type<TelegrafOptionsFactory>;
|
|
|
|
return [
|
|
|
|
this.createAsyncOptionsProvider(options),
|
|
|
|
{
|
|
|
|
provide: useClass,
|
|
|
|
useClass,
|
|
|
|
},
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
private static createAsyncOptionsProvider(
|
|
|
|
options: TelegrafModuleAsyncOptions,
|
|
|
|
): Provider {
|
|
|
|
if (options.useFactory) {
|
|
|
|
return {
|
|
|
|
provide: TELEGRAF_MODULE_OPTIONS,
|
|
|
|
useFactory: options.useFactory,
|
|
|
|
inject: options.inject || [],
|
|
|
|
};
|
|
|
|
}
|
|
|
|
// `as Type<TelegrafOptionsFactory>` is a workaround for microsoft/TypeScript#31603
|
|
|
|
const inject = [
|
|
|
|
(options.useClass || options.useExisting) as Type<TelegrafOptionsFactory>,
|
|
|
|
];
|
|
|
|
return {
|
|
|
|
provide: TELEGRAF_MODULE_OPTIONS,
|
|
|
|
useFactory: async (optionsFactory: TelegrafOptionsFactory) =>
|
|
|
|
await optionsFactory.createTelegrafOptions(),
|
|
|
|
inject,
|
|
|
|
};
|
|
|
|
}
|
2021-01-02 01:27:01 +03:00
|
|
|
|
|
|
|
async onApplicationShutdown(): Promise<void> {
|
|
|
|
const bot = this.moduleRef.get<any>(this.botName);
|
|
|
|
bot && (await bot.stop());
|
|
|
|
}
|
2020-03-19 16:21:35 +03:00
|
|
|
}
|