mirror of
https://github.com/Maks1mS/nestjs-telegraf.git
synced 2024-12-24 15:04:38 +03:00
chore(release): v1.0.0-alpha.1 (#39)
This commit is contained in:
commit
29e489f619
@ -1,5 +1,4 @@
|
||||
{
|
||||
"trailingComma": "es5",
|
||||
"singleQuote": true,
|
||||
"semi": false
|
||||
"trailingComma": "all",
|
||||
"singleQuote": true
|
||||
}
|
||||
|
245
README.md
245
README.md
@ -27,213 +27,126 @@
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
$ npm i nestjs-telegraf telegraf
|
||||
$ npm i nestjs-telegraf
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### An example of package usage
|
||||
Once the installation process is complete, we can import the TelegrafModule into the root AppModule.
|
||||
|
||||
```typescript
|
||||
/* bot.module.ts */
|
||||
/* app.module.ts */
|
||||
|
||||
import { Module, OnModuleInit, Logger } from '@nestjs/common'
|
||||
import { ModuleRef } from '@nestjs/core'
|
||||
import { ConfigModule } from '@nestjs/config'
|
||||
import { TelegrafModule, TelegrafService } from 'nestjs-telegraf'
|
||||
import botConfig from './bot.config'
|
||||
import { TelegrafConfigService } from './telegraf-config.service'
|
||||
import { BotService } from './bot.service'
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TelegrafModule } from 'nestjs-telegraf';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
TelegrafModule.fromFactory({
|
||||
imports: [ConfigModule.forFeature(botConfig)],
|
||||
useClass: TelegrafConfigService,
|
||||
}),
|
||||
TelegrafModule.forRoot({
|
||||
token: 'TELEGRAM_BOT_TOKEN',
|
||||
})
|
||||
],
|
||||
exports: [TelegrafModule],
|
||||
providers: [BotService],
|
||||
})
|
||||
export class BotModule implements OnModuleInit {
|
||||
constructor(
|
||||
private readonly moduleRef: ModuleRef,
|
||||
private readonly telegrafService: TelegrafService
|
||||
) {}
|
||||
|
||||
onModuleInit() {
|
||||
this.telegrafService.init(this.moduleRef)
|
||||
this.telegrafService.startPolling()
|
||||
}
|
||||
}
|
||||
export class AppModule {}
|
||||
```
|
||||
|
||||
```typescript
|
||||
/* telegraf-config.service.ts */
|
||||
The `forRoot()` method accepts the same configuration object as Telegraf class constructor from the Telegraf package, as described [here](https://telegraf.js.org/#/?id=constructor).
|
||||
|
||||
import { Injectable } from '@nestjs/common'
|
||||
import { TelegrafOptionsFactory, TelegrafModuleOptions } from 'nestjs-telegraf'
|
||||
import { ConfigService } from '@nestjs/config'
|
||||
## Telegraf methods
|
||||
|
||||
Each Telegraf instance method described [here](https://telegraf.js.org/#/?id=telegraf) has own decorator in `nestjs-telegraf` package. The name of the decorator corresponds to the name of the Telegraf method and starts with `Telegraf`. For example [`@TelegrafHears`](https://telegraf.js.org/#/?id=hears), [`@TelegrafOn`](https://telegraf.js.org/#/?id=on), [`@TelegrafAction`](https://telegraf.js.org/#/?id=action) and so on.
|
||||
|
||||
Now let's try to repeat the example from the Telegraf [documentation page](https://telegraf.js.org/#/?id=example).
|
||||
|
||||
```typescript
|
||||
/* app.service.ts */
|
||||
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import {
|
||||
TelegrafStart,
|
||||
TelegrafHelp,
|
||||
TelegrafOn,
|
||||
TelegrafHears,
|
||||
ContextMessageUpdate,
|
||||
} from 'nestjs-telegraf';
|
||||
|
||||
@Injectable()
|
||||
export class TelegrafConfigService implements TelegrafOptionsFactory {
|
||||
constructor(private readonly configService: ConfigService) {}
|
||||
export class AppService {
|
||||
@TelegrafStart()
|
||||
start(ctx: ContextMessageUpdate) {
|
||||
ctx.reply('Welcome');
|
||||
}
|
||||
|
||||
createTelegrafOptions(): TelegrafModuleOptions {
|
||||
return {
|
||||
token: this.configService.get('bot.token'),
|
||||
}
|
||||
@TelegrafHelp()
|
||||
help(ctx: ContextMessageUpdate) {
|
||||
ctx.reply('Send me a sticker');
|
||||
}
|
||||
|
||||
@TelegrafOn('sticker')
|
||||
on(ctx: ContextMessageUpdate) {
|
||||
ctx.reply('👍');
|
||||
}
|
||||
|
||||
@TelegrafHears('hi')
|
||||
hears(ctx: ContextMessageUpdate) {
|
||||
ctx.reply('Hey there');
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```typescript
|
||||
/* bot.config.ts */
|
||||
## Async configuration
|
||||
When you need to pass module options asynchronously instead of statically, use the forRootAsync() method. As with most dynamic modules, Nest provides several techniques to deal with async configuration.
|
||||
|
||||
import { registerAs } from '@nestjs/config'
|
||||
|
||||
interface Config {
|
||||
token: string
|
||||
}
|
||||
|
||||
export default registerAs(
|
||||
'bot',
|
||||
(): Config => ({
|
||||
token: process.env.TELEGRAM_BOT_TOKEN,
|
||||
})
|
||||
)
|
||||
```
|
||||
|
||||
### Telegraf
|
||||
|
||||
#### Telegraf methods usage
|
||||
You can decorate any `Telegraf` method with `@TelegramActionHandler` decorator.
|
||||
One technique is to use a factory function:
|
||||
|
||||
```typescript
|
||||
/* bot.service.ts */
|
||||
|
||||
import { Injectable } from '@nestjs/common'
|
||||
import { TelegrafTelegramService } from 'nestjs-telegraf'
|
||||
import { ContextMessageUpdate } from 'telegraf'
|
||||
|
||||
@Injectable()
|
||||
export class BotService {
|
||||
/* This decorator handle /start command */
|
||||
@TelegramActionHandler({ onStart: true })
|
||||
async onStart(ctx: ContextMessageUpdate) {
|
||||
await ctx.reply('/start command reply')
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
##### Today available actions for decorator:
|
||||
|
||||
- [`onStart`](https://telegraf.js.org/#/?id=start) Handler for /start command.
|
||||
|
||||
- [`command`](https://telegraf.js.org/#/?id=command) Command handling.
|
||||
|
||||
- [`message`](https://telegraf.js.org/#/?id=hears) Registers middleware for handling text messages.
|
||||
|
||||
- [`action`](https://telegraf.js.org/#/?id=action) Registers middleware for handling `callback_data` actions with regular expressions.
|
||||
|
||||
#### Telegraf middlewares usage
|
||||
|
||||
See https://github.com/bukhalo/nestjs-telegraf/issues/7#issuecomment-577582322
|
||||
|
||||
#### Telegraf proxy usage
|
||||
|
||||
```typescript
|
||||
|
||||
/* bot.config.ts */
|
||||
|
||||
import { registerAs } from '@nestjs/config'
|
||||
|
||||
interface Config {
|
||||
token: string
|
||||
socksHost: string
|
||||
socksPort: string | number
|
||||
socksUser: string
|
||||
socksPassword: string
|
||||
}
|
||||
|
||||
export default registerAs(
|
||||
'bot',
|
||||
(): Config => ({
|
||||
token: process.env.TELEGRAM_BOT_TOKEN,
|
||||
socksHost: process.env.TELEGRAM_BOT_SOCKS_HOST,
|
||||
socksPort: process.env.TELEGRAM_BOT_SOCKS_PORT,
|
||||
socksUser: process.env.TELEGRAM_BOT_SOCKS_USER,
|
||||
socksPassword: process.env.TELEGRAM_BOT_SOCKS_PASS,
|
||||
TelegrafModule.forRootAsync({
|
||||
useFactory: () => ({
|
||||
token: 'TELEGRAM_BOT_TOKEN',
|
||||
}),
|
||||
);
|
||||
|
||||
});
|
||||
```
|
||||
|
||||
Like other [factory providers](https://docs.nestjs.com/fundamentals/custom-providers#factory-providers-usefactory), our factory function can be async and can inject dependencies through inject.
|
||||
|
||||
```typescript
|
||||
TelegrafModule.forRootAsync({
|
||||
imports: [ConfigModule],
|
||||
useFactory: async (configService: ConfigService) => ({
|
||||
token: configService.getString('TELEGRAM_BOT_TOKEN'),
|
||||
}),
|
||||
inject: [ConfigService],
|
||||
});
|
||||
```
|
||||
|
||||
/* telegraf-config.service.ts */
|
||||
Alternatively, you can configure the TelegrafModule using a class instead of a factory, as shown below:
|
||||
|
||||
import { Injectable } from '@nestjs/common'
|
||||
import { ConfigService } from '@nestjs/config'
|
||||
import { TelegrafModuleOptions, TelegrafOptionsFactory } from 'nestjs-telegraf'
|
||||
import { SocksProxyAgent } from 'socks-proxy-agent'
|
||||
```typescript
|
||||
TelegrafModule.forRootAsync({
|
||||
useClass: TelegrafConfigService,
|
||||
});
|
||||
```
|
||||
|
||||
The construction above instantiates `TelegrafConfigService` inside `TelegrafModule`, using it to create the required options object. Note that in this example, the `TelegrafConfigService` has to implement the `TelegrafOptionsFactory` interface, as shown below. The `TelegrafModule` will call the `createTelegrafOptions()` method on the instantiated object of the supplied class.
|
||||
|
||||
```typescript
|
||||
@Injectable()
|
||||
export class TelegrafConfigService implements TelegrafOptionsFactory {
|
||||
private agent
|
||||
|
||||
constructor(private readonly configService: ConfigService) {}
|
||||
|
||||
createTelegrafOptions(): TelegrafModuleOptions {
|
||||
const proxyConfig = {
|
||||
host: this.configService.get('bot.socksHost'),
|
||||
port: this.configService.get('bot.socksPort'),
|
||||
userId: this.configService.get('bot.socksUser'),
|
||||
password: this.configService.get('bot.socksPassword'),
|
||||
}
|
||||
this.agent = new SocksProxyAgent(proxyConfig)
|
||||
|
||||
class TelegrafConfigService implements TelegrafOptionsFactory {
|
||||
createMongooseOptions(): TelegrafModuleOptions {
|
||||
return {
|
||||
token: this.configService.get('bot.token'),
|
||||
telegrafOptions: { telegram: { agent: this.agent } },
|
||||
token: 'TELEGRAM_BOT_TOKEN',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Telegram
|
||||
|
||||
#### Telegram methods usage
|
||||
|
||||
Inject `TelegrafTelegramService` from `nestjs-telegraf` package for use [Telegram instance](https://telegraf.js.org/#/?id=telegram) from `telegraf` package.
|
||||
If you want to reuse an existing options provider instead of creating a private copy inside the `TelegrafModule`, use the `useExisting` syntax.
|
||||
|
||||
```typescript
|
||||
/* bot.service.ts */
|
||||
|
||||
import { Injectable } from '@nestjs/common'
|
||||
import { TelegrafTelegramService, TelegramActionHandler } from 'nestjs-telegraf'
|
||||
import { ContextMessageUpdate } from 'telegraf'
|
||||
|
||||
@Injectable()
|
||||
export class BotService {
|
||||
constructor(
|
||||
private readonly telegrafTelegramService: TelegrafTelegramService
|
||||
) {}
|
||||
|
||||
@TelegramActionHandler({ onStart: true })
|
||||
async start(ctx: ContextMessageUpdate) {
|
||||
const me = await this.telegrafTelegramService.getMe()
|
||||
console.log(me)
|
||||
}
|
||||
}
|
||||
TelegrafModule.forRootAsync({
|
||||
imports: [ConfigModule],
|
||||
useExisting: ConfigService,
|
||||
});
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
You can see the basic use of the package in this repository:
|
||||
https://github.com/bukhalo/nestjs-telegraf-sample
|
||||
|
||||
## Support
|
||||
|
||||
Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support).
|
||||
|
@ -1,3 +1,15 @@
|
||||
export * from './pipe-context.decorator'
|
||||
export * from './telegram-action-handler.decorator'
|
||||
export * from './telegram-catch.decorator'
|
||||
export * from './telegraf-use.decorator';
|
||||
export * from './telegraf-on.decorator';
|
||||
export * from './telegraf-hears.decorator';
|
||||
export * from './telegraf-command.decorator';
|
||||
export * from './telegraf-start.decorator';
|
||||
export * from './telegraf-help.decorator';
|
||||
export * from './telegraf-settings.decorator';
|
||||
export * from './telegraf-entity.decorator';
|
||||
export * from './telegraf-mention.decorator';
|
||||
export * from './telegraf-phone.decorator';
|
||||
export * from './telegraf-hashtag.decorator';
|
||||
export * from './telegraf-cashtag.decorator';
|
||||
export * from './telegraf-action.decorator';
|
||||
export * from './telegraf-inline-query.decorator';
|
||||
export * from './telegraf-game-query.decorator';
|
||||
|
@ -1,18 +0,0 @@
|
||||
import { Type } from '@nestjs/common'
|
||||
import { ContextTransformer } from '../interfaces'
|
||||
import { addHandlerToStore } from './'
|
||||
|
||||
export const PipeContext = <T>(transform: Type<ContextTransformer<T>>) => (
|
||||
target: Object,
|
||||
propertyKey: string,
|
||||
parameterIndex: number,
|
||||
) => {
|
||||
addHandlerToStore(target, propertyKey, {
|
||||
transformations: [
|
||||
{
|
||||
index: parameterIndex,
|
||||
transform,
|
||||
},
|
||||
],
|
||||
})
|
||||
}
|
21
lib/decorators/telegraf-action.decorator.ts
Normal file
21
lib/decorators/telegraf-action.decorator.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { SetMetadata } from '@nestjs/common';
|
||||
import { DECORATORS } from '../telegraf.constants';
|
||||
import { HearsTriggers } from 'telegraf';
|
||||
|
||||
export type TelegrafActionTriggers = HearsTriggers;
|
||||
|
||||
export interface TelegrafActionMetadata {
|
||||
triggers: TelegrafActionTriggers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers middleware for handling callback_data actions with regular expressions.
|
||||
* @param triggers Triggers
|
||||
*
|
||||
* https://telegraf.js.org/#/?id=action
|
||||
*/
|
||||
export function TelegrafAction(
|
||||
triggers: TelegrafActionTriggers,
|
||||
): MethodDecorator {
|
||||
return SetMetadata(DECORATORS.ACTION, { triggers });
|
||||
}
|
20
lib/decorators/telegraf-cashtag.decorator.ts
Normal file
20
lib/decorators/telegraf-cashtag.decorator.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { SetMetadata } from '@nestjs/common';
|
||||
import { DECORATORS } from '../telegraf.constants';
|
||||
|
||||
export type TelegrafCashtagCashtag = string | string[];
|
||||
|
||||
export interface TelegrafCashtagMetadata {
|
||||
cashtag: TelegrafCashtagCashtag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cashtag handling.
|
||||
* @param cashtag Cashtag
|
||||
*
|
||||
* https://telegraf.js.org/#/?id=cashtag
|
||||
*/
|
||||
export function TelegrafCashtag(
|
||||
cashtag: TelegrafCashtagCashtag,
|
||||
): MethodDecorator {
|
||||
return SetMetadata(DECORATORS.CASHTAG, { cashtag });
|
||||
}
|
20
lib/decorators/telegraf-command.decorator.ts
Normal file
20
lib/decorators/telegraf-command.decorator.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { SetMetadata } from '@nestjs/common';
|
||||
import { DECORATORS } from '../telegraf.constants';
|
||||
|
||||
export type TelegrafCommandCommands = string | string[];
|
||||
|
||||
export interface TelegrafCommandMetadata {
|
||||
commands: TelegrafCommandCommands;
|
||||
}
|
||||
|
||||
/**
|
||||
* Command handling.
|
||||
* @param commands Commands
|
||||
*
|
||||
* https://telegraf.js.org/#/?id=command
|
||||
*/
|
||||
export function TelegrafCommand(
|
||||
commands: TelegrafCommandCommands,
|
||||
): MethodDecorator {
|
||||
return SetMetadata(DECORATORS.COMMAND, { commands });
|
||||
}
|
23
lib/decorators/telegraf-entity.decorator.ts
Normal file
23
lib/decorators/telegraf-entity.decorator.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { SetMetadata } from '@nestjs/common';
|
||||
import { DECORATORS } from '../telegraf.constants';
|
||||
|
||||
export type TelegrafEntityEntity =
|
||||
| string
|
||||
| string[]
|
||||
| RegExp
|
||||
| RegExp[]
|
||||
| Function;
|
||||
|
||||
export interface TelegrafEntityMetadata {
|
||||
entity: TelegrafEntityEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Entity handling.
|
||||
* @param entity Entity name
|
||||
*
|
||||
* https://telegraf.js.org/#/?id=entity
|
||||
*/
|
||||
export function TelegrafEntity(entity: TelegrafEntityEntity): MethodDecorator {
|
||||
return SetMetadata(DECORATORS.ENTITY, { entity });
|
||||
}
|
11
lib/decorators/telegraf-game-query.decorator.ts
Normal file
11
lib/decorators/telegraf-game-query.decorator.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { SetMetadata } from '@nestjs/common';
|
||||
import { DECORATORS } from '../telegraf.constants';
|
||||
|
||||
/**
|
||||
* Registers middleware for handling callback_data actions with game query.
|
||||
*
|
||||
* https://telegraf.js.org/#/?id=inlinequery
|
||||
*/
|
||||
export function TelegrafGameQuery(): MethodDecorator {
|
||||
return SetMetadata(DECORATORS.GAME_QUERY, {});
|
||||
}
|
20
lib/decorators/telegraf-hashtag.decorator.ts
Normal file
20
lib/decorators/telegraf-hashtag.decorator.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { SetMetadata } from '@nestjs/common';
|
||||
import { DECORATORS } from '../telegraf.constants';
|
||||
|
||||
export type TelegrafHashtagHashtag = string | string[];
|
||||
|
||||
export interface TelegrafHashtagMetadata {
|
||||
hashtag: TelegrafHashtagHashtag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hashtag handling.
|
||||
* @param hashtag Hashtag
|
||||
*
|
||||
* https://telegraf.js.org/#/?id=hashtag
|
||||
*/
|
||||
export function TelegrafHashtag(
|
||||
hashtag: TelegrafHashtagHashtag,
|
||||
): MethodDecorator {
|
||||
return SetMetadata(DECORATORS.HASHTAG, { hashtag });
|
||||
}
|
21
lib/decorators/telegraf-hears.decorator.ts
Normal file
21
lib/decorators/telegraf-hears.decorator.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { SetMetadata } from '@nestjs/common';
|
||||
import { DECORATORS } from '../telegraf.constants';
|
||||
import { HearsTriggers } from 'telegraf';
|
||||
|
||||
export type TelegrafHearsTriggers = HearsTriggers;
|
||||
|
||||
export interface TelegrafHearsMetadata {
|
||||
triggers: TelegrafHearsTriggers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers middleware for handling text messages.
|
||||
* @param triggers Triggers
|
||||
*
|
||||
* https://telegraf.js.org/#/?id=hears
|
||||
*/
|
||||
export function TelegrafHears(
|
||||
triggers: TelegrafHearsTriggers,
|
||||
): MethodDecorator {
|
||||
return SetMetadata(DECORATORS.HEARS, { triggers: triggers });
|
||||
}
|
11
lib/decorators/telegraf-help.decorator.ts
Normal file
11
lib/decorators/telegraf-help.decorator.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { SetMetadata } from '@nestjs/common';
|
||||
import { DECORATORS } from '../telegraf.constants';
|
||||
|
||||
/**
|
||||
* Handler for /help command.
|
||||
*
|
||||
* https://telegraf.js.org/#/?id=help
|
||||
*/
|
||||
export function TelegrafHelp(): MethodDecorator {
|
||||
return SetMetadata(DECORATORS.HELP, {});
|
||||
}
|
20
lib/decorators/telegraf-inline-query.decorator.ts
Normal file
20
lib/decorators/telegraf-inline-query.decorator.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { SetMetadata } from '@nestjs/common';
|
||||
import { DECORATORS } from '../telegraf.constants';
|
||||
|
||||
export type TelegrafInlineQueryTriggers = string | string[] | RegExp | RegExp[];
|
||||
|
||||
export interface TelegrafInlineQueryMetadata {
|
||||
triggers: TelegrafInlineQueryTriggers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers middleware for handling inline_query actions with regular expressions.
|
||||
* @param triggers Triggers
|
||||
*
|
||||
* https://telegraf.js.org/#/?id=inlinequery
|
||||
*/
|
||||
export function TelegrafInlineQuery(
|
||||
triggers: TelegrafInlineQueryTriggers,
|
||||
): MethodDecorator {
|
||||
return SetMetadata(DECORATORS.INLINE_QUERY, { triggers });
|
||||
}
|
20
lib/decorators/telegraf-mention.decorator.ts
Normal file
20
lib/decorators/telegraf-mention.decorator.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { SetMetadata } from '@nestjs/common';
|
||||
import { DECORATORS } from '../telegraf.constants';
|
||||
|
||||
export type TelegrafMentionUsername = string | string[];
|
||||
|
||||
export interface TelegrafMentionMetadata {
|
||||
username: TelegrafMentionUsername;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mention handling.
|
||||
* @param username Username
|
||||
*
|
||||
* https://telegraf.js.org/#/?id=mention
|
||||
*/
|
||||
export function TelegrafMention(
|
||||
username: TelegrafMentionUsername,
|
||||
): MethodDecorator {
|
||||
return SetMetadata(DECORATORS.MENTION, { username });
|
||||
}
|
25
lib/decorators/telegraf-on.decorator.ts
Normal file
25
lib/decorators/telegraf-on.decorator.ts
Normal file
@ -0,0 +1,25 @@
|
||||
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 TelegrafOnMetadata {
|
||||
updateTypes: TelegrafOnUpdateTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers middleware for provided update type.
|
||||
* @param updateTypes Update type
|
||||
*
|
||||
* https://telegraf.js.org/#/?id=on
|
||||
*/
|
||||
export function TelegrafOn(
|
||||
updateTypes: TelegrafOnUpdateTypes,
|
||||
): MethodDecorator {
|
||||
return SetMetadata(DECORATORS.ON, { updateTypes: updateTypes });
|
||||
}
|
18
lib/decorators/telegraf-phone.decorator.ts
Normal file
18
lib/decorators/telegraf-phone.decorator.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { SetMetadata } from '@nestjs/common';
|
||||
import { DECORATORS } from '../telegraf.constants';
|
||||
|
||||
export type TelegrafPhonePhone = string | string[];
|
||||
|
||||
export interface TelegrafPhoneMetadata {
|
||||
phone: TelegrafPhonePhone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Phone number handling.
|
||||
* @param phone Phone number
|
||||
*
|
||||
* https://telegraf.js.org/#/?id=phone
|
||||
*/
|
||||
export function TelegrafPhone(phone: TelegrafPhonePhone): MethodDecorator {
|
||||
return SetMetadata(DECORATORS.PHONE, { phone });
|
||||
}
|
11
lib/decorators/telegraf-settings.decorator.ts
Normal file
11
lib/decorators/telegraf-settings.decorator.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { SetMetadata } from '@nestjs/common';
|
||||
import { DECORATORS } from '../telegraf.constants';
|
||||
|
||||
/**
|
||||
* Handler for /settings command.
|
||||
*
|
||||
* https://telegraf.js.org/#/?id=settings
|
||||
*/
|
||||
export function TelegrafSettings(): MethodDecorator {
|
||||
return SetMetadata(DECORATORS.SETTINGS, {});
|
||||
}
|
11
lib/decorators/telegraf-start.decorator.ts
Normal file
11
lib/decorators/telegraf-start.decorator.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { SetMetadata } from '@nestjs/common';
|
||||
import { DECORATORS } from '../telegraf.constants';
|
||||
|
||||
/**
|
||||
* Handler for /start command.
|
||||
*
|
||||
* https://telegraf.js.org/#/?id=start
|
||||
*/
|
||||
export function TelegrafStart(): MethodDecorator {
|
||||
return SetMetadata(DECORATORS.START, {});
|
||||
}
|
11
lib/decorators/telegraf-use.decorator.ts
Normal file
11
lib/decorators/telegraf-use.decorator.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { SetMetadata } from '@nestjs/common';
|
||||
import { DECORATORS } from '../telegraf.constants';
|
||||
|
||||
/**
|
||||
* Registers a middleware.
|
||||
*
|
||||
* https://telegraf.js.org/#/?id=use
|
||||
*/
|
||||
export function TelegrafUse(): MethodDecorator {
|
||||
return SetMetadata(DECORATORS.USE, {});
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
import { HandleParameters } from '../interfaces'
|
||||
|
||||
type Decorator = (
|
||||
params: HandleParameters,
|
||||
) => (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void
|
||||
|
||||
type HandlerDecorator = Decorator & {
|
||||
handlers?: Map<any, Map<string, HandleParameters>>
|
||||
}
|
||||
|
||||
export const TelegramActionHandler: HandlerDecorator = (
|
||||
parameters: HandleParameters,
|
||||
) => (target: any, propertyKey: string) => {
|
||||
// eslint-disable-next-line no-use-before-define
|
||||
addHandlerToStore(target, propertyKey, parameters)
|
||||
}
|
||||
|
||||
export const addHandlerToStore = (
|
||||
instance: Object,
|
||||
name: string,
|
||||
config: HandleParameters,
|
||||
) => {
|
||||
const handlerClass = instance.constructor
|
||||
|
||||
if (!TelegramActionHandler.handlers) {
|
||||
TelegramActionHandler.handlers = new Map()
|
||||
}
|
||||
|
||||
if (!TelegramActionHandler.handlers.get(handlerClass)) {
|
||||
TelegramActionHandler.handlers.set(handlerClass, new Map())
|
||||
}
|
||||
|
||||
const oldParameters =
|
||||
TelegramActionHandler.handlers.get(handlerClass).get(name) || {}
|
||||
|
||||
TelegramActionHandler.handlers.get(handlerClass).set(name, {
|
||||
...oldParameters,
|
||||
...config,
|
||||
transformations: [
|
||||
...(oldParameters.transformations || []),
|
||||
...(config.transformations || []),
|
||||
],
|
||||
})
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
import { Type } from '@nestjs/common'
|
||||
import { TelegramErrorHandler } from '../interfaces'
|
||||
|
||||
type Decorator = (error: any) => ClassDecorator
|
||||
|
||||
type HandlerDecorator = Decorator & {
|
||||
handlers?: Map<Error, Type<TelegramErrorHandler>>
|
||||
}
|
||||
|
||||
export const TelegramCatch: HandlerDecorator = error => target => {
|
||||
if (!TelegramCatch.handlers) {
|
||||
TelegramCatch.handlers = new Map()
|
||||
}
|
||||
|
||||
TelegramCatch.handlers.set(error, target as any)
|
||||
|
||||
return target
|
||||
}
|
@ -1 +0,0 @@
|
||||
export * from './invalid-configuration.exeption'
|
@ -1,10 +0,0 @@
|
||||
export class InvalidConfigurationException extends Error {
|
||||
public constructor(
|
||||
public readonly invalidField,
|
||||
public readonly invalidCause,
|
||||
) {
|
||||
super(
|
||||
`Options validation failed, "${invalidField}" invalid — ${invalidCause}`,
|
||||
)
|
||||
}
|
||||
}
|
@ -1,5 +1,3 @@
|
||||
export * from './telegraf.module'
|
||||
export * from './interfaces'
|
||||
export * from './decorators'
|
||||
export * from './telegraf.service'
|
||||
export * from './telegraf-telegram.service'
|
||||
export * from './telegraf.module';
|
||||
export * from './interfaces';
|
||||
export * from './decorators';
|
||||
|
@ -1,5 +0,0 @@
|
||||
import { ContextMessageUpdate } from 'telegraf'
|
||||
|
||||
export interface ContextTransformer<T = any> {
|
||||
transform: (ctx: ContextMessageUpdate) => Promise<T>
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
import { ContextTransformer } from './'
|
||||
import { HearsTriggers } from 'telegraf'
|
||||
import { UpdateType, MessageSubTypes } from 'telegraf/typings/telegram-types'
|
||||
import { Type } from '@nestjs/common'
|
||||
|
||||
interface ArgumentTransformation {
|
||||
index: number
|
||||
transform: Type<ContextTransformer>
|
||||
}
|
||||
|
||||
export interface HandleParameters {
|
||||
onStart?: boolean
|
||||
on?: UpdateType | UpdateType[] | MessageSubTypes | MessageSubTypes[]
|
||||
command?: string
|
||||
message?: string | RegExp
|
||||
action?: HearsTriggers
|
||||
transformations?: ArgumentTransformation[]
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
import { HandleParameters } from './'
|
||||
|
||||
export interface Handler {
|
||||
handle: (...args: any[]) => Promise<void>
|
||||
config: HandleParameters
|
||||
}
|
@ -1,5 +1,2 @@
|
||||
export * from './telegraf-options.interface'
|
||||
export * from './handler.interface'
|
||||
export * from './handle-parameters.interface'
|
||||
export * from './telegram-error-handler.interface'
|
||||
export * from './context-transformer.interface'
|
||||
export { ContextMessageUpdate } from 'telegraf';
|
||||
export * from './telegraf-options.interface';
|
||||
|
@ -1,22 +1,21 @@
|
||||
import { ModuleMetadata, Type } from '@nestjs/common/interfaces'
|
||||
import { TelegrafOptions } from 'telegraf'
|
||||
import { ModuleMetadata, Type } from '@nestjs/common/interfaces';
|
||||
import { TelegrafOptions } from 'telegraf';
|
||||
|
||||
export interface TelegrafModuleOptions {
|
||||
token: string
|
||||
sitePublicUrl?: string
|
||||
telegrafOptions?: TelegrafOptions
|
||||
token: string;
|
||||
options?: TelegrafOptions;
|
||||
}
|
||||
|
||||
export interface TelegrafOptionsFactory {
|
||||
createTelegrafOptions(): TelegrafModuleOptions
|
||||
createTelegrafOptions(): TelegrafModuleOptions;
|
||||
}
|
||||
|
||||
export interface TelegrafModuleAsyncOptions
|
||||
extends Pick<ModuleMetadata, 'imports'> {
|
||||
useExisting?: Type<TelegrafOptionsFactory>
|
||||
useClass?: Type<TelegrafOptionsFactory>
|
||||
useExisting?: Type<TelegrafOptionsFactory>;
|
||||
useClass?: Type<TelegrafOptionsFactory>;
|
||||
useFactory?: (
|
||||
...args: any[]
|
||||
) => Promise<TelegrafModuleOptions> | TelegrafModuleOptions
|
||||
inject?: any[]
|
||||
) => Promise<TelegrafModuleOptions> | TelegrafModuleOptions;
|
||||
inject?: any[];
|
||||
}
|
||||
|
@ -1,5 +0,0 @@
|
||||
import { ContextMessageUpdate } from 'telegraf'
|
||||
|
||||
export interface TelegramErrorHandler<E = any> {
|
||||
catch(ctx: ContextMessageUpdate, error: E): Promise<void>
|
||||
}
|
91
lib/telegraf-core.module.ts
Normal file
91
lib/telegraf-core.module.ts
Normal file
@ -0,0 +1,91 @@
|
||||
import { Module, DynamicModule, Provider, Type } from '@nestjs/common';
|
||||
import {
|
||||
TelegrafModuleOptions,
|
||||
TelegrafModuleAsyncOptions,
|
||||
TelegrafOptionsFactory,
|
||||
} from './interfaces';
|
||||
import {
|
||||
TELEGRAF_MODULE_OPTIONS,
|
||||
TELEGRAF_PROVIDER,
|
||||
} from './telegraf.constants';
|
||||
import { TelegrafMetadataAccessor } from './telegraf-metadata.accessor';
|
||||
import { TelegrafExplorer } from './telegraf.explorer';
|
||||
import { DiscoveryModule } from '@nestjs/core';
|
||||
import { TelegrafProvider } from './telegraf.provider';
|
||||
|
||||
@Module({
|
||||
imports: [DiscoveryModule],
|
||||
providers: [TelegrafMetadataAccessor, TelegrafExplorer],
|
||||
})
|
||||
export class TelegrafCoreModule {
|
||||
public static forRoot(options: TelegrafModuleOptions): DynamicModule {
|
||||
const telegrafProvider = {
|
||||
provide: TELEGRAF_PROVIDER,
|
||||
useClass: TelegrafProvider,
|
||||
inject: [TELEGRAF_MODULE_OPTIONS],
|
||||
};
|
||||
return {
|
||||
module: TelegrafCoreModule,
|
||||
providers: [
|
||||
{ provide: TELEGRAF_MODULE_OPTIONS, useValue: options },
|
||||
telegrafProvider,
|
||||
],
|
||||
exports: [telegrafProvider],
|
||||
};
|
||||
}
|
||||
|
||||
public static forRootAsync(
|
||||
options: TelegrafModuleAsyncOptions,
|
||||
): DynamicModule {
|
||||
const telegrafProvider = {
|
||||
provide: TELEGRAF_PROVIDER,
|
||||
useClass: TelegrafProvider,
|
||||
inject: [TELEGRAF_MODULE_OPTIONS],
|
||||
};
|
||||
const asyncProviders = this.createAsyncProviders(options);
|
||||
return {
|
||||
module: TelegrafCoreModule,
|
||||
imports: options.imports,
|
||||
providers: [...asyncProviders, telegrafProvider],
|
||||
exports: [telegrafProvider],
|
||||
};
|
||||
}
|
||||
|
||||
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,
|
||||
};
|
||||
}
|
||||
}
|
186
lib/telegraf-metadata.accessor.ts
Normal file
186
lib/telegraf-metadata.accessor.ts
Normal file
@ -0,0 +1,186 @@
|
||||
import { Injectable, Type } from '@nestjs/common';
|
||||
import { Reflector } from '@nestjs/core';
|
||||
import {
|
||||
TelegrafActionMetadata,
|
||||
TelegrafCashtagMetadata,
|
||||
TelegrafCommandMetadata,
|
||||
TelegrafEntityMetadata,
|
||||
TelegrafHashtagMetadata,
|
||||
TelegrafHearsMetadata,
|
||||
TelegrafInlineQueryMetadata,
|
||||
TelegrafMentionMetadata,
|
||||
TelegrafOnMetadata,
|
||||
TelegrafPhoneMetadata,
|
||||
TelegrafStart,
|
||||
} from './decorators';
|
||||
import { DECORATORS } from './telegraf.constants';
|
||||
|
||||
@Injectable()
|
||||
export class TelegrafMetadataAccessor {
|
||||
constructor(private readonly reflector: Reflector) {}
|
||||
|
||||
isTelegrafUse(target: Type<any> | Function): boolean {
|
||||
if (!target) {
|
||||
return false;
|
||||
}
|
||||
return !!this.reflector.get(DECORATORS.USE, target);
|
||||
}
|
||||
|
||||
isTelegrafOn(target: Type<any> | Function): boolean {
|
||||
if (!target) {
|
||||
return false;
|
||||
}
|
||||
return !!this.reflector.get(DECORATORS.ON, target);
|
||||
}
|
||||
|
||||
getTelegrafOnMetadata(
|
||||
target: Type<any> | Function,
|
||||
): TelegrafOnMetadata | undefined {
|
||||
return this.reflector.get(DECORATORS.ON, target);
|
||||
}
|
||||
|
||||
isTelegrafHears(target: Type<any> | Function): boolean {
|
||||
if (!target) {
|
||||
return false;
|
||||
}
|
||||
return !!this.reflector.get(DECORATORS.HEARS, target);
|
||||
}
|
||||
|
||||
getTelegrafHearsMetadata(
|
||||
target: Type<any> | Function,
|
||||
): TelegrafHearsMetadata | undefined {
|
||||
return this.reflector.get(DECORATORS.HEARS, target);
|
||||
}
|
||||
|
||||
isTelegrafCommand(target: Type<any> | Function): boolean {
|
||||
if (!target) {
|
||||
return false;
|
||||
}
|
||||
return !!this.reflector.get(DECORATORS.COMMAND, target);
|
||||
}
|
||||
|
||||
getTelegrafCommandMetadata(
|
||||
target: Type<any> | Function,
|
||||
): TelegrafCommandMetadata | undefined {
|
||||
return this.reflector.get(DECORATORS.COMMAND, target);
|
||||
}
|
||||
|
||||
isTelegrafStart(target: Type<any> | Function): boolean {
|
||||
if (!target) {
|
||||
return false;
|
||||
}
|
||||
return !!this.reflector.get(DECORATORS.START, target);
|
||||
}
|
||||
|
||||
isTelegrafHelp(target: Type<any> | Function): boolean {
|
||||
if (!target) {
|
||||
return false;
|
||||
}
|
||||
return !!this.reflector.get(DECORATORS.HELP, target);
|
||||
}
|
||||
|
||||
isTelegrafSettings(target: Type<any> | Function): boolean {
|
||||
if (!target) {
|
||||
return false;
|
||||
}
|
||||
return !!this.reflector.get(DECORATORS.SETTINGS, target);
|
||||
}
|
||||
|
||||
isTelegrafEntity(target: Type<any> | Function): boolean {
|
||||
if (!target) {
|
||||
return false;
|
||||
}
|
||||
return !!this.reflector.get(DECORATORS.ENTITY, target);
|
||||
}
|
||||
|
||||
getTelegrafEntityMetadata(
|
||||
target: Type<any> | Function,
|
||||
): TelegrafEntityMetadata | undefined {
|
||||
return this.reflector.get(DECORATORS.ENTITY, target);
|
||||
}
|
||||
|
||||
isTelegrafMention(target: Type<any> | Function): boolean {
|
||||
if (!target) {
|
||||
return false;
|
||||
}
|
||||
return !!this.reflector.get(DECORATORS.MENTION, target);
|
||||
}
|
||||
|
||||
getTelegrafMentionMetadata(
|
||||
target: Type<any> | Function,
|
||||
): TelegrafMentionMetadata | undefined {
|
||||
return this.reflector.get(DECORATORS.MENTION, target);
|
||||
}
|
||||
|
||||
isTelegrafPhone(target: Type<any> | Function): boolean {
|
||||
if (!target) {
|
||||
return false;
|
||||
}
|
||||
return !!this.reflector.get(DECORATORS.PHONE, target);
|
||||
}
|
||||
|
||||
getTelegrafPhoneMetadata(
|
||||
target: Type<any> | Function,
|
||||
): TelegrafPhoneMetadata | undefined {
|
||||
return this.reflector.get(DECORATORS.PHONE, target);
|
||||
}
|
||||
|
||||
isTelegrafHashtag(target: Type<any> | Function): boolean {
|
||||
if (!target) {
|
||||
return false;
|
||||
}
|
||||
return !!this.reflector.get(DECORATORS.HASHTAG, target);
|
||||
}
|
||||
|
||||
getTelegrafHashtagMetadata(
|
||||
target: Type<any> | Function,
|
||||
): TelegrafHashtagMetadata | undefined {
|
||||
return this.reflector.get(DECORATORS.HASHTAG, target);
|
||||
}
|
||||
|
||||
isTelegrafCashtag(target: Type<any> | Function): boolean {
|
||||
if (!target) {
|
||||
return false;
|
||||
}
|
||||
return !!this.reflector.get(DECORATORS.CASHTAG, target);
|
||||
}
|
||||
|
||||
getTelegrafCashtagMetadata(
|
||||
target: Type<any> | Function,
|
||||
): TelegrafCashtagMetadata | undefined {
|
||||
return this.reflector.get(DECORATORS.CASHTAG, target);
|
||||
}
|
||||
|
||||
isTelegrafAction(target: Type<any> | Function): boolean {
|
||||
if (!target) {
|
||||
return false;
|
||||
}
|
||||
return !!this.reflector.get(DECORATORS.ACTION, target);
|
||||
}
|
||||
|
||||
getTelegrafActionMetadata(
|
||||
target: Type<any> | Function,
|
||||
): TelegrafActionMetadata | undefined {
|
||||
return this.reflector.get(DECORATORS.ACTION, target);
|
||||
}
|
||||
|
||||
isTelegrafInlineQuery(target: Type<any> | Function): boolean {
|
||||
if (!target) {
|
||||
return false;
|
||||
}
|
||||
return !!this.reflector.get(DECORATORS.INLINE_QUERY, target);
|
||||
}
|
||||
|
||||
getTelegrafInlineQueryMetadata(
|
||||
target: Type<any> | Function,
|
||||
): TelegrafInlineQueryMetadata | undefined {
|
||||
return this.reflector.get(DECORATORS.INLINE_QUERY, target);
|
||||
}
|
||||
|
||||
isTelegrafGameQuery(target: Type<any> | Function): boolean {
|
||||
if (!target) {
|
||||
return false;
|
||||
}
|
||||
return !!this.reflector.get(DECORATORS.GAME_QUERY, target);
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
import { Injectable, Inject } from '@nestjs/common';
|
||||
const Telegram = require('telegraf/telegram');
|
||||
import { Telegram as TelegramClient } from 'telegraf';
|
||||
|
||||
import { TELEGRAF_MODULE_OPTIONS } from './telegraf.constants';
|
||||
import { TelegrafModuleOptions } from './interfaces';
|
||||
|
||||
@Injectable()
|
||||
export class TelegrafTelegramService extends TelegramClient {
|
||||
constructor(@Inject(TELEGRAF_MODULE_OPTIONS) options: TelegrafModuleOptions) {
|
||||
super(options.token, {});
|
||||
}
|
||||
}
|
@ -1,2 +1,21 @@
|
||||
export const TELEGRAF_MODULE_OPTIONS = 'TELEGRAF_MODULE_OPTIONS'
|
||||
export const TokenInjectionToken = Symbol('TokenInjectionToken')
|
||||
export const TELEGRAF_MODULE_OPTIONS = 'TELEGRAF_MODULE_OPTIONS';
|
||||
export const TELEGRAF_PROVIDER = 'TELEGRAF_PROVIDER';
|
||||
|
||||
export const DECORATORS_PREFIX = 'TELEGRAF';
|
||||
export const DECORATORS = {
|
||||
USE: `${DECORATORS_PREFIX}/USE`,
|
||||
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`,
|
||||
};
|
||||
|
258
lib/telegraf.explorer.ts
Normal file
258
lib/telegraf.explorer.ts
Normal file
@ -0,0 +1,258 @@
|
||||
import { Injectable, OnModuleInit } from '@nestjs/common';
|
||||
import { DiscoveryService, ModuleRef } from '@nestjs/core';
|
||||
import { InstanceWrapper } from '@nestjs/core/injector/instance-wrapper';
|
||||
import { MetadataScanner } from '@nestjs/core/metadata-scanner';
|
||||
import Telegraf from 'telegraf';
|
||||
import { TelegrafMetadataAccessor } from './telegraf-metadata.accessor';
|
||||
import { TelegrafProvider } from './telegraf.provider';
|
||||
import { TELEGRAF_PROVIDER } from './telegraf.constants';
|
||||
import { ContextMessageUpdate } from 'telegraf';
|
||||
import {
|
||||
TelegrafActionMetadata,
|
||||
TelegrafCashtagMetadata,
|
||||
TelegrafCommandMetadata,
|
||||
TelegrafEntityMetadata,
|
||||
TelegrafHashtagMetadata,
|
||||
TelegrafHearsMetadata,
|
||||
TelegrafInlineQueryMetadata,
|
||||
TelegrafMentionMetadata,
|
||||
TelegrafOnMetadata,
|
||||
TelegrafPhoneMetadata,
|
||||
} from './decorators';
|
||||
|
||||
@Injectable()
|
||||
export class TelegrafExplorer implements OnModuleInit {
|
||||
constructor(
|
||||
private readonly moduleRef: ModuleRef,
|
||||
private readonly discoveryService: DiscoveryService,
|
||||
private readonly metadataAccessor: TelegrafMetadataAccessor,
|
||||
private readonly metadataScanner: MetadataScanner,
|
||||
) {}
|
||||
|
||||
onModuleInit() {
|
||||
this.explore();
|
||||
}
|
||||
|
||||
explore() {
|
||||
const providers: InstanceWrapper[] = this.discoveryService.getProviders();
|
||||
providers.forEach((wrapper: InstanceWrapper) => {
|
||||
const { instance } = wrapper;
|
||||
|
||||
if (!instance) {
|
||||
return;
|
||||
}
|
||||
|
||||
const telegraf = this.moduleRef.get<TelegrafProvider<any>>(
|
||||
TELEGRAF_PROVIDER,
|
||||
{ strict: false },
|
||||
);
|
||||
|
||||
this.metadataScanner.scanFromPrototype(
|
||||
instance,
|
||||
Object.getPrototypeOf(instance),
|
||||
(key: string) => {
|
||||
if (this.metadataAccessor.isTelegrafUse(instance[key])) {
|
||||
this.handleTelegrafUse(instance, key, telegraf);
|
||||
} else if (this.metadataAccessor.isTelegrafOn(instance[key])) {
|
||||
const metadata = this.metadataAccessor.getTelegrafOnMetadata(
|
||||
instance[key],
|
||||
);
|
||||
this.handleTelegrafOn(instance, key, telegraf, metadata);
|
||||
} else if (this.metadataAccessor.isTelegrafHears(instance[key])) {
|
||||
const metadata = this.metadataAccessor.getTelegrafHearsMetadata(
|
||||
instance[key],
|
||||
);
|
||||
this.handleTelegrafHears(instance, key, telegraf, metadata);
|
||||
} else if (this.metadataAccessor.isTelegrafCommand(instance[key])) {
|
||||
const metadata = this.metadataAccessor.getTelegrafCommandMetadata(
|
||||
instance[key],
|
||||
);
|
||||
this.handleTelegrafCommand(instance, key, telegraf, metadata);
|
||||
} else if (this.metadataAccessor.isTelegrafStart(instance[key])) {
|
||||
this.handleTelegrafStart(instance, key, telegraf);
|
||||
} else if (this.metadataAccessor.isTelegrafHelp(instance[key])) {
|
||||
this.handleTelegrafHelp(instance, key, telegraf);
|
||||
} else if (this.metadataAccessor.isTelegrafSettings(instance[key])) {
|
||||
this.handleTelegrafSettings(instance, key, telegraf);
|
||||
} else if (this.metadataAccessor.isTelegrafEntity(instance[key])) {
|
||||
const metadata = this.metadataAccessor.getTelegrafEntityMetadata(
|
||||
instance[key],
|
||||
);
|
||||
this.handleTelegrafEntity(instance, key, telegraf, metadata);
|
||||
} else if (this.metadataAccessor.isTelegrafMention(instance[key])) {
|
||||
const metadata = this.metadataAccessor.getTelegrafMentionMetadata(
|
||||
instance[key],
|
||||
);
|
||||
this.handleTelegrafMention(instance, key, telegraf, metadata);
|
||||
} else if (this.metadataAccessor.isTelegrafPhone(instance[key])) {
|
||||
const metadata = this.metadataAccessor.getTelegrafPhoneMetadata(
|
||||
instance[key],
|
||||
);
|
||||
this.handleTelegrafPhone(instance, key, telegraf, metadata);
|
||||
} else if (this.metadataAccessor.isTelegrafHashtag(instance[key])) {
|
||||
const metadata = this.metadataAccessor.getTelegrafHashtagMetadata(
|
||||
instance[key],
|
||||
);
|
||||
this.handleTelegrafHashtag(instance, key, telegraf, metadata);
|
||||
} else if (this.metadataAccessor.isTelegrafCashtag(instance[key])) {
|
||||
const metadata = this.metadataAccessor.getTelegrafCashtagMetadata(
|
||||
instance[key],
|
||||
);
|
||||
this.handleTelegrafCashtag(instance, key, telegraf, metadata);
|
||||
} else if (this.metadataAccessor.isTelegrafAction(instance[key])) {
|
||||
const metadata = this.metadataAccessor.getTelegrafActionMetadata(
|
||||
instance[key],
|
||||
);
|
||||
this.handleTelegrafAction(instance, key, telegraf, metadata);
|
||||
} else if (
|
||||
this.metadataAccessor.isTelegrafInlineQuery(instance[key])
|
||||
) {
|
||||
const metadata = this.metadataAccessor.getTelegrafInlineQueryMetadata(
|
||||
instance[key],
|
||||
);
|
||||
this.handleTelegrafInlineQuery(instance, key, telegraf, metadata);
|
||||
} else if (this.metadataAccessor.isTelegrafGameQuery(instance[key])) {
|
||||
this.handleTelegrafGameQuery(instance, key, telegraf);
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
handleTelegrafUse(
|
||||
instance: object,
|
||||
key: string,
|
||||
telegraf: Telegraf<ContextMessageUpdate>,
|
||||
) {
|
||||
telegraf.use(instance[key].bind(instance));
|
||||
}
|
||||
|
||||
handleTelegrafOn(
|
||||
instance: object,
|
||||
key: string,
|
||||
telegraf: Telegraf<ContextMessageUpdate>,
|
||||
metadata: TelegrafOnMetadata,
|
||||
) {
|
||||
telegraf.on(metadata.updateTypes, instance[key].bind(instance));
|
||||
}
|
||||
|
||||
handleTelegrafHears(
|
||||
instance: object,
|
||||
key: string,
|
||||
telegraf: Telegraf<ContextMessageUpdate>,
|
||||
metadata: TelegrafHearsMetadata,
|
||||
) {
|
||||
telegraf.hears(metadata.triggers, instance[key].bind(instance));
|
||||
}
|
||||
|
||||
handleTelegrafCommand(
|
||||
instance: object,
|
||||
key: string,
|
||||
telegraf: Telegraf<ContextMessageUpdate>,
|
||||
metadata: TelegrafCommandMetadata,
|
||||
) {
|
||||
telegraf.command(metadata.commands, instance[key].bind(instance));
|
||||
}
|
||||
|
||||
handleTelegrafStart(
|
||||
instance: object,
|
||||
key: string,
|
||||
telegraf: Telegraf<ContextMessageUpdate>,
|
||||
) {
|
||||
telegraf.start(instance[key].bind(instance));
|
||||
}
|
||||
|
||||
handleTelegrafHelp(
|
||||
instance: object,
|
||||
key: string,
|
||||
telegraf: Telegraf<ContextMessageUpdate>,
|
||||
) {
|
||||
telegraf.help(instance[key].bind(instance));
|
||||
}
|
||||
|
||||
handleTelegrafSettings(
|
||||
instance: object,
|
||||
key: string,
|
||||
telegraf: Telegraf<ContextMessageUpdate>,
|
||||
) {
|
||||
// @ts-ignore
|
||||
telegraf.settings(instance[key].bind(instance));
|
||||
}
|
||||
|
||||
handleTelegrafEntity(
|
||||
instance: object,
|
||||
key: string,
|
||||
telegraf: Telegraf<ContextMessageUpdate>,
|
||||
metadata: TelegrafEntityMetadata,
|
||||
) {
|
||||
// @ts-ignore
|
||||
telegraf.entity(metadata.entity, instance[key].bind(instance));
|
||||
}
|
||||
|
||||
handleTelegrafMention(
|
||||
instance: object,
|
||||
key: string,
|
||||
telegraf: Telegraf<ContextMessageUpdate>,
|
||||
metadata: TelegrafMentionMetadata,
|
||||
) {
|
||||
// @ts-ignore
|
||||
telegraf.mention(metadata.username, instance[key].bind(instance));
|
||||
}
|
||||
|
||||
handleTelegrafPhone(
|
||||
instance: object,
|
||||
key: string,
|
||||
telegraf: Telegraf<ContextMessageUpdate>,
|
||||
metadata: TelegrafPhoneMetadata,
|
||||
) {
|
||||
// @ts-ignore
|
||||
telegraf.phone(metadata.phone, instance[key].bind(instance));
|
||||
}
|
||||
|
||||
handleTelegrafHashtag(
|
||||
instance: object,
|
||||
key: string,
|
||||
telegraf: Telegraf<ContextMessageUpdate>,
|
||||
metadata: TelegrafHashtagMetadata,
|
||||
) {
|
||||
// @ts-ignore
|
||||
telegraf.hashtag(metadata.hashtag, instance[key].bind(instance));
|
||||
}
|
||||
|
||||
handleTelegrafCashtag(
|
||||
instance: object,
|
||||
key: string,
|
||||
telegraf: Telegraf<ContextMessageUpdate>,
|
||||
metadata: TelegrafCashtagMetadata,
|
||||
) {
|
||||
// @ts-ignore
|
||||
telegraf.cashtag(metadata.cashtag, instance[key].bind(instance));
|
||||
}
|
||||
|
||||
handleTelegrafAction(
|
||||
instance: object,
|
||||
key: string,
|
||||
telegraf: Telegraf<ContextMessageUpdate>,
|
||||
metadata: TelegrafActionMetadata,
|
||||
) {
|
||||
telegraf.action(metadata.triggers, instance[key].bind(instance));
|
||||
}
|
||||
|
||||
handleTelegrafInlineQuery(
|
||||
instance: object,
|
||||
key: string,
|
||||
telegraf: Telegraf<ContextMessageUpdate>,
|
||||
metadata: TelegrafInlineQueryMetadata,
|
||||
) {
|
||||
// @ts-ignore
|
||||
telegraf.inlineQuery(metadata.triggers, instance[key].bind(instance));
|
||||
}
|
||||
|
||||
handleTelegrafGameQuery(
|
||||
instance: object,
|
||||
key: string,
|
||||
telegraf: Telegraf<ContextMessageUpdate>,
|
||||
) {
|
||||
telegraf.gameQuery(instance[key].bind(instance));
|
||||
}
|
||||
}
|
@ -1,63 +1,25 @@
|
||||
import { Module, DynamicModule, Provider } from '@nestjs/common';
|
||||
import { Module, DynamicModule } from '@nestjs/common';
|
||||
import { TelegrafCoreModule } from './telegraf-core.module';
|
||||
import {
|
||||
TelegrafModuleOptions,
|
||||
TelegrafModuleAsyncOptions,
|
||||
TelegrafOptionsFactory
|
||||
} from './interfaces';
|
||||
import {
|
||||
TELEGRAF_MODULE_OPTIONS,
|
||||
TokenInjectionToken
|
||||
} from './telegraf.constants';
|
||||
import { TelegrafService, TelegrafTelegramService } from './';
|
||||
|
||||
@Module({})
|
||||
export class TelegrafModule {
|
||||
static fromFactory(options: TelegrafModuleAsyncOptions): DynamicModule {
|
||||
public static forRoot(options?: TelegrafModuleOptions): DynamicModule {
|
||||
return {
|
||||
module: TelegrafModule,
|
||||
imports: options.imports || [],
|
||||
providers: [
|
||||
...this.createAsyncProviders(options),
|
||||
TelegrafService,
|
||||
TelegrafTelegramService,
|
||||
{
|
||||
provide: TokenInjectionToken,
|
||||
useClass: options.useClass
|
||||
}
|
||||
],
|
||||
exports: [TelegrafService, TelegrafTelegramService]
|
||||
imports: [TelegrafCoreModule.forRoot(options)],
|
||||
};
|
||||
}
|
||||
|
||||
private static createAsyncProviders(
|
||||
options: TelegrafModuleAsyncOptions
|
||||
): Provider[] {
|
||||
if (options.useExisting || options.useFactory) {
|
||||
return [this.createAsyncOptionsProvider(options)];
|
||||
}
|
||||
return [
|
||||
this.createAsyncOptionsProvider(options),
|
||||
{
|
||||
provide: options.useClass,
|
||||
useClass: options.useClass
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
private static createAsyncOptionsProvider(
|
||||
options: TelegrafModuleAsyncOptions
|
||||
): Provider {
|
||||
if (options.useFactory) {
|
||||
return {
|
||||
provide: TELEGRAF_MODULE_OPTIONS,
|
||||
useFactory: options.useFactory,
|
||||
inject: options.inject || []
|
||||
};
|
||||
}
|
||||
public static forRootAsync(
|
||||
options: TelegrafModuleAsyncOptions,
|
||||
): DynamicModule {
|
||||
return {
|
||||
provide: TELEGRAF_MODULE_OPTIONS,
|
||||
useFactory: async (optionsFactory: TelegrafOptionsFactory) =>
|
||||
await optionsFactory.createTelegrafOptions(),
|
||||
inject: [options.useExisting || options.useClass]
|
||||
module: TelegrafModule,
|
||||
imports: [TelegrafCoreModule.forRootAsync(options)],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
33
lib/telegraf.provider.ts
Normal file
33
lib/telegraf.provider.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import {
|
||||
Injectable,
|
||||
Inject,
|
||||
OnApplicationBootstrap,
|
||||
Logger,
|
||||
OnApplicationShutdown,
|
||||
} from '@nestjs/common';
|
||||
import Telegraf, { ContextMessageUpdate } from 'telegraf';
|
||||
import { TELEGRAF_MODULE_OPTIONS } from './telegraf.constants';
|
||||
import { TelegrafModuleOptions } from './interfaces';
|
||||
|
||||
@Injectable()
|
||||
// @ts-ignore
|
||||
export class TelegrafProvider<TContext extends ContextMessageUpdate>
|
||||
extends Telegraf<TContext>
|
||||
implements OnApplicationBootstrap, OnApplicationShutdown {
|
||||
private logger = new Logger('Telegraf');
|
||||
|
||||
constructor(@Inject(TELEGRAF_MODULE_OPTIONS) options: TelegrafModuleOptions) {
|
||||
super(options.token, options.options);
|
||||
}
|
||||
|
||||
onApplicationBootstrap() {
|
||||
this.catch(e => {
|
||||
this.logger.error(e);
|
||||
});
|
||||
this.startPolling();
|
||||
}
|
||||
|
||||
async onApplicationShutdown(signal?: string) {
|
||||
await this.stop();
|
||||
}
|
||||
}
|
@ -1,183 +0,0 @@
|
||||
import { Inject, Injectable, Logger } from '@nestjs/common'
|
||||
import { ModuleRef } from '@nestjs/core'
|
||||
import { flatten, head } from 'lodash'
|
||||
import Telegraf, { ContextMessageUpdate } from 'telegraf'
|
||||
import { TelegramActionHandler, TelegramCatch } from './decorators'
|
||||
import { InvalidConfigurationException } from './exeptions'
|
||||
import {
|
||||
ContextTransformer,
|
||||
Handler,
|
||||
TelegrafOptionsFactory,
|
||||
TelegramErrorHandler,
|
||||
} from './interfaces'
|
||||
import { TokenInjectionToken } from './telegraf.constants'
|
||||
|
||||
@Injectable()
|
||||
export class TelegrafService {
|
||||
private readonly logger = new Logger(TelegrafService.name, true)
|
||||
private readonly sitePublicUrl?: string
|
||||
public readonly bot: Telegraf<ContextMessageUpdate>
|
||||
private ref: ModuleRef
|
||||
|
||||
public constructor(
|
||||
@Inject(TokenInjectionToken) options: TelegrafOptionsFactory
|
||||
) {
|
||||
const {
|
||||
token,
|
||||
sitePublicUrl,
|
||||
telegrafOptions,
|
||||
} = options.createTelegrafOptions()
|
||||
this.sitePublicUrl = sitePublicUrl
|
||||
this.bot = new Telegraf(token, telegrafOptions)
|
||||
}
|
||||
|
||||
public init(ref: ModuleRef, devMode: boolean = false) {
|
||||
this.ref = ref
|
||||
|
||||
const handlers = this.createHandlers()
|
||||
|
||||
this.setupOnStart(handlers)
|
||||
this.setupOn(handlers)
|
||||
this.setupOnMessage(handlers)
|
||||
this.setupOnCommand(handlers)
|
||||
this.setupActions(handlers)
|
||||
|
||||
if (devMode) {
|
||||
this.startPolling()
|
||||
}
|
||||
}
|
||||
|
||||
public getMiddleware(path: string) {
|
||||
if (!this.sitePublicUrl) {
|
||||
throw new InvalidConfigurationException(
|
||||
'sitePublicUrl',
|
||||
'does not exist, but webook used'
|
||||
)
|
||||
}
|
||||
|
||||
const url = `${this.sitePublicUrl}/${path}`
|
||||
|
||||
this.bot.telegram
|
||||
.setWebhook(url)
|
||||
.then(() => this.logger.log(`Webhook set success @ ${url}`))
|
||||
|
||||
return this.bot.webhookCallback(`/${path}`)
|
||||
}
|
||||
|
||||
public startPolling() {
|
||||
this.bot.telegram.deleteWebhook().then(
|
||||
() => this.bot.startPolling(),
|
||||
() => {
|
||||
// okay, never mind
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private createHandlers(): Handler[] {
|
||||
return flatten(
|
||||
Array.from((TelegramActionHandler.handlers || new Map()).entries()).map(
|
||||
([handlerClass, classConfig]) => {
|
||||
const handlerInstance = this.ref.get(handlerClass, { strict: false })
|
||||
|
||||
return Array.from(classConfig.entries()).map(
|
||||
([methodName, methodCondig]) => ({
|
||||
handle: handlerInstance[methodName].bind(handlerInstance),
|
||||
config: methodCondig,
|
||||
})
|
||||
)
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private setupOnStart(handlers: Handler[]): void {
|
||||
const onStart = handlers.filter(({ config }) => config.onStart)
|
||||
|
||||
if (onStart.length !== 1) {
|
||||
throw new Error()
|
||||
}
|
||||
|
||||
this.bot.start(this.adoptHandle(head(onStart)))
|
||||
}
|
||||
|
||||
private setupOn(handlers: Handler[]): void {
|
||||
const onHandlers = handlers.filter(({ config }) => config.on)
|
||||
|
||||
onHandlers.forEach(handler => {
|
||||
this.bot.on(handler.config.on, this.adoptHandle(handler))
|
||||
})
|
||||
}
|
||||
|
||||
private setupOnMessage(handlers: Handler[]): void {
|
||||
const onMessageHandlers = handlers.filter(
|
||||
({ config }) => config.message !== undefined
|
||||
)
|
||||
|
||||
onMessageHandlers.forEach(handler => {
|
||||
if (handler.config.message) {
|
||||
this.bot.hears(handler.config.message, this.adoptHandle(handler))
|
||||
} else {
|
||||
this.bot.on('message', this.adoptHandle(handler))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private setupOnCommand(handlers: Handler[]): void {
|
||||
const commandHandlers = handlers.filter(({ config }) => config.command)
|
||||
|
||||
commandHandlers.forEach(handler => {
|
||||
this.bot.command(handler.config.command, this.adoptHandle(handler))
|
||||
})
|
||||
}
|
||||
|
||||
private setupActions(handlers: Handler[]): void {
|
||||
const commandHandlers = handlers.filter(({ config }) => config.action)
|
||||
|
||||
commandHandlers.forEach(handler => {
|
||||
this.bot.action(handler.config.action, this.adoptHandle(handler))
|
||||
})
|
||||
}
|
||||
|
||||
private adoptHandle({ handle, config }: Handler) {
|
||||
const errorHandler = this.createCatch()
|
||||
|
||||
return async (ctx: ContextMessageUpdate) => {
|
||||
const args = await Promise.all(
|
||||
(config.transformations || [])
|
||||
.sort((a, b) => a.index - b.index)
|
||||
.map(({ transform }) =>
|
||||
this.ref
|
||||
.get<ContextTransformer>(transform, { strict: false })
|
||||
.transform(ctx)
|
||||
)
|
||||
)
|
||||
|
||||
return handle(ctx, ...args).catch(errorHandler(ctx))
|
||||
}
|
||||
}
|
||||
|
||||
private createCatch() {
|
||||
const handlers = Array.from(
|
||||
(TelegramCatch.handlers || new Map()).entries()
|
||||
).map(([errorType, handlerType]) => {
|
||||
const handler = this.ref.get<TelegramErrorHandler>(handlerType, {
|
||||
strict: false,
|
||||
})
|
||||
|
||||
return {
|
||||
errorType,
|
||||
handler,
|
||||
}
|
||||
})
|
||||
|
||||
return (ctx: ContextMessageUpdate) => (e: any) => {
|
||||
for (const { errorType, handler } of handlers) {
|
||||
if (e instanceof (errorType as any)) {
|
||||
return handler.catch(ctx, e)
|
||||
}
|
||||
}
|
||||
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}
|
44
package-lock.json
generated
44
package-lock.json
generated
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "nestjs-telegraf",
|
||||
"version": "0.7.3",
|
||||
"version": "1.0.0-alpha.1",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@ -102,17 +102,10 @@
|
||||
"integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/lodash": {
|
||||
"version": "4.14.149",
|
||||
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.149.tgz",
|
||||
"integrity": "sha512-ijGqzZt/b7BfzcK9vTrS6MFljQRPn5BFWOx8oE0GYxribu6uV+aA9zZuXI1zc/etK9E8nrgdoF2+LgUw7+9tJQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "13.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-13.1.6.tgz",
|
||||
"integrity": "sha512-Jg1F+bmxcpENHP23sVKkNuU3uaxPnsBMW0cLjleiikFKomJQbsn0Cqk2yDvQArqzZN6ABfBkZ0To7pQ8sLdWDg==",
|
||||
"dev": true
|
||||
"version": "13.9.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-13.9.2.tgz",
|
||||
"integrity": "sha512-bnoqK579sAYrQbp73wwglccjJ4sfRdKU7WNEZ5FW4K2U6Kc0/eZ5kvXG0JKsEKFB50zrFmfFt52/cvBbZa7eXg=="
|
||||
},
|
||||
"@types/parse-json": {
|
||||
"version": "4.0.0",
|
||||
@ -902,11 +895,6 @@
|
||||
"p-locate": "^4.1.0"
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.15",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
|
||||
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
|
||||
},
|
||||
"log-symbols": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz",
|
||||
@ -975,16 +963,14 @@
|
||||
"dev": true
|
||||
},
|
||||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
|
||||
"dev": true
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
||||
},
|
||||
"module-alias": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/module-alias/-/module-alias-2.2.2.tgz",
|
||||
"integrity": "sha512-A/78XjoX2EmNvppVWEhM2oGk3x4lLxnkEA4jTbaK97QKSDjkIoOsKQlfylt/d3kKKi596Qy3NP5XrXJ6fZIC9Q==",
|
||||
"dev": true
|
||||
"integrity": "sha512-A/78XjoX2EmNvppVWEhM2oGk3x4lLxnkEA4jTbaK97QKSDjkIoOsKQlfylt/d3kKKi596Qy3NP5XrXJ6fZIC9Q=="
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
@ -1001,8 +987,7 @@
|
||||
"node-fetch": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
|
||||
"integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA=="
|
||||
},
|
||||
"normalize-path": {
|
||||
"version": "3.0.0",
|
||||
@ -1239,8 +1224,7 @@
|
||||
"sandwich-stream": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/sandwich-stream/-/sandwich-stream-2.0.2.tgz",
|
||||
"integrity": "sha512-jLYV0DORrzY3xaz/S9ydJL6Iz7essZeAfnAavsJ+zsJGZ1MOnsS52yRjU3uF3pJa/lla7+wisp//fxOwOH8SKQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-jLYV0DORrzY3xaz/S9ydJL6Iz7essZeAfnAavsJ+zsJGZ1MOnsS52yRjU3uF3pJa/lla7+wisp//fxOwOH8SKQ=="
|
||||
},
|
||||
"semver-compare": {
|
||||
"version": "1.0.0",
|
||||
@ -1349,7 +1333,6 @@
|
||||
"version": "3.36.0",
|
||||
"resolved": "https://registry.npmjs.org/telegraf/-/telegraf-3.36.0.tgz",
|
||||
"integrity": "sha512-9o6AJKRiTm5vMWYI6WpTfBHzu4FMpWBNKxvnMxRds/cbMY9RnsVVjdi8i4bFFlfd+xbi73EbrnI3dybayryICA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "^13.1.0",
|
||||
"debug": "^4.0.1",
|
||||
@ -1364,7 +1347,6 @@
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
|
||||
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
@ -1372,16 +1354,14 @@
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||
"dev": true
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"telegram-typings": {
|
||||
"version": "3.6.1",
|
||||
"resolved": "https://registry.npmjs.org/telegram-typings/-/telegram-typings-3.6.1.tgz",
|
||||
"integrity": "sha512-njVv1EAhIZnmQVLocZEADYUyqA1WIXuVcDYlsp+mXua/XB0pxx+PKtMSPeZ/EE4wPWTw9h/hA9ASTT6yQelkiw==",
|
||||
"dev": true
|
||||
"integrity": "sha512-njVv1EAhIZnmQVLocZEADYUyqA1WIXuVcDYlsp+mXua/XB0pxx+PKtMSPeZ/EE4wPWTw9h/hA9ASTT6yQelkiw=="
|
||||
},
|
||||
"timers-ext": {
|
||||
"version": "0.1.7",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "nestjs-telegraf",
|
||||
"version": "0.7.3",
|
||||
"version": "1.0.0-alpha.1",
|
||||
"description": "Telegraf module for Nest framework",
|
||||
"keywords": [
|
||||
"nest",
|
||||
@ -34,24 +34,21 @@
|
||||
"publish:npm": "npm publish --access public"
|
||||
},
|
||||
"dependencies": {
|
||||
"lodash": "4.17.15"
|
||||
"telegraf": "^3.36.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nestjs/common": "6.11.11",
|
||||
"@nestjs/core": "6.11.11",
|
||||
"@types/lodash": "4.14.149",
|
||||
"husky": "4.2.3",
|
||||
"lint-staged": "10.0.8",
|
||||
"prettier": "1.19.1",
|
||||
"reflect-metadata": "0.1.13",
|
||||
"telegraf": "3.36.0",
|
||||
"typescript": "3.8.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@nestjs/common": "^6.7.0",
|
||||
"@nestjs/core": "^6.7.0",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"telegraf": "^3.35.0"
|
||||
"reflect-metadata": "^0.1.13"
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
|
Loading…
Reference in New Issue
Block a user