mirror of
https://github.com/Maks1mS/nestjs-telegraf.git
synced 2024-12-23 14:42:59 +03:00
chore(release): v2.0.0
This commit is contained in:
parent
7136f57995
commit
8ddc37c424
1
.husky/.gitignore
vendored
Normal file
1
.husky/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
_
|
@ -15,7 +15,7 @@ This package uses the best of the NodeJS world under the hood. [Telegraf](https:
|
|||||||
- Scenes support.
|
- Scenes support.
|
||||||
- Telegraf plugins and custom plugins support.
|
- Telegraf plugins and custom plugins support.
|
||||||
- Ability to run multiple bots simultaneously.
|
- Ability to run multiple bots simultaneously.
|
||||||
- Full support of NestJS guards, interceptors, filters and pipes! (*in progress...*)
|
- Full support of NestJS guards, interceptors, filters and pipes!
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
If you want to dive fully into NestJS Telegraf then don't waste your time in this dump, check out the [documentation site](https://nestjs-telegraf.vercel.app).
|
If you want to dive fully into NestJS Telegraf then don't waste your time in this dump, check out the [documentation site](https://nestjs-telegraf.vercel.app).
|
||||||
|
5
package-lock.json
generated
5
package-lock.json
generated
@ -1,11 +1,11 @@
|
|||||||
{
|
{
|
||||||
"name": "nestjs-telegraf",
|
"name": "nestjs-telegraf",
|
||||||
"version": "2.0.0-beta.4",
|
"version": "2.0.0",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"version": "2.0.0-beta.4",
|
"version": "2.0.0",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
@ -2130,6 +2130,7 @@
|
|||||||
"minimist": "^1.2.5",
|
"minimist": "^1.2.5",
|
||||||
"neo-async": "^2.6.0",
|
"neo-async": "^2.6.0",
|
||||||
"source-map": "^0.6.1",
|
"source-map": "^0.6.1",
|
||||||
|
"uglify-js": "^3.1.4",
|
||||||
"wordwrap": "^1.0.0"
|
"wordwrap": "^1.0.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "nestjs-telegraf",
|
"name": "nestjs-telegraf",
|
||||||
"version": "2.0.0-beta.4",
|
"version": "2.0.0",
|
||||||
"description": "Telegraf module for NestJS",
|
"description": "Telegraf module for NestJS",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"nest",
|
"nest",
|
||||||
|
@ -1,186 +0,0 @@
|
|||||||
---
|
|
||||||
id: decorators
|
|
||||||
title: Decorators
|
|
||||||
sidebar_label: Decorators
|
|
||||||
slug: /api-reference/decorators
|
|
||||||
---
|
|
||||||
|
|
||||||
:::caution
|
|
||||||
The described functionality is under development, the functionality has not been tested and can be changed at any time!
|
|
||||||
:::
|
|
||||||
|
|
||||||
### Update
|
|
||||||
|
|
||||||
`@Update` class decorator, it's like NestJS [`@Controller`](https://docs.nestjs.com/controllers) decorator, but for [Telegram Bot API updates](https://core.telegram.org/bots/api#getting-updates).
|
|
||||||
It is required for the class that will receive updates from Telegram.
|
|
||||||
|
|
||||||
```typescript {3}
|
|
||||||
import { Update, Context } from 'nestjs-telegraf';
|
|
||||||
|
|
||||||
@Update()
|
|
||||||
export class SomeBotService {
|
|
||||||
...
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Message
|
|
||||||
|
|
||||||
Use `@Message` method decorator for handling new incoming message of any kind — text, photo, sticker, etc.
|
|
||||||
|
|
||||||
```typescript {5}
|
|
||||||
import { Update, Message, Context } from 'nestjs-telegraf';
|
|
||||||
|
|
||||||
@Update()
|
|
||||||
export class SomeBotService {
|
|
||||||
@Message()
|
|
||||||
message(ctx: Context) {
|
|
||||||
ctx.reply(`You say: ${ctx.message.text}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### EditedMessage
|
|
||||||
|
|
||||||
Use `@EditedMessage` method decorator for handling new version of a message that is known to the bot and was edited.
|
|
||||||
|
|
||||||
```typescript {5}
|
|
||||||
import { Update, EditedMessage, Context } from 'nestjs-telegraf';
|
|
||||||
|
|
||||||
@Update()
|
|
||||||
export class SomeBotService {
|
|
||||||
@EditedMessage()
|
|
||||||
editedMessage(ctx: Context) {
|
|
||||||
...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### ChannelPost
|
|
||||||
|
|
||||||
Use `@ChannelPost` method decorator for handling new incoming channel post of any kind — text, photo, sticker, etc.
|
|
||||||
|
|
||||||
```typescript {5}
|
|
||||||
import { Update, ChannelPost, Context } from 'nestjs-telegraf';
|
|
||||||
|
|
||||||
@Update()
|
|
||||||
export class SomeBotService {
|
|
||||||
@ChannelPost()
|
|
||||||
channelPost(ctx: Context) {
|
|
||||||
...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### EditedChannelPost
|
|
||||||
|
|
||||||
Use `@EditedChannelPost` method decorator for handling new version of a channel post that is known to the bot and was edited.
|
|
||||||
|
|
||||||
```typescript {5}
|
|
||||||
import { Update, EditedChannelPost, Context } from 'nestjs-telegraf';
|
|
||||||
|
|
||||||
@Update()
|
|
||||||
export class SomeBotService {
|
|
||||||
@EditedChannelPost()
|
|
||||||
editedChannelPost(ctx: Context) {
|
|
||||||
...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### InlineQuery
|
|
||||||
|
|
||||||
Use `@InlineQuery` method decorator for handling new incoming inline query.
|
|
||||||
|
|
||||||
```typescript {5}
|
|
||||||
import { Update, InlineQuery, Context } from 'nestjs-telegraf';
|
|
||||||
|
|
||||||
@Update()
|
|
||||||
export class SomeBotService {
|
|
||||||
@InlineQuery()
|
|
||||||
inlineQuery(ctx: Context) {
|
|
||||||
...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The `@InlineQuery` decorator can take a `triggers` option to handle inline query with specific value.
|
|
||||||
|
|
||||||
```typescript {6}
|
|
||||||
import { Update, InlineQuery, Context } from 'nestjs-telegraf';
|
|
||||||
|
|
||||||
@Update()
|
|
||||||
export class SomeBotService {
|
|
||||||
@InlineQuery({
|
|
||||||
triggers: 'trigger' // string/string[]/RegEx/RegEx[]
|
|
||||||
})
|
|
||||||
inlineQuery(ctx: Context) {
|
|
||||||
...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### ChosenInlineResult
|
|
||||||
|
|
||||||
Use `@ChosenInlineResult` method decorator for handling result of an inline query that was chosen by a user and sent to their chat partner.
|
|
||||||
|
|
||||||
```typescript {5}
|
|
||||||
import { Update, ChosenInlineResult, Context } from 'nestjs-telegraf';
|
|
||||||
|
|
||||||
@Update()
|
|
||||||
export class SomeBotService {
|
|
||||||
@ChosenInlineResult()
|
|
||||||
chosenInlineResult(ctx: Context) {
|
|
||||||
...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### CallbackQuery
|
|
||||||
|
|
||||||
Use `@CallbackQuery` method decorator for handling new incoming callback query.
|
|
||||||
|
|
||||||
```typescript {5}
|
|
||||||
import { Update, CallbackQuery, Context } from 'nestjs-telegraf';
|
|
||||||
|
|
||||||
@Update()
|
|
||||||
export class SomeBotService {
|
|
||||||
@CallbackQuery()
|
|
||||||
callbackQuery(ctx: Context) {
|
|
||||||
...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### ShippingQuery
|
|
||||||
|
|
||||||
Use `@ShippingQuery` method decorator for handling new incoming shipping query. Only for invoices with flexible price.
|
|
||||||
|
|
||||||
```typescript {5}
|
|
||||||
import { Update, ShippingQuery, Context } from 'nestjs-telegraf';
|
|
||||||
|
|
||||||
@Update()
|
|
||||||
export class SomeBotService {
|
|
||||||
@ShippingQuery()
|
|
||||||
shippingQuery(ctx: Context) {
|
|
||||||
...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### PreCheckoutQuery
|
|
||||||
|
|
||||||
Use `@PreCheckoutQuery` method decorator for handling new incoming pre-checkout query. Contains full information about checkout.
|
|
||||||
|
|
||||||
```typescript {5}
|
|
||||||
import { Update, PreCheckoutQuery, Context } from 'nestjs-telegraf';
|
|
||||||
|
|
||||||
@Update()
|
|
||||||
export class SomeBotService {
|
|
||||||
@PreCheckoutQuery()
|
|
||||||
preCheckoutQuery(ctx: Context) {
|
|
||||||
...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
@ -1,17 +0,0 @@
|
|||||||
---
|
|
||||||
id: bot-injection
|
|
||||||
title: Bot injection
|
|
||||||
sidebar_label: Bot injection
|
|
||||||
slug: /bot-injection
|
|
||||||
---
|
|
||||||
|
|
||||||
At times you may need to access the native `Telegraf` instance. For example, you may want to connect stage middleware. You can inject the Telegraf by using the `@InjectBot()` decorator as follows:
|
|
||||||
```typescript
|
|
||||||
import { Injectable } from '@nestjs/common';
|
|
||||||
import { InjectBot, TelegrafProvider, Context } from 'nestjs-telegraf';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class BotSettingsService {
|
|
||||||
constructor(@InjectBot() private bot: TelegrafProvider<Context>) {}
|
|
||||||
}
|
|
||||||
```
|
|
@ -1,31 +0,0 @@
|
|||||||
---
|
|
||||||
id: error-handling
|
|
||||||
title: Error handling
|
|
||||||
sidebar_label: Error handling
|
|
||||||
slug: /error-handling
|
|
||||||
---
|
|
||||||
|
|
||||||
By default, `nestjs-telegraf` catches all errors using the `Logger` built into NestJS.
|
|
||||||
|
|
||||||
Use can disable global errors catch with `disableGlobalCatch`:
|
|
||||||
```typescript
|
|
||||||
TelegrafModule.forRoot({
|
|
||||||
disableGlobalCatch: true,
|
|
||||||
}),
|
|
||||||
```
|
|
||||||
|
|
||||||
After that you can override errors handling with bot instance `catch` function.
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
import { Injectable } from '@nestjs/common';
|
|
||||||
import { InjectBot, TelegrafProvider, Context } from 'nestjs-telegraf';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class BotSettingsService {
|
|
||||||
constructor(@InjectBot() private bot: TelegrafProvider<Context>) {
|
|
||||||
this.bot.catch((err, ctx) => {
|
|
||||||
console.log(`Ooops, encountered an error for ${ctx.updateType}`, err);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
36
website/docs/extras/bot-injection.md
Normal file
36
website/docs/extras/bot-injection.md
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
---
|
||||||
|
id: bot-injection
|
||||||
|
title: Bot injection
|
||||||
|
sidebar_label: Bot injection
|
||||||
|
slug: /extras/bot-injection
|
||||||
|
---
|
||||||
|
|
||||||
|
At times you may need to access the native `Telegraf` instance. You can inject the Telegraf by using the `@InjectBot()` decorator as follows:
|
||||||
|
|
||||||
|
```typescript {8} title="src/echo/echo.service.ts"
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { InjectBot } from 'nestjs-telegraf';
|
||||||
|
import { Telegraf } from 'telegraf';
|
||||||
|
import { TelegrafContext } from '../common/interfaces/telegraf-context.interface.ts';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class EchoService {
|
||||||
|
constructor(@InjectBot() private bot: Telegraf<TelegrafContext>) {}
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If you run [multiple bots](/docs/extras/multiple-bots) in the same application, explicitly specify the bot name:
|
||||||
|
|
||||||
|
```typescript {8} title="src/echo/echo.service.ts"
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { InjectBot } from 'nestjs-telegraf';
|
||||||
|
import { Telegraf } from 'telegraf';
|
||||||
|
import { TelegrafContext } from '../common/interfaces/telegraf-context.interface.ts';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class EchoService {
|
||||||
|
constructor(@InjectBot('cats') private bot: Telegraf<TelegrafContext>) {}
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
@ -2,7 +2,7 @@
|
|||||||
id: middlewares
|
id: middlewares
|
||||||
title: Middlewares
|
title: Middlewares
|
||||||
sidebar_label: Middlewares
|
sidebar_label: Middlewares
|
||||||
slug: /middlewares
|
slug: /extras/middlewares
|
||||||
---
|
---
|
||||||
|
|
||||||
`nestjs-telegraf` has support of the Telegraf middleware packages. To use an existing middleware package, simply import it and add it to the middlewares array:
|
`nestjs-telegraf` has support of the Telegraf middleware packages. To use an existing middleware package, simply import it and add it to the middlewares array:
|
@ -2,7 +2,7 @@
|
|||||||
id: multiple-bots
|
id: multiple-bots
|
||||||
title: Multiple bots
|
title: Multiple bots
|
||||||
sidebar_label: Multiple bots
|
sidebar_label: Multiple bots
|
||||||
slug: /multiple-bots
|
slug: /extras/multiple-bots
|
||||||
---
|
---
|
||||||
|
|
||||||
In some cases, you may need to run multiple bots at the same time. This can also be achieved with this module. To work with multiple bots, first create the bots. In this case, bot naming becomes mandatory.
|
In some cases, you may need to run multiple bots at the same time. This can also be achieved with this module. To work with multiple bots, first create the bots. In this case, bot naming becomes mandatory.
|
@ -6,14 +6,12 @@ slug: /
|
|||||||
---
|
---
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ npm i nestjs-telegraf
|
$ npm i nestjs-telegraf telegraf
|
||||||
```
|
```
|
||||||
|
|
||||||
Once the installation process is complete, we can import the TelegrafModule into the root AppModule.
|
Once the installation process is complete, we can import the `TelegrafModule` into the root `AppModule`.
|
||||||
|
|
||||||
```typescript
|
|
||||||
/* app.module.ts */
|
|
||||||
|
|
||||||
|
```typescript title="src/app.module.ts"
|
||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
import { TelegrafModule } from 'nestjs-telegraf';
|
import { TelegrafModule } from 'nestjs-telegraf';
|
||||||
|
|
||||||
|
41
website/docs/migrating/from-v1-to-v2.md
Normal file
41
website/docs/migrating/from-v1-to-v2.md
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
---
|
||||||
|
id: from-v1-to-v2
|
||||||
|
title: From v1 to v2
|
||||||
|
sidebar_label: From v1 to v2
|
||||||
|
slug: /migrating/from-v1-to-v2
|
||||||
|
---
|
||||||
|
|
||||||
|
## Remove `Telegraf` prefix
|
||||||
|
If you previously used decorators with the prefix `Telegraf` in the decorator name (such as `@TelegrafOn()` or `@TelegrafHelp()`) replace them with the same decorators but without the prefix `Telegraf`, such as `@On()`, `@Start()`, `@Command()` and so on.
|
||||||
|
|
||||||
|
## `@Update()` decorator
|
||||||
|
Since v2, `nestjs-telegraf` looks for all update handlers only inside individual classes, under the `@Update()` decorator.
|
||||||
|
|
||||||
|
Previously, you could declare a handler anywhere, for example:
|
||||||
|
```typescript title="src/cats/cats.provider.ts"
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { Command } from 'nestjs-telegraf';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class CatsProvider {
|
||||||
|
@Command('cats')
|
||||||
|
async helpCommand(ctx: TelegrafContext) {
|
||||||
|
await ctx.reply('Meow.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Now you must explicitly bind the class, for Telegram Bot Api update handlers:
|
||||||
|
```typescript {3} title="src/cats/cats.updates.ts"
|
||||||
|
import { Update, Ctx } from 'nestjs-telegraf';
|
||||||
|
|
||||||
|
@Update()
|
||||||
|
export class HelpUpdate {
|
||||||
|
@Command('help')
|
||||||
|
async helpCommand(@Ctx() ctx: TelegrafContext) {
|
||||||
|
await ctx.reply('Help command.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Treat the `@Update()` decorator like the `@Controller()` decorator, but to capture Telegram Bot Api updates.
|
@ -5,42 +5,41 @@ sidebar_label: Telegraf methods
|
|||||||
slug: /telegraf-methods
|
slug: /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. For example [`@Hears`](https://telegraf.js.org/#/?id=hears), [`@On`](https://telegraf.js.org/#/?id=on), [`@Action`](https://telegraf.js.org/#/?id=action) and so on.
|
Each Telegraf instance method has own decorator in `nestjs-telegraf` package. The name of the decorator corresponds to the name of the Telegraf method. For example [`@Hears`](https://telegraf.js.org/classes/telegraf.html#hears), [`@On`](https://telegraf.js.org/classes/telegraf.html#on), [`@Action`](https://telegraf.js.org/classes/telegraf.html#action) and so on.
|
||||||
|
|
||||||
Now let's try to repeat the example from the Telegraf [documentation page](https://telegraf.js.org/#/?id=example).
|
Now let's try simple example:
|
||||||
|
|
||||||
```typescript
|
```typescript title="src/app.update.ts"
|
||||||
/* app.service.ts */
|
|
||||||
|
|
||||||
import { Injectable } from '@nestjs/common';
|
|
||||||
import {
|
import {
|
||||||
|
Update,
|
||||||
|
Ctx,
|
||||||
Start,
|
Start,
|
||||||
Help,
|
Help,
|
||||||
On,
|
On,
|
||||||
Hears,
|
Hears,
|
||||||
} from 'nestjs-telegraf';
|
} from 'nestjs-telegraf';
|
||||||
import { Context } from 'telegraf';
|
import { TelegrafContext } from './common/interfaces/telegraf-context.interface.ts';
|
||||||
|
|
||||||
@Injectable()
|
@Update()
|
||||||
export class AppService {
|
export class AppUpdate {
|
||||||
@Start()
|
@Start()
|
||||||
start(ctx: Context) {
|
async start(@Ctx() ctx: TelegrafContext) {
|
||||||
ctx.reply('Welcome');
|
await ctx.reply('Welcome');
|
||||||
}
|
}
|
||||||
|
|
||||||
@Help()
|
@Help()
|
||||||
help(ctx: Context) {
|
async help(@Ctx() ctx: TelegrafContext) {
|
||||||
ctx.reply('Send me a sticker');
|
await ctx.reply('Send me a sticker');
|
||||||
}
|
}
|
||||||
|
|
||||||
@On('sticker')
|
@On('sticker')
|
||||||
on(ctx: Context) {
|
async on(@Ctx() ctx: TelegrafContext) {
|
||||||
ctx.reply('👍');
|
await ctx.reply('👍');
|
||||||
}
|
}
|
||||||
|
|
||||||
@Hears('hi')
|
@Hears('hi')
|
||||||
hears(ctx: Context) {
|
async hears(@Ctx() ctx: TelegrafContext) {
|
||||||
ctx.reply('Hey there');
|
await ctx.reply('Hey there');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -35,52 +35,44 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
footer: {
|
footer: {
|
||||||
style: 'dark',
|
style: 'dark',
|
||||||
// links: [
|
links: [
|
||||||
// {
|
{
|
||||||
// title: 'Docs',
|
title: 'Docs',
|
||||||
// items: [
|
items: [
|
||||||
// {
|
{
|
||||||
// label: 'Style Guide',
|
label: 'Getting Started',
|
||||||
// to: 'docs/',
|
to: 'docs/',
|
||||||
// },
|
},
|
||||||
// {
|
],
|
||||||
// label: 'Second Doc',
|
},
|
||||||
// to: 'docs/doc2/',
|
{
|
||||||
// },
|
title: 'Community',
|
||||||
// ],
|
items: [
|
||||||
// },
|
{
|
||||||
// {
|
label: 'Discussions',
|
||||||
// title: 'Community',
|
href: 'https://github.com/bukhalo/nestjs-telegraf/discussions',
|
||||||
// items: [
|
},
|
||||||
// {
|
{
|
||||||
// label: 'Stack Overflow',
|
label: 'Telegram',
|
||||||
// href: 'https://stackoverflow.com/questions/tagged/docusaurus',
|
href: 'https://t.me/nestjs_telegraf',
|
||||||
// },
|
},
|
||||||
// {
|
],
|
||||||
// label: 'Discord',
|
},
|
||||||
// href: 'https://discordapp.com/invite/docusaurus',
|
{
|
||||||
// },
|
title: 'More',
|
||||||
// {
|
items: [
|
||||||
// label: 'Twitter',
|
{
|
||||||
// href: 'https://twitter.com/docusaurus',
|
label: 'Issues',
|
||||||
// },
|
href: 'https://github.com/bukhalo/nestjs-telegraf/issues',
|
||||||
// ],
|
},
|
||||||
// },
|
{
|
||||||
// {
|
label: 'Examples',
|
||||||
// title: 'More',
|
to: 'https://github.com/bukhalo/nestjs-telegraf/tree/master/sample/',
|
||||||
// items: [
|
}
|
||||||
// {
|
],
|
||||||
// label: 'Blog',
|
},
|
||||||
// to: 'blog',
|
],
|
||||||
// },
|
copyright: `Copyright © 2019 - ${new Date().getFullYear()}, <a target="_blank" href="https://bukhalo.com">Alexander Bukhalo</a> & <a target="_blank" href="mailto:arthur.asimov.z0@gmail.com">Arthur Asimov</a>.`,
|
||||||
// {
|
|
||||||
// label: 'GitHub',
|
|
||||||
// href: 'https://github.com/facebook/docusaurus',
|
|
||||||
// },
|
|
||||||
// ],
|
|
||||||
// },
|
|
||||||
// ],
|
|
||||||
copyright: `Copyright © ${new Date().getFullYear()} NestJS Telegraf.`,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
presets: [
|
presets: [
|
||||||
@ -89,7 +81,6 @@ module.exports = {
|
|||||||
{
|
{
|
||||||
docs: {
|
docs: {
|
||||||
sidebarPath: require.resolve('./sidebars.js'),
|
sidebarPath: require.resolve('./sidebars.js'),
|
||||||
// Please change this to your repo.
|
|
||||||
editUrl:
|
editUrl:
|
||||||
'https://github.com/bukhalo/nestjs-telegraf/edit/master/website/',
|
'https://github.com/bukhalo/nestjs-telegraf/edit/master/website/',
|
||||||
showLastUpdateAuthor: true,
|
showLastUpdateAuthor: true,
|
||||||
|
@ -4,13 +4,14 @@ module.exports = {
|
|||||||
'installation',
|
'installation',
|
||||||
'getting-updates',
|
'getting-updates',
|
||||||
'telegraf-methods',
|
'telegraf-methods',
|
||||||
'bot-injection',
|
|
||||||
'async-configuration',
|
'async-configuration',
|
||||||
'multiple-bots',
|
|
||||||
'middlewares',
|
|
||||||
'error-handling',
|
|
||||||
],
|
],
|
||||||
Extras: ['extras/standalone-applications'],
|
Extras: [
|
||||||
'API Reference': ['api-reference/decorators'],
|
'extras/bot-injection',
|
||||||
|
'extras/middlewares',
|
||||||
|
'extras/multiple-bots',
|
||||||
|
'extras/standalone-applications',
|
||||||
|
],
|
||||||
|
'Migrating': ['migrating/from-v1-to-v2'],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -7,14 +7,14 @@
|
|||||||
|
|
||||||
/* You can override the default Infima variables here. */
|
/* You can override the default Infima variables here. */
|
||||||
:root {
|
:root {
|
||||||
--ifm-color-primary: #25c2a0;
|
--ifm-color-primary: #3578e5;
|
||||||
--ifm-color-primary-dark: rgb(33, 175, 144);
|
--ifm-color-primary-dark: #1d68e1;
|
||||||
--ifm-color-primary-darker: rgb(31, 165, 136);
|
--ifm-color-primary-darker: #1b62d4;
|
||||||
--ifm-color-primary-darkest: rgb(26, 136, 112);
|
--ifm-color-primary-darkest: #1751af;
|
||||||
--ifm-color-primary-light: rgb(70, 203, 174);
|
--ifm-color-primary-light: #4e89e8;
|
||||||
--ifm-color-primary-lighter: rgb(102, 212, 189);
|
--ifm-color-primary-lighter: #5a91ea;
|
||||||
--ifm-color-primary-lightest: rgb(146, 224, 208);
|
--ifm-color-primary-lightest: #80aaef;
|
||||||
--ifm-code-font-size: 95%;
|
--ifm-code-font-size: 90%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.docusaurus-highlight-code-line {
|
.docusaurus-highlight-code-line {
|
||||||
|
60
website/versioned_docs/version-2.0.0/async-configuration.md
Normal file
60
website/versioned_docs/version-2.0.0/async-configuration.md
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
---
|
||||||
|
id: async-configuration
|
||||||
|
title: Async configuration
|
||||||
|
sidebar_label: Async configuration
|
||||||
|
slug: /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.
|
||||||
|
|
||||||
|
One technique is to use a factory function:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
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.forFeature(telegrafModuleConfig)],
|
||||||
|
useFactory: async (configService: ConfigService) => ({
|
||||||
|
token: configService.get<string>('TELEGRAM_BOT_TOKEN'),
|
||||||
|
}),
|
||||||
|
inject: [ConfigService],
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
Alternatively, you can configure the TelegrafModule using a class instead of a factory, as shown below:
|
||||||
|
|
||||||
|
```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()
|
||||||
|
class TelegrafConfigService implements TelegrafOptionsFactory {
|
||||||
|
createTelegrafOptions(): TelegrafModuleOptions {
|
||||||
|
return {
|
||||||
|
token: 'TELEGRAM_BOT_TOKEN',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If you want to reuse an existing options provider instead of creating a private copy inside the `TelegrafModule`, use the `useExisting` syntax.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
TelegrafModule.forRootAsync({
|
||||||
|
imports: [ConfigModule.forFeature(telegrafModuleConfig)],
|
||||||
|
useExisting: ConfigService,
|
||||||
|
});
|
||||||
|
```
|
36
website/versioned_docs/version-2.0.0/extras/bot-injection.md
Normal file
36
website/versioned_docs/version-2.0.0/extras/bot-injection.md
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
---
|
||||||
|
id: bot-injection
|
||||||
|
title: Bot injection
|
||||||
|
sidebar_label: Bot injection
|
||||||
|
slug: /extras/bot-injection
|
||||||
|
---
|
||||||
|
|
||||||
|
At times you may need to access the native `Telegraf` instance. You can inject the Telegraf by using the `@InjectBot()` decorator as follows:
|
||||||
|
|
||||||
|
```typescript {8} title="src/echo/echo.service.ts"
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { InjectBot } from 'nestjs-telegraf';
|
||||||
|
import { Telegraf } from 'telegraf';
|
||||||
|
import { TelegrafContext } from '../common/interfaces/telegraf-context.interface.ts';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class EchoService {
|
||||||
|
constructor(@InjectBot() private bot: Telegraf<TelegrafContext>) {}
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If you run [multiple bots](/docs/extras/multiple-bots) in the same application, explicitly specify the bot name:
|
||||||
|
|
||||||
|
```typescript {8} title="src/echo/echo.service.ts"
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { InjectBot } from 'nestjs-telegraf';
|
||||||
|
import { Telegraf } from 'telegraf';
|
||||||
|
import { TelegrafContext } from '../common/interfaces/telegraf-context.interface.ts';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class EchoService {
|
||||||
|
constructor(@InjectBot('cats') private bot: Telegraf<TelegrafContext>) {}
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
13
website/versioned_docs/version-2.0.0/extras/middlewares.md
Normal file
13
website/versioned_docs/version-2.0.0/extras/middlewares.md
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
id: middlewares
|
||||||
|
title: Middlewares
|
||||||
|
sidebar_label: Middlewares
|
||||||
|
slug: /extras/middlewares
|
||||||
|
---
|
||||||
|
|
||||||
|
`nestjs-telegraf` has support of the Telegraf middleware packages. To use an existing middleware package, simply import it and add it to the middlewares array:
|
||||||
|
```typescript
|
||||||
|
TelegrafModule.forRoot({
|
||||||
|
middlewares: [session()],
|
||||||
|
}),
|
||||||
|
```
|
74
website/versioned_docs/version-2.0.0/extras/multiple-bots.md
Normal file
74
website/versioned_docs/version-2.0.0/extras/multiple-bots.md
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
---
|
||||||
|
id: multiple-bots
|
||||||
|
title: Multiple bots
|
||||||
|
sidebar_label: Multiple bots
|
||||||
|
slug: /extras/multiple-bots
|
||||||
|
---
|
||||||
|
|
||||||
|
In some cases, you may need to run multiple bots at the same time. This can also be achieved with this module. To work with multiple bots, first create the bots. In this case, bot naming becomes mandatory.
|
||||||
|
```typescript
|
||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { ConfigModule } from '@nestjs/config';
|
||||||
|
import { TelegrafModule } from 'nestjs-telegraf';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [
|
||||||
|
ConfigModule.forRoot(),
|
||||||
|
TelegrafModule.forRootAsync({
|
||||||
|
imports: [ConfigModule],
|
||||||
|
botName: 'cat',
|
||||||
|
useFactory: (configService: ConfigService) => ({
|
||||||
|
token: configService.get<string>('CAT_BOT_TOKEN'),
|
||||||
|
}),
|
||||||
|
inject: [ConfigService],
|
||||||
|
}),
|
||||||
|
TelegrafModule.forRootAsync({
|
||||||
|
imports: [ConfigModule.forFeature(telegrafModuleConfig)],
|
||||||
|
botName: 'dog',
|
||||||
|
useFactory: async (configService: ConfigService) => ({
|
||||||
|
token: configService.get<string>('DOG_BOT_TOKEN'),
|
||||||
|
}),
|
||||||
|
inject: [ConfigService],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class AppModule {}
|
||||||
|
```
|
||||||
|
|
||||||
|
:::caution
|
||||||
|
Please note that you shouldn't have multiple bots without a name, or with the same name, otherwise they will get overridden.
|
||||||
|
:::
|
||||||
|
|
||||||
|
You can also inject the `Bot` for a given bot:
|
||||||
|
```typescript
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { InjectBot, Telegraf, Context } from 'nestjs-telegraf';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class EchoService {
|
||||||
|
constructor(@InjectBot('cat') private catBot: Telegraf<Context>) {}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
To inject a given `Bot` to a custom provider (for example, factory provider), use the `getBotToken()` function passing the name of the bot as an argument.
|
||||||
|
```typescript
|
||||||
|
{
|
||||||
|
provide: CatsService,
|
||||||
|
useFactory: (catBot: Telegraf<Context>) => {
|
||||||
|
return new CatsService(catBot);
|
||||||
|
},
|
||||||
|
inject: [getBotToken('cat')],
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Another useful feature of the `nestjs-telegraf` module is the ability to choose which modules should handle updates for each launched bot. By default, module searches for handlers throughout the whole app. To limit this scan to only a subset of modules, use the include property.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
TelegrafModule.forRootAsync({
|
||||||
|
imports: [ConfigModule],
|
||||||
|
botName: 'cat',
|
||||||
|
useFactory: (configService: ConfigService) => ({
|
||||||
|
token: configService.get<string>('CAT_BOT_TOKEN'),
|
||||||
|
include: [CatsModule],
|
||||||
|
}),
|
||||||
|
inject: [ConfigService],
|
||||||
|
}),
|
||||||
|
```
|
@ -0,0 +1,27 @@
|
|||||||
|
---
|
||||||
|
id: standalone-applications
|
||||||
|
title: Standalone applications
|
||||||
|
sidebar_label: Standalone applications
|
||||||
|
slug: standalone-applications
|
||||||
|
---
|
||||||
|
|
||||||
|
If you initialized your application with the [Nest CLI](https://docs.nestjs.com/cli/overview), [Express](https://expressjs.com/) framework will be installed by default along with Nest. Nest and NestJS Telegraf does not require Express for work. So if you don't plan to getting bot updates through webhooks, and you don't need a web server, you can remove Express.
|
||||||
|
|
||||||
|
To do this, change the `bootstrap` function in the `main.ts` file of your project on something like that:
|
||||||
|
```typescript
|
||||||
|
async function bootstrap() {
|
||||||
|
const app = await NestFactory.createApplicationContext(AppModule);
|
||||||
|
}
|
||||||
|
bootstrap();
|
||||||
|
```
|
||||||
|
|
||||||
|
This initializes Nest as a **standalone application** (without any network listeners).
|
||||||
|
|
||||||
|
All that remains is to remove unused dependencies:
|
||||||
|
```bash
|
||||||
|
npm un @nestjs/platform-express @types/express
|
||||||
|
```
|
||||||
|
|
||||||
|
:::info
|
||||||
|
More information about standalone applications located at [Nest documentation](https://docs.nestjs.com/standalone-applications)
|
||||||
|
:::
|
44
website/versioned_docs/version-2.0.0/getting-updates.md
Normal file
44
website/versioned_docs/version-2.0.0/getting-updates.md
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
---
|
||||||
|
id: getting-updates
|
||||||
|
title: Getting updates
|
||||||
|
sidebar_label: Getting updates
|
||||||
|
slug: getting-updates
|
||||||
|
---
|
||||||
|
|
||||||
|
## Long polling
|
||||||
|
|
||||||
|
By default, the bot receives updates using long-polling and requires no additional action.
|
||||||
|
|
||||||
|
## Webhooks
|
||||||
|
|
||||||
|
If you want to configure a telegram bot webhook, you need to get a middleware via `getBotToken` helper in your `main.ts` file.
|
||||||
|
|
||||||
|
To access it, you must use the `app.get()` method, followed by the provider reference:
|
||||||
|
```typescript
|
||||||
|
import { getBotToken } from 'nestjs-telegraf';
|
||||||
|
|
||||||
|
// ...
|
||||||
|
const bot = app.get(getBotToken());
|
||||||
|
```
|
||||||
|
|
||||||
|
Now you can connect middleware:
|
||||||
|
```typescript
|
||||||
|
app.use(bot.webhookCallback('/secret-path'));
|
||||||
|
```
|
||||||
|
|
||||||
|
The last step is to specify launchOptions in `forRoot` method:
|
||||||
|
```typescript
|
||||||
|
TelegrafModule.forRootAsync({
|
||||||
|
imports: [ConfigModule],
|
||||||
|
useFactory: (configService: ConfigService) => ({
|
||||||
|
token: configService.get<string>('TELEGRAM_BOT_TOKEN'),
|
||||||
|
launchOptions: {
|
||||||
|
webhook: {
|
||||||
|
domain: 'domain.tld',
|
||||||
|
hookPath: '/secret-path',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
inject: [ConfigService],
|
||||||
|
});
|
||||||
|
```
|
28
website/versioned_docs/version-2.0.0/installation.md
Normal file
28
website/versioned_docs/version-2.0.0/installation.md
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
---
|
||||||
|
id: installation
|
||||||
|
title: Installation
|
||||||
|
sidebar_label: Installation
|
||||||
|
slug: /
|
||||||
|
---
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ npm i nestjs-telegraf telegraf
|
||||||
|
```
|
||||||
|
|
||||||
|
Once the installation process is complete, we can import the `TelegrafModule` into the root `AppModule`.
|
||||||
|
|
||||||
|
```typescript title="src/app.module.ts"
|
||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { TelegrafModule } from 'nestjs-telegraf';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [
|
||||||
|
TelegrafModule.forRoot({
|
||||||
|
token: 'TELEGRAM_BOT_TOKEN',
|
||||||
|
})
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class AppModule {}
|
||||||
|
```
|
||||||
|
|
||||||
|
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).
|
@ -0,0 +1,41 @@
|
|||||||
|
---
|
||||||
|
id: from-v1-to-v2
|
||||||
|
title: From v1 to v2
|
||||||
|
sidebar_label: From v1 to v2
|
||||||
|
slug: /migrating/from-v1-to-v2
|
||||||
|
---
|
||||||
|
|
||||||
|
## Remove `Telegraf` prefix
|
||||||
|
If you previously used decorators with the prefix `Telegraf` in the decorator name (such as `@TelegrafOn()` or `@TelegrafHelp()`) replace them with the same decorators but without the prefix `Telegraf`, such as `@On()`, `@Start()`, `@Command()` and so on.
|
||||||
|
|
||||||
|
## `@Update()` decorator
|
||||||
|
Since v2, `nestjs-telegraf` looks for all update handlers only inside individual classes, under the `@Update()` decorator.
|
||||||
|
|
||||||
|
Previously, you could declare a handler anywhere, for example:
|
||||||
|
```typescript title="src/cats/cats.provider.ts"
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { Command } from 'nestjs-telegraf';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class CatsProvider {
|
||||||
|
@Command('cats')
|
||||||
|
async helpCommand(ctx: TelegrafContext) {
|
||||||
|
await ctx.reply('Meow.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Now you must explicitly bind the class, for Telegram Bot Api update handlers:
|
||||||
|
```typescript {3} title="src/cats/cats.updates.ts"
|
||||||
|
import { Update, Ctx } from 'nestjs-telegraf';
|
||||||
|
|
||||||
|
@Update()
|
||||||
|
export class HelpUpdate {
|
||||||
|
@Command('help')
|
||||||
|
async helpCommand(@Ctx() ctx: TelegrafContext) {
|
||||||
|
await ctx.reply('Help command.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Treat the `@Update()` decorator like the `@Controller()` decorator, but to capture Telegram Bot Api updates.
|
45
website/versioned_docs/version-2.0.0/telegraf-methods.md
Normal file
45
website/versioned_docs/version-2.0.0/telegraf-methods.md
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
---
|
||||||
|
id: telegraf-methods
|
||||||
|
title: Telegraf methods
|
||||||
|
sidebar_label: Telegraf methods
|
||||||
|
slug: /telegraf-methods
|
||||||
|
---
|
||||||
|
|
||||||
|
Each Telegraf instance method has own decorator in `nestjs-telegraf` package. The name of the decorator corresponds to the name of the Telegraf method. For example [`@Hears`](https://telegraf.js.org/classes/telegraf.html#hears), [`@On`](https://telegraf.js.org/classes/telegraf.html#on), [`@Action`](https://telegraf.js.org/classes/telegraf.html#action) and so on.
|
||||||
|
|
||||||
|
Now let's try simple example:
|
||||||
|
|
||||||
|
```typescript title="src/app.update.ts"
|
||||||
|
import {
|
||||||
|
Update,
|
||||||
|
Ctx,
|
||||||
|
Start,
|
||||||
|
Help,
|
||||||
|
On,
|
||||||
|
Hears,
|
||||||
|
} from 'nestjs-telegraf';
|
||||||
|
import { TelegrafContext } from './common/interfaces/telegraf-context.interface.ts';
|
||||||
|
|
||||||
|
@Update()
|
||||||
|
export class AppUpdate {
|
||||||
|
@Start()
|
||||||
|
async start(@Ctx() ctx: TelegrafContext) {
|
||||||
|
await ctx.reply('Welcome');
|
||||||
|
}
|
||||||
|
|
||||||
|
@Help()
|
||||||
|
async help(@Ctx() ctx: TelegrafContext) {
|
||||||
|
await ctx.reply('Send me a sticker');
|
||||||
|
}
|
||||||
|
|
||||||
|
@On('sticker')
|
||||||
|
async on(@Ctx() ctx: TelegrafContext) {
|
||||||
|
await ctx.reply('👍');
|
||||||
|
}
|
||||||
|
|
||||||
|
@Hears('hi')
|
||||||
|
async hears(@Ctx() ctx: TelegrafContext) {
|
||||||
|
await ctx.reply('Hey there');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
61
website/versioned_sidebars/version-2.0.0-sidebars.json
Normal file
61
website/versioned_sidebars/version-2.0.0-sidebars.json
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
{
|
||||||
|
"version-2.0.0/docs": [
|
||||||
|
{
|
||||||
|
"collapsed": true,
|
||||||
|
"type": "category",
|
||||||
|
"label": "Getting Started",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"type": "doc",
|
||||||
|
"id": "version-2.0.0/installation"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "doc",
|
||||||
|
"id": "version-2.0.0/getting-updates"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "doc",
|
||||||
|
"id": "version-2.0.0/telegraf-methods"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "doc",
|
||||||
|
"id": "version-2.0.0/async-configuration"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collapsed": true,
|
||||||
|
"type": "category",
|
||||||
|
"label": "Extras",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"type": "doc",
|
||||||
|
"id": "version-2.0.0/extras/bot-injection"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "doc",
|
||||||
|
"id": "version-2.0.0/extras/middlewares"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "doc",
|
||||||
|
"id": "version-2.0.0/extras/multiple-bots"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "doc",
|
||||||
|
"id": "version-2.0.0/extras/standalone-applications"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collapsed": true,
|
||||||
|
"type": "category",
|
||||||
|
"label": "Migrating",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"type": "doc",
|
||||||
|
"id": "version-2.0.0/migrating/from-v1-to-v2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
[
|
[
|
||||||
|
"2.0.0",
|
||||||
"1.3.0",
|
"1.3.0",
|
||||||
"1.2.1"
|
"1.2.1"
|
||||||
]
|
]
|
||||||
|
Loading…
Reference in New Issue
Block a user