docs: update

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

239
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) {
createTelegrafOptions(): TelegrafModuleOptions { ctx.reply('Welcome');
return {
token: this.configService.get('bot.token'),
}
}
}
```
```typescript
/* bot.config.ts */
import { registerAs } from '@nestjs/config'
interface Config {
token: string
} }
export default registerAs( @TelegrafHelp()
'bot', help(ctx: ContextMessageUpdate) {
(): Config => ({ ctx.reply('Send me a sticker');
token: process.env.TELEGRAM_BOT_TOKEN, }
})
)
```
### Telegraf @TelegrafOn('sticker')
on(ctx: ContextMessageUpdate) {
ctx.reply('👍');
}
#### Telegraf methods usage @TelegrafHears('hi')
You can decorate any `Telegraf` method with `@TelegramActionHandler` decorator. hears(ctx: ContextMessageUpdate) {
ctx.reply('Hey there');
```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: ## 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.
- [`onStart`](https://telegraf.js.org/#/?id=start) Handler for /start command. One technique is to use a factory function:
- [`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 ```typescript
TelegrafModule.forRootAsync({
/* bot.config.ts */ useFactory: () => ({
token: 'TELEGRAM_BOT_TOKEN',
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).