docs: update

This commit is contained in:
Aleksandr Bukhalo 2020-03-19 20:50:04 +03:00
parent ee0ad03af8
commit 2b05c5cc17

245
README.md
View File

@ -27,213 +27,126 @@
## Installation ## Installation
```bash ```bash
$ npm i nestjs-telegraf telegraf $ npm i nestjs-telegraf
``` ```
## Usage Once the installation process is complete, we can import the TelegrafModule into the root AppModule.
### An example of package usage
```typescript ```typescript
/* bot.module.ts */ /* app.module.ts */
import { Module, OnModuleInit, Logger } from '@nestjs/common' import { Module } from '@nestjs/common';
import { ModuleRef } from '@nestjs/core' import { TelegrafModule } from 'nestjs-telegraf';
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'
@Module({ @Module({
imports: [ imports: [
TelegrafModule.fromFactory({ TelegrafModule.forRoot({
imports: [ConfigModule.forFeature(botConfig)], token: 'TELEGRAM_BOT_TOKEN',
useClass: TelegrafConfigService, })
}),
], ],
exports: [TelegrafModule],
providers: [BotService],
}) })
export class BotModule implements OnModuleInit { export class AppModule {}
constructor(
private readonly moduleRef: ModuleRef,
private readonly telegrafService: TelegrafService
) {}
onModuleInit() {
this.telegrafService.init(this.moduleRef)
this.telegrafService.startPolling()
}
}
``` ```
```typescript 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).
/* telegraf-config.service.ts */
import { Injectable } from '@nestjs/common' ## Telegraf methods
import { TelegrafOptionsFactory, TelegrafModuleOptions } from 'nestjs-telegraf'
import { ConfigService } from '@nestjs/config' 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() @Injectable()
export class TelegrafConfigService implements TelegrafOptionsFactory { export class AppService {
constructor(private readonly configService: ConfigService) {} @TelegrafStart()
start(ctx: ContextMessageUpdate) {
ctx.reply('Welcome');
}
createTelegrafOptions(): TelegrafModuleOptions { @TelegrafHelp()
return { help(ctx: ContextMessageUpdate) {
token: this.configService.get('bot.token'), ctx.reply('Send me a sticker');
} }
@TelegrafOn('sticker')
on(ctx: ContextMessageUpdate) {
ctx.reply('👍');
}
@TelegrafHears('hi')
hears(ctx: ContextMessageUpdate) {
ctx.reply('Hey there');
} }
} }
``` ```
```typescript ## Async configuration
/* bot.config.ts */ 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' One technique is to use a factory function:
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.
```typescript ```typescript
/* bot.service.ts */ TelegrafModule.forRootAsync({
useFactory: () => ({
import { Injectable } from '@nestjs/common' token: 'TELEGRAM_BOT_TOKEN',
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,
}), }),
); });
``` ```
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 ```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' ```typescript
import { ConfigService } from '@nestjs/config' TelegrafModule.forRootAsync({
import { TelegrafModuleOptions, TelegrafOptionsFactory } from 'nestjs-telegraf' useClass: TelegrafConfigService,
import { SocksProxyAgent } from 'socks-proxy-agent' });
```
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() @Injectable()
export class TelegrafConfigService implements TelegrafOptionsFactory { class TelegrafConfigService implements TelegrafOptionsFactory {
private agent createMongooseOptions(): TelegrafModuleOptions {
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)
return { return {
token: this.configService.get('bot.token'), token: 'TELEGRAM_BOT_TOKEN',
telegrafOptions: { telegram: { agent: this.agent } },
}; };
} }
} }
``` ```
### Telegram If you want to reuse an existing options provider instead of creating a private copy inside the `TelegrafModule`, use the `useExisting` syntax.
#### Telegram methods usage
Inject `TelegrafTelegramService` from `nestjs-telegraf` package for use [Telegram instance](https://telegraf.js.org/#/?id=telegram) from `telegraf` package.
```typescript ```typescript
/* bot.service.ts */ TelegrafModule.forRootAsync({
imports: [ConfigModule],
import { Injectable } from '@nestjs/common' useExisting: ConfigService,
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)
}
}
``` ```
## Examples
You can see the basic use of the package in this repository:
https://github.com/bukhalo/nestjs-telegraf-sample
## Support ## 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). 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).