@kastov/grammy-nestjs 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/README.md +362 -0
  3. package/package.json +48 -0
  4. package/src/decorators/composer/chat-type.decorator.d.ts +1 -0
  5. package/src/decorators/composer/chat-type.decorator.js +6 -0
  6. package/src/decorators/composer/chat-type.decorator.js.map +1 -0
  7. package/src/decorators/composer/drop.decorator.d.ts +1 -0
  8. package/src/decorators/composer/drop.decorator.js +6 -0
  9. package/src/decorators/composer/drop.decorator.js.map +1 -0
  10. package/src/decorators/composer/filter.decorator.d.ts +1 -0
  11. package/src/decorators/composer/filter.decorator.js +6 -0
  12. package/src/decorators/composer/filter.decorator.js.map +1 -0
  13. package/src/decorators/composer/index.d.ts +3 -0
  14. package/src/decorators/composer/index.js +7 -0
  15. package/src/decorators/composer/index.js.map +1 -0
  16. package/src/decorators/core/index.d.ts +2 -0
  17. package/src/decorators/core/index.js +6 -0
  18. package/src/decorators/core/index.js.map +1 -0
  19. package/src/decorators/core/inject-bot.decorator.d.ts +1 -0
  20. package/src/decorators/core/inject-bot.decorator.js +8 -0
  21. package/src/decorators/core/inject-bot.decorator.js.map +1 -0
  22. package/src/decorators/core/update.decorator.d.ts +5 -0
  23. package/src/decorators/core/update.decorator.js +12 -0
  24. package/src/decorators/core/update.decorator.js.map +1 -0
  25. package/src/decorators/index.d.ts +4 -0
  26. package/src/decorators/index.js +8 -0
  27. package/src/decorators/index.js.map +1 -0
  28. package/src/decorators/listeners/admin.decorator.d.ts +6 -0
  29. package/src/decorators/listeners/admin.decorator.js +11 -0
  30. package/src/decorators/listeners/admin.decorator.js.map +1 -0
  31. package/src/decorators/listeners/callback-query.decorator.d.ts +6 -0
  32. package/src/decorators/listeners/callback-query.decorator.js +11 -0
  33. package/src/decorators/listeners/callback-query.decorator.js.map +1 -0
  34. package/src/decorators/listeners/command.decorator.d.ts +6 -0
  35. package/src/decorators/listeners/command.decorator.js +11 -0
  36. package/src/decorators/listeners/command.decorator.js.map +1 -0
  37. package/src/decorators/listeners/hears.decorator.d.ts +6 -0
  38. package/src/decorators/listeners/hears.decorator.js +11 -0
  39. package/src/decorators/listeners/hears.decorator.js.map +1 -0
  40. package/src/decorators/listeners/help.decorator.d.ts +6 -0
  41. package/src/decorators/listeners/help.decorator.js +11 -0
  42. package/src/decorators/listeners/help.decorator.js.map +1 -0
  43. package/src/decorators/listeners/index.d.ts +9 -0
  44. package/src/decorators/listeners/index.js +14 -0
  45. package/src/decorators/listeners/index.js.map +1 -0
  46. package/src/decorators/listeners/inline-query.decorator.d.ts +6 -0
  47. package/src/decorators/listeners/inline-query.decorator.js +11 -0
  48. package/src/decorators/listeners/inline-query.decorator.js.map +1 -0
  49. package/src/decorators/listeners/on.decorator.d.ts +6 -0
  50. package/src/decorators/listeners/on.decorator.js +11 -0
  51. package/src/decorators/listeners/on.decorator.js.map +1 -0
  52. package/src/decorators/listeners/settings.decorator.d.ts +6 -0
  53. package/src/decorators/listeners/settings.decorator.js +11 -0
  54. package/src/decorators/listeners/settings.decorator.js.map +1 -0
  55. package/src/decorators/listeners/start.decorator.d.ts +6 -0
  56. package/src/decorators/listeners/start.decorator.js +11 -0
  57. package/src/decorators/listeners/start.decorator.js.map +1 -0
  58. package/src/decorators/params/context.decorator.d.ts +2 -0
  59. package/src/decorators/params/context.decorator.js +8 -0
  60. package/src/decorators/params/context.decorator.js.map +1 -0
  61. package/src/decorators/params/index.d.ts +4 -0
  62. package/src/decorators/params/index.js +8 -0
  63. package/src/decorators/params/index.js.map +1 -0
  64. package/src/decorators/params/message.decorator.d.ts +4 -0
  65. package/src/decorators/params/message.decorator.js +10 -0
  66. package/src/decorators/params/message.decorator.js.map +1 -0
  67. package/src/decorators/params/next.decorator.d.ts +1 -0
  68. package/src/decorators/params/next.decorator.js +7 -0
  69. package/src/decorators/params/next.decorator.js.map +1 -0
  70. package/src/decorators/params/sender.decorator.d.ts +4 -0
  71. package/src/decorators/params/sender.decorator.js +10 -0
  72. package/src/decorators/params/sender.decorator.js.map +1 -0
  73. package/src/enums/grammy-paramtype.enum.d.ts +6 -0
  74. package/src/enums/grammy-paramtype.enum.js +12 -0
  75. package/src/enums/grammy-paramtype.enum.js.map +1 -0
  76. package/src/enums/index.d.ts +1 -0
  77. package/src/enums/index.js +5 -0
  78. package/src/enums/index.js.map +1 -0
  79. package/src/errors/grammy.exception.d.ts +2 -0
  80. package/src/errors/grammy.exception.js +7 -0
  81. package/src/errors/grammy.exception.js.map +1 -0
  82. package/src/errors/index.d.ts +1 -0
  83. package/src/errors/index.js +5 -0
  84. package/src/errors/index.js.map +1 -0
  85. package/src/execution-context/grammy-arguments-host.d.ts +8 -0
  86. package/src/execution-context/grammy-arguments-host.js +20 -0
  87. package/src/execution-context/grammy-arguments-host.js.map +1 -0
  88. package/src/execution-context/grammy-execution-context.d.ts +10 -0
  89. package/src/execution-context/grammy-execution-context.js +23 -0
  90. package/src/execution-context/grammy-execution-context.js.map +1 -0
  91. package/src/execution-context/index.d.ts +3 -0
  92. package/src/execution-context/index.js +7 -0
  93. package/src/execution-context/index.js.map +1 -0
  94. package/src/execution-context/tg-arguments-host.interface.d.ts +5 -0
  95. package/src/execution-context/tg-arguments-host.interface.js +3 -0
  96. package/src/execution-context/tg-arguments-host.interface.js.map +1 -0
  97. package/src/factories/grammy-params-factory.d.ts +6 -0
  98. package/src/factories/grammy-params-factory.js +25 -0
  99. package/src/factories/grammy-params-factory.js.map +1 -0
  100. package/src/factories/index.d.ts +1 -0
  101. package/src/factories/index.js +5 -0
  102. package/src/factories/index.js.map +1 -0
  103. package/src/index.d.ts +13 -0
  104. package/src/index.js +17 -0
  105. package/src/index.js.map +1 -0
  106. package/src/interfaces/composer-metadata.interface.d.ts +14 -0
  107. package/src/interfaces/composer-metadata.interface.js +3 -0
  108. package/src/interfaces/composer-metadata.interface.js.map +1 -0
  109. package/src/interfaces/grammy-exception-filter.interface.d.ts +4 -0
  110. package/src/interfaces/grammy-exception-filter.interface.js +3 -0
  111. package/src/interfaces/grammy-exception-filter.interface.js.map +1 -0
  112. package/src/interfaces/grammy-options.interface.d.ts +22 -0
  113. package/src/interfaces/grammy-options.interface.js +3 -0
  114. package/src/interfaces/grammy-options.interface.js.map +1 -0
  115. package/src/interfaces/index.d.ts +4 -0
  116. package/src/interfaces/index.js +8 -0
  117. package/src/interfaces/index.js.map +1 -0
  118. package/src/interfaces/listener-metadata.interface.d.ts +6 -0
  119. package/src/interfaces/listener-metadata.interface.js +3 -0
  120. package/src/interfaces/listener-metadata.interface.js.map +1 -0
  121. package/src/nestjs-grammy-core.module.d.ts +13 -0
  122. package/src/nestjs-grammy-core.module.js +108 -0
  123. package/src/nestjs-grammy-core.module.js.map +1 -0
  124. package/src/nestjs-grammy.constants.d.ts +8 -0
  125. package/src/nestjs-grammy.constants.js +13 -0
  126. package/src/nestjs-grammy.constants.js.map +1 -0
  127. package/src/nestjs-grammy.module.d.ts +6 -0
  128. package/src/nestjs-grammy.module.js +32 -0
  129. package/src/nestjs-grammy.module.js.map +1 -0
  130. package/src/services/base-explorer.service.d.ts +7 -0
  131. package/src/services/base-explorer.service.js +43 -0
  132. package/src/services/base-explorer.service.js.map +1 -0
  133. package/src/services/index.d.ts +3 -0
  134. package/src/services/index.js +7 -0
  135. package/src/services/index.js.map +1 -0
  136. package/src/services/listeners-explorer.service.d.ts +29 -0
  137. package/src/services/listeners-explorer.service.js +104 -0
  138. package/src/services/listeners-explorer.service.js.map +1 -0
  139. package/src/services/metadata-accessor.service.d.ts +9 -0
  140. package/src/services/metadata-accessor.service.js +30 -0
  141. package/src/services/metadata-accessor.service.js.map +1 -0
  142. package/src/types/grammy-types.d.ts +8 -0
  143. package/src/types/grammy-types.js +3 -0
  144. package/src/types/grammy-types.js.map +1 -0
  145. package/src/types/index.d.ts +1 -0
  146. package/src/types/index.js +5 -0
  147. package/src/types/index.js.map +1 -0
  148. package/src/utils/create-bot-factory.util.d.ts +3 -0
  149. package/src/utils/create-bot-factory.util.js +25 -0
  150. package/src/utils/create-bot-factory.util.js.map +1 -0
  151. package/src/utils/create-composer-decorator.util.d.ts +3 -0
  152. package/src/utils/create-composer-decorator.util.js +22 -0
  153. package/src/utils/create-composer-decorator.util.js.map +1 -0
  154. package/src/utils/create-emiiter-decorator.util.d.ts +3 -0
  155. package/src/utils/create-emiiter-decorator.util.js +23 -0
  156. package/src/utils/create-emiiter-decorator.util.js.map +1 -0
  157. package/src/utils/get-bot-name.util.d.ts +1 -0
  158. package/src/utils/get-bot-name.util.js +9 -0
  159. package/src/utils/get-bot-name.util.js.map +1 -0
  160. package/src/utils/index.d.ts +4 -0
  161. package/src/utils/index.js +8 -0
  162. package/src/utils/index.js.map +1 -0
  163. package/src/utils/param-decorator.util.d.ts +6 -0
  164. package/src/utils/param-decorator.util.js +26 -0
  165. package/src/utils/param-decorator.util.js.map +1 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,54 @@
1
+ # Changelog
2
+
3
+ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
4
+
5
+ ## [0.4.0](https://github.com/grammyjs/nestjs/compare/grammy-nestjs-0.3.1...grammy-nestjs-0.4.0) (2023-01-08)
6
+
7
+ ### Features
8
+
9
+ - create composer decorators ([4be9318](https://github.com/grammyjs/nestjs/commit/4be93183f55eea3bd87c434d5b91292a0cb320ca))
10
+
11
+ ### [0.3.3](https://github.com/grammyjs/nestjs/compare/grammy-nestjs-0.3.2...grammy-nestjs-0.3.3) (2023-01-08)
12
+
13
+ ### Add back `bot.use(...)` call in factory to fix middleware.
14
+
15
+ - bump deps - include NestJS@^9.0.0 ([44e17b0](https://github.com/grammyjs/nestjs/commit/44e17b04c2a3a093fa9cbaaacc9ab217111c4594))
16
+
17
+ ## [0.3.2](https://github.com/grammyjs/nestjs/compare/grammy-nestjs-0.3.1...grammy-nestjs-0.3.2) (2022-10-07)
18
+
19
+ ### Publish peer dependency for NestJS ^9.0.0.
20
+
21
+ ### [0.3.1](https://github.com/grammyjs/nestjs/compare/grammy-nestjs-0.3.0...grammy-nestjs-0.3.1) (2022-06-26)
22
+
23
+ ### Bug Fixes
24
+
25
+ - add lodash and other deps to package.json build ([ad7389c](https://github.com/grammyjs/nestjs/commit/ad7389c70cf9754482f6721638d140c5bc7c964a)), closes [#14](https://github.com/grammyjs/nestjs/issues/14)
26
+
27
+ ## [0.3.0](https://github.com/grammyjs/nestjs/compare/grammy-nestjs-0.2.0...grammy-nestjs-0.3.0) (2022-06-25)
28
+
29
+ ### Features
30
+
31
+ - fix explorer startup race condition ([9de1ce5](https://github.com/grammyjs/nestjs/commit/9de1ce511cdcd052ae4dc83e19ad7a64fa6b1588)), closes [#10](https://github.com/grammyjs/nestjs/issues/10)
32
+ - misc cleanup ([ad47d69](https://github.com/grammyjs/nestjs/commit/ad47d69252af646a92e3c44ab66a24e6c59e34ab))
33
+ - rename emitter and cleanup code ([d7d5297](https://github.com/grammyjs/nestjs/commit/d7d529798ef2571dfe3e9b80cfbe145545dde6fc))
34
+
35
+ ## [0.2.0](https://github.com/grammyjs/nestjs/compare/grammy-nestjs-0.1.0...grammy-nestjs-0.2.0) (2022-04-23)
36
+
37
+ ### Features
38
+
39
+ - add callbackQuery decorator ([bb81d64](https://github.com/grammyjs/nestjs/commit/bb81d643c64c36f19941f7b463749888f9ac05be))
40
+ - changing startup webhook flag ([a1004ee](https://github.com/grammyjs/nestjs/commit/a1004ee343249fa4e845382f003b63ec3432b380))
41
+ - initial support for firebase serverless bot ([93d8f83](https://github.com/grammyjs/nestjs/commit/93d8f8335b567979d0a5729d50dff07df36f0ee1))
42
+ - updating deployment script ([558d5c1](https://github.com/grammyjs/nestjs/commit/558d5c165d4ff2546b50054bae26f3c599a836d5))
43
+
44
+ ## 0.1.0 (2022-04-19)
45
+
46
+ ### Features
47
+
48
+ - changing startup webhook flag ([a1004ee](https://github.com/grammyjs/nestjs/commit/a1004ee343249fa4e845382f003b63ec3432b380))
49
+ - initial support for firebase serverless bot ([93d8f83](https://github.com/grammyjs/nestjs/commit/93d8f8335b567979d0a5729d50dff07df36f0ee1))
50
+ - updating deployment script ([558d5c1](https://github.com/grammyjs/nestjs/commit/558d5c165d4ff2546b50054bae26f3c599a836d5))
51
+
52
+ ### Bug Fixes
53
+
54
+ - fix namespace to [@grammyjs](https://github.com/grammyjs) ([3f4c92a](https://github.com/grammyjs/nestjs/commit/3f4c92a2b61a04779f633e6dc5157d793b07c2c3))
package/README.md ADDED
@@ -0,0 +1,362 @@
1
+ <div align="center">
2
+
3
+ ![issues](https://badgen.net/github/open-issues/grammyjs/nestjs)![GitHub last commit](https://img.shields.io/github/last-commit/grammyjs/nestjs)![tags](https://badgen.net/github/tags/grammyjs/nestjs)![license](https://badgen.net/badge/license/MIT/blue)
4
+
5
+ </div>
6
+
7
+ # grammY port of NestJS Telegraf
8
+
9
+ > :information_source: This project would not be possible without the help and assistance of [Aleksandr Bukhalo](https://t.me/bukhalo_a) and the fantastic [bukhalo/nestjs-telegraf](https://github.com/bukhalo/nestjs-telegraf) project.
10
+
11
+ ## Table of Contents
12
+
13
+ - [grammY port of NestJS Telegraf](#grammy-port-of-nestjs-telegraf)
14
+ - [Table of Contents](#table-of-contents)
15
+ - [Features](#features)
16
+ - [Installation](#installation)
17
+ - [Usage](#usage)
18
+ - [grammY instance access](#grammy-instance-access)
19
+ - [Asynchronous Configuration](#asynchronous-configuration)
20
+ - [Getting Updates](#getting-updates)
21
+ - [Long polling](#long-polling)
22
+ - [Webhooks](#webhooks)
23
+ - [Middlewares](#middlewares)
24
+ - [Multiple Bots](#multiple-bots)
25
+ - [Standalone Applications](#standalone-applications)
26
+
27
+ <img align="right" width="95" height="148" title="NestJS logotype"
28
+ src="https://nestjs.com/img/logo-small.svg">
29
+
30
+ NestJS grammY – powerful solution for creating Telegram bots.
31
+
32
+ This package uses the best of the NodeJS world under the hood. [grammY](https://github.com/grammyjs/grammY) is the most powerful library for creating bots and [NestJS](https://github.com/nestjs) is a progressive framework for creating well-architectured applications. This module provides fast and easy way for creating Telegram bots and deep integration with your NestJS application.
33
+
34
+ ## Features
35
+
36
+ - Simple. Easy to use.
37
+ - Ton of decorators available out of the box for handling bot actions.
38
+ - Ability to create custom decorators.
39
+ - grammY plugins and custom plugins support.
40
+ - Ability to run multiple bots simultaneously.
41
+ - Full support of NestJS guards, interceptors, filters and pipes!
42
+
43
+ ## Installation
44
+
45
+ ```bash
46
+ npm i @grammyjs/nestjs
47
+ # or
48
+ yarn add @grammyjs/nestjs
49
+ ```
50
+
51
+ ## Usage
52
+
53
+ Once the installation process is complete, we can import the `NestjsGrammyModule` into the root `AppModule`:
54
+
55
+ ```typescript
56
+ import { Module } from '@nestjs/common'
57
+ import { NestjsGrammyModule } from '@grammyjs/nestjs'
58
+
59
+ @Module({
60
+ imports: [
61
+ NestjsGrammyModule.forRoot({
62
+ token: 'TELEGRAM_BOT_TOKEN',
63
+ }),
64
+ ],
65
+ })
66
+ export class AppModule {}
67
+ ```
68
+
69
+ Then create `app.update.ts` file and add some decorators for handling Telegram bot API updates:
70
+
71
+ ```typescript
72
+ import { Bot, Context } from 'grammy'
73
+ import { InjectBot, Update, Message, Start, Hears, Ctx, Help, Admin } from '@grammyjs/nestjs'
74
+
75
+ @Update()
76
+ @UseInterceptors(ResponseTimeInterceptor)
77
+ @UseFilters(GrammyExceptionFilter)
78
+ export class EchoUpdate {
79
+ constructor(
80
+ @InjectBot(EchoBotName)
81
+ private readonly bot: Bot<Context>,
82
+ private readonly echoService: EchoService,
83
+ ) {
84
+ log('echo update starting', this.bot ? this.bot.botInfo.id : '(booting)')
85
+ }
86
+
87
+ @Start()
88
+ async onStart(@Ctx() ctx: Context): Promise<void> {
89
+ // const me = await this.bot.api.getMe()
90
+ log('onStart!!', this.bot ? this.bot.botInfo : '(booting)')
91
+ ctx.reply(`Hey, I'm ${this.bot.botInfo.first_name}`)
92
+ }
93
+
94
+ @Help()
95
+ async onHelp(@Ctx() ctx: Context): Promise<void> {
96
+ ctx.reply('Send me any text')
97
+ }
98
+
99
+ @Admin()
100
+ @UseGuards(AdminGuard)
101
+ async onAdminCommand(@Ctx() ctx: Context): Promise<void> {
102
+ ctx.reply('Welcome, Judge')
103
+ }
104
+
105
+ @Hears('greetings')
106
+ async onMessage(@Ctx() ctx: Context, @Message('text', new ReverseTextPipe()) reversedText: string): Promise<void> {
107
+ ctx.reply(reversedText)
108
+ }
109
+
110
+ @On('chat_member')
111
+ @UpdateFilter(ctx => ctx.chatMember?.new_chat_member.status === 'member')
112
+ greetNewMember(@Ctx() ctx: Context) {
113
+ ctx.reply(`Welcome to our chat, ${ctx.chatMember.new_chat_member.user.first_name}!`)
114
+ }
115
+
116
+ @On('message')
117
+ @ChatType('private')
118
+ onPrivateMessage(@Ctx() ctx: Context) {
119
+ ctx.reply('Hello! This is private chat. You can continue to tell me your secrets')
120
+ }
121
+ }
122
+ ```
123
+
124
+ ## grammY instance access
125
+
126
+ If you want to use `grammY` instance directly, you can use `@InjectBot` for that.
127
+
128
+ ```typescript
129
+ import { Injectable } from '@nestjs/common'
130
+ import { Bot, Context } from 'grammy'
131
+ import { InjectBot } from '@grammyjs/nestjs'
132
+
133
+ @Injectable()
134
+ export class EchoService {
135
+ constructor(@InjectBot(EchoBotName) private readonly bot: Bot<Context>) {}
136
+ ...
137
+ }
138
+ ```
139
+
140
+ ## Asynchronous Configuration
141
+
142
+ 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.
143
+
144
+ One technique is to use a factory function:
145
+
146
+ ```typescript
147
+ NestjsGrammyModule.forRootAsync({
148
+ useFactory: () => ({
149
+ token: 'TELEGRAM_BOT_TOKEN',
150
+ }),
151
+ })
152
+ ```
153
+
154
+ 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.
155
+
156
+ ```typescript
157
+ NestjsGrammyModule.forRootAsync({
158
+ imports: [ConfigModule.forFeature(grammyModuleConfig)],
159
+ useFactory: async (configService: ConfigService) => ({
160
+ token: configService.get<string>('TELEGRAM_BOT_TOKEN'),
161
+ }),
162
+ inject: [ConfigService],
163
+ })
164
+ ```
165
+
166
+ Alternatively, you can configure the NestjsGrammyModule using a class instead of a factory, as shown below:
167
+
168
+ ```typescript
169
+ NestjsGrammyModule.forRootAsync({
170
+ useClass: MyConfigService,
171
+ })
172
+ ```
173
+
174
+ The construction above instantiates `MyConfigService` inside `NestjsGrammyModule`, using it to create the required options object. Note that in this example, the `MyConfigService` has to implement the `MyOptionsFactory` interface, as shown below. The `NestjsGrammyModule` will call the `createMyOptions()` method on the instantiated object of the supplied class.
175
+
176
+ ```typescript
177
+ @Injectable()
178
+ class MyConfigService implements MyOptionsFactory {
179
+ createMyOptions(): NestjsGrammyModuleOptions {
180
+ return {
181
+ token: 'TELEGRAM_BOT_TOKEN',
182
+ }
183
+ }
184
+ }
185
+ ```
186
+
187
+ If you want to reuse an existing options provider instead of creating a private copy inside the `NestjsGrammyModule`, use the `useExisting` syntax.
188
+
189
+ ```typescript
190
+ NestjsGrammyModule.forRootAsync({
191
+ imports: [ConfigModule.forFeature(grammyModuleConfig)],
192
+ useExisting: ConfigService,
193
+ })
194
+ ```
195
+
196
+ ## Getting Updates
197
+
198
+ ### Long polling
199
+
200
+ By default, the bot receives updates using long-polling and requires no additional action.
201
+
202
+ ### Webhooks
203
+
204
+ To utilize webhooks, the best documentation is to review the [Sample Firebase Bot](tree/main/packages/sample-firebase-bot) package and how it configures webhooks.
205
+
206
+ At a high level, you simply enable webhooks and pass the webhook module as follows:
207
+
208
+ ```ts
209
+ useWebhook: true,
210
+ include: [FirebaseWebhookModule],
211
+ ```
212
+
213
+ This module must initialize the webhooks for grammY as such:
214
+
215
+ ```ts
216
+ configure(consumer: MiddlewareConsumer) {
217
+ consumer.apply(webhookCallback(this.bot, 'express')).forRoutes('*')
218
+ }
219
+ ```
220
+
221
+ The last step is to write the update functions in a module like this:
222
+
223
+ ```ts
224
+ @Update()
225
+ @UseInterceptors(ResponseTimeInterceptor)
226
+ @UseFilters(GrammyExceptionFilter)
227
+ export class WebhookUpdater {
228
+ private readonly inlineKeyboard: InlineKeyboard
229
+
230
+ constructor(
231
+ @InjectBot(FirebaseBotName)
232
+ private readonly bot: Bot<Context>,
233
+ private readonly botService: FirebaseBotService,
234
+ ) {
235
+ log(`Initializing`, bot.isInited() ? bot.botInfo.first_name : '(pending)')
236
+ }
237
+
238
+ @Start()
239
+ async onStart(@Ctx() ctx: Context): Promise<any> {
240
+ log('onStart!!', this.bot ? this.bot.botInfo.first_name : '(booting)')
241
+ return ctx.reply('Curious? Click me!', { reply_markup: this.inlineKeyboard })
242
+ }
243
+
244
+ @CallbackQuery('click-payload')
245
+ async onCallback(@Ctx() ctx: Context): Promise<any> {
246
+ return ctx.answerCallbackQuery({
247
+ text: 'You were curious, indeed!',
248
+ })
249
+ }
250
+
251
+ ...
252
+ ```
253
+
254
+ ## Middlewares
255
+
256
+ `@grammyjs/nestjs` has support of the grammY middleware packages. To use an existing middleware package, simply import it and add it to the middlewares array:
257
+
258
+ ```typescript
259
+ NestjsGrammyModule.forRoot({
260
+ middlewares: [session()],
261
+ }),
262
+ ```
263
+
264
+ ## Multiple Bots
265
+
266
+ 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.
267
+
268
+ ```typescript
269
+ import { Module } from '@nestjs/common'
270
+ import { ConfigModule } from '@nestjs/config'
271
+ import { NestjsGrammyModule } from '@grammyjs/nestjs'
272
+
273
+ @Module({
274
+ imports: [
275
+ ConfigModule.forRoot(),
276
+ NestjsGrammyModule.forRootAsync({
277
+ imports: [ConfigModule],
278
+ botName: 'cat',
279
+ useFactory: (configService: ConfigService) => ({
280
+ token: configService.get<string>('CAT_BOT_TOKEN'),
281
+ }),
282
+ inject: [ConfigService],
283
+ }),
284
+ NestjsGrammyModule.forRootAsync({
285
+ imports: [ConfigModule.forFeature(myModuleConfig)],
286
+ botName: 'dog',
287
+ useFactory: async (configService: ConfigService) => ({
288
+ token: configService.get<string>('DOG_BOT_TOKEN'),
289
+ }),
290
+ inject: [ConfigService],
291
+ }),
292
+ ],
293
+ })
294
+ export class AppModule {}
295
+ ```
296
+
297
+ :::caution
298
+ Please note that you shouldn't have multiple bots without a name, or with the same name, otherwise they will get overridden.
299
+ :::
300
+
301
+ You can also inject the `Bot` for a given bot:
302
+
303
+ ```typescript
304
+ import { Injectable } from '@nestjs/common'
305
+ import { InjectBot, Bot, Context } from '@grammyjs/nestjs'
306
+
307
+ @Injectable()
308
+ export class EchoService {
309
+ constructor(@InjectBot('cat') private catBot: Bot<Context>) {}
310
+ }
311
+ ```
312
+
313
+ 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.
314
+
315
+ ```typescript
316
+ {
317
+ provide: CatsService,
318
+ useFactory: (catBot: Bot<Context>) => {
319
+ return new CatsService(catBot);
320
+ },
321
+ inject: [getBotToken('cat')],
322
+ }
323
+ ```
324
+
325
+ Another useful feature of the `@grammyjs/nestjs` 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.
326
+
327
+ ```typescript
328
+ NestjsGrammyModule.forRootAsync({
329
+ imports: [ConfigModule],
330
+ botName: 'cat',
331
+ useFactory: (configService: ConfigService) => ({
332
+ token: configService.get<string>('CAT_BOT_TOKEN'),
333
+ include: [CatsModule],
334
+ }),
335
+ inject: [ConfigService],
336
+ }),
337
+ ```
338
+
339
+ ## Standalone Applications
340
+
341
+ 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 grammY 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.
342
+
343
+ To do this, change the `bootstrap` function in the `main.ts` file of your project on something like that:
344
+
345
+ ```typescript
346
+ async function bootstrap() {
347
+ const app = await NestFactory.createApplicationContext(AppModule)
348
+ }
349
+ bootstrap()
350
+ ```
351
+
352
+ This initializes Nest as a **standalone application** (without any network listeners).
353
+
354
+ All that remains is to remove unused dependencies:
355
+
356
+ ```bash
357
+ npm un @nestjs/platform-express @types/express
358
+ ```
359
+
360
+ :::info
361
+ More information about standalone applications located at [Nest documentation](https://docs.nestjs.com/standalone-applications)
362
+ :::
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@kastov/grammy-nestjs",
3
+ "description": "grammY module for NestJS",
4
+ "version": "0.4.1",
5
+ "author": {
6
+ "name": "Mike Crowe",
7
+ "email": "drmikecrowe@gmail.com"
8
+ },
9
+ "bugs": "https://github.com/grammyjs/nestjs/issues",
10
+ "contributors": [
11
+ {
12
+ "name": "Arthur Asimov",
13
+ "email": "arthur.asimov.z0@gmail.com"
14
+ }
15
+ ],
16
+ "publishConfig": {
17
+ "registry": "https://registry.npmjs.org"
18
+ },
19
+ "homepage": "https://github.com/grammyjs/nestjs#README.md",
20
+ "keywords": [
21
+ "bot",
22
+ "bot api",
23
+ "bot framework",
24
+ "grammy",
25
+ "nest",
26
+ "nestjs",
27
+ "nestjs-module",
28
+ "telegram",
29
+ "telegram bot",
30
+ "telegram bot api"
31
+ ],
32
+ "license": "MIT",
33
+ "dependencies": {
34
+ "debug": "^4.3.4",
35
+ "lodash": "^4.17.21",
36
+ "source-map-support": "^0.5.21",
37
+ "tslib": "^2.0.0"
38
+ },
39
+ "peerDependencies": {
40
+ "@nestjs/common": "^8.0.0 || ^9.0.0",
41
+ "@nestjs/core": "^8.0.0 || ^9.0.0",
42
+ "grammy": "^1.7.3"
43
+ },
44
+ "repository": "grammyjs/nestjs",
45
+ "type": "commonjs",
46
+ "main": "./src/index.js",
47
+ "typings": "./src/index.d.ts"
48
+ }
@@ -0,0 +1 @@
1
+ export declare const ChatType: (arg: "private" | "group" | "supergroup" | "channel" | ("private" | "group" | "supergroup" | "channel")[]) => MethodDecorator;
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ChatType = void 0;
4
+ const create_composer_decorator_util_1 = require("../../utils/create-composer-decorator.util");
5
+ exports.ChatType = (0, create_composer_decorator_util_1.createComposerDecorator)('chatType');
6
+ //# sourceMappingURL=chat-type.decorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-type.decorator.js","sourceRoot":"","sources":["../../../../../../packages/grammy-nestjs/src/decorators/composer/chat-type.decorator.ts"],"names":[],"mappings":";;;AAAA,+FAAoF;AAEvE,QAAA,QAAQ,GAAG,IAAA,wDAAuB,EAAC,UAAU,CAAC,CAAA"}
@@ -0,0 +1 @@
1
+ export declare const Drop: (arg: (ctx: import("grammy").Context) => boolean | Promise<boolean>) => MethodDecorator;
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Drop = void 0;
4
+ const create_composer_decorator_util_1 = require("../../utils/create-composer-decorator.util");
5
+ exports.Drop = (0, create_composer_decorator_util_1.createComposerDecorator)('drop');
6
+ //# sourceMappingURL=drop.decorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drop.decorator.js","sourceRoot":"","sources":["../../../../../../packages/grammy-nestjs/src/decorators/composer/drop.decorator.ts"],"names":[],"mappings":";;;AAAA,+FAAoF;AAEvE,QAAA,IAAI,GAAG,IAAA,wDAAuB,EAAC,MAAM,CAAC,CAAA"}
@@ -0,0 +1 @@
1
+ export declare const UpdateFilter: (arg: (ctx: import("grammy").Context) => boolean | Promise<boolean>) => MethodDecorator;
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UpdateFilter = void 0;
4
+ const create_composer_decorator_util_1 = require("../../utils/create-composer-decorator.util");
5
+ exports.UpdateFilter = (0, create_composer_decorator_util_1.createComposerDecorator)('filter');
6
+ //# sourceMappingURL=filter.decorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter.decorator.js","sourceRoot":"","sources":["../../../../../../packages/grammy-nestjs/src/decorators/composer/filter.decorator.ts"],"names":[],"mappings":";;;AAAA,+FAAoF;AAEvE,QAAA,YAAY,GAAG,IAAA,wDAAuB,EAAC,QAAQ,CAAC,CAAA"}
@@ -0,0 +1,3 @@
1
+ export * from './chat-type.decorator';
2
+ export * from './filter.decorator';
3
+ export * from './drop.decorator';
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./chat-type.decorator"), exports);
5
+ tslib_1.__exportStar(require("./filter.decorator"), exports);
6
+ tslib_1.__exportStar(require("./drop.decorator"), exports);
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../packages/grammy-nestjs/src/decorators/composer/index.ts"],"names":[],"mappings":";;;AAAA,gEAAqC;AACrC,6DAAkC;AAClC,2DAAgC"}
@@ -0,0 +1,2 @@
1
+ export * from './inject-bot.decorator';
2
+ export * from './update.decorator';
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./inject-bot.decorator"), exports);
5
+ tslib_1.__exportStar(require("./update.decorator"), exports);
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../packages/grammy-nestjs/src/decorators/core/index.ts"],"names":[],"mappings":";;;AAAA,iEAAsC;AACtC,6DAAkC"}
@@ -0,0 +1 @@
1
+ export declare const InjectBot: (botName?: string) => ParameterDecorator;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InjectBot = void 0;
4
+ const common_1 = require("@nestjs/common");
5
+ const utils_1 = require("../../utils");
6
+ const InjectBot = (botName) => (0, common_1.Inject)((0, utils_1.getBotName)(botName));
7
+ exports.InjectBot = InjectBot;
8
+ //# sourceMappingURL=inject-bot.decorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inject-bot.decorator.js","sourceRoot":"","sources":["../../../../../../packages/grammy-nestjs/src/decorators/core/inject-bot.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAAuC;AACvC,uCAAwC;AAEjC,MAAM,SAAS,GAAG,CAAC,OAAgB,EAAsB,EAAE,CAAC,IAAA,eAAM,EAAC,IAAA,kBAAU,EAAC,OAAO,CAAC,CAAC,CAAA;AAAjF,QAAA,SAAS,aAAwE"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * `@Update` decorator, it's like NestJS `@Controller` decorator,
3
+ * but for Telegram Bot API updates.
4
+ */
5
+ export declare const Update: () => ClassDecorator;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Update = void 0;
4
+ const common_1 = require("@nestjs/common");
5
+ const nestjs_grammy_constants_1 = require("../../nestjs-grammy.constants");
6
+ /**
7
+ * `@Update` decorator, it's like NestJS `@Controller` decorator,
8
+ * but for Telegram Bot API updates.
9
+ */
10
+ const Update = () => (0, common_1.SetMetadata)(nestjs_grammy_constants_1.UPDATE_METADATA, true);
11
+ exports.Update = Update;
12
+ //# sourceMappingURL=update.decorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.decorator.js","sourceRoot":"","sources":["../../../../../../packages/grammy-nestjs/src/decorators/core/update.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAA4C;AAC5C,2EAA+D;AAE/D;;;GAGG;AACI,MAAM,MAAM,GAAG,GAAmB,EAAE,CAAC,IAAA,oBAAW,EAAC,yCAAe,EAAE,IAAI,CAAC,CAAA;AAAjE,QAAA,MAAM,UAA2D"}
@@ -0,0 +1,4 @@
1
+ export * from './core';
2
+ export * from './listeners';
3
+ export * from './params';
4
+ export * from './composer';
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./core"), exports);
5
+ tslib_1.__exportStar(require("./listeners"), exports);
6
+ tslib_1.__exportStar(require("./params"), exports);
7
+ tslib_1.__exportStar(require("./composer"), exports);
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/grammy-nestjs/src/decorators/index.ts"],"names":[],"mappings":";;;AAAA,iDAAsB;AACtB,sDAA2B;AAC3B,mDAAwB;AACxB,qDAA0B"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Handler for /help command.
3
+ *
4
+ * @see https://telegraf.js.org/#/?id=help
5
+ */
6
+ export declare const Admin: (search?: string | RegExp | string[]) => MethodDecorator;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Admin = void 0;
4
+ const utils_1 = require("../../utils");
5
+ /**
6
+ * Handler for /help command.
7
+ *
8
+ * @see https://telegraf.js.org/#/?id=help
9
+ */
10
+ exports.Admin = (0, utils_1.createBotDecorator)('command', 'admin');
11
+ //# sourceMappingURL=admin.decorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admin.decorator.js","sourceRoot":"","sources":["../../../../../../packages/grammy-nestjs/src/decorators/listeners/admin.decorator.ts"],"names":[],"mappings":";;;AAAA,uCAAgD;AAEhD;;;;GAIG;AACU,QAAA,KAAK,GAAG,IAAA,0BAAkB,EAAC,SAAS,EAAE,OAAO,CAAC,CAAA"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Registers middleware for handling keyboard callbacks
3
+ *
4
+ * @see https://grammy.dev/plugins/keyboard.html#responding-to-clicks
5
+ */
6
+ export declare const CallbackQuery: (search?: string | RegExp | string[]) => MethodDecorator;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CallbackQuery = void 0;
4
+ const utils_1 = require("../../utils");
5
+ /**
6
+ * Registers middleware for handling keyboard callbacks
7
+ *
8
+ * @see https://grammy.dev/plugins/keyboard.html#responding-to-clicks
9
+ */
10
+ exports.CallbackQuery = (0, utils_1.createBotDecorator)('callbackQuery');
11
+ //# sourceMappingURL=callback-query.decorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"callback-query.decorator.js","sourceRoot":"","sources":["../../../../../../packages/grammy-nestjs/src/decorators/listeners/callback-query.decorator.ts"],"names":[],"mappings":";;;AAAA,uCAAgD;AAEhD;;;;GAIG;AACU,QAAA,aAAa,GAAG,IAAA,0BAAkB,EAAC,eAAe,CAAC,CAAA"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Handler for /help command.
3
+ *
4
+ * @see https://telegraf.js.org/#/?id=help
5
+ */
6
+ export declare const Command: (search?: string | RegExp | string[]) => MethodDecorator;