grammy 1.8.3 β†’ 1.9.0

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.
package/README.md CHANGED
@@ -10,10 +10,10 @@ _<h2 align="center"> [:mag: Documentation](https://grammy.dev) | [:page_with_cur
10
10
 
11
11
  <!-- deno-fmt-ignore-start -->
12
12
 
13
- [![Bot API](https://img.shields.io/badge/Bot%20API-6.0-blue?logo=telegram&style=flat-square)](https://core.telegram.org/bots/api)
14
- [![npm](https://img.shields.io/npm/v/grammy?logo=npm&style=flat-square)](https://www.npmjs.org/package/grammy) <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
15
- [![All Contributors](https://img.shields.io/badge/all_contributors-54-orange.svg?style=flat-square)](#contributors-)
16
- <!-- ALL-CONTRIBUTORS-BADGE:END -->
13
+ [![Bot API](https://img.shields.io/badge/Bot%20API-6.1-blue?logo=telegram&style=flat&labelColor=000&color=3b82f6)](https://core.telegram.org/bots/api)
14
+ [![Deno](https://shield.deno.dev/x/grammy)](https://deno.land/x/grammy)
15
+ [![npm](https://img.shields.io/npm/v/grammy?logo=npm&style=flat&labelColor=000&color=3b82f6)](https://www.npmjs.org/package/grammy)
16
+ [![All Contributors](https://img.shields.io/github/all-contributors/grammyjs/grammy?style=flat&labelColor=000&color=3b82f6)](#contributors-)
17
17
 
18
18
  <!-- deno-fmt-ignore-end -->
19
19
 
@@ -140,11 +140,11 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
140
140
  <tr>
141
141
  <td align="center"><a href="https://edjopato.de/"><img src="https://avatars.githubusercontent.com/u/7953011?v=4?s=100" width="100px;" alt=""/><br /><sub><b>EdJoPaTo</b></sub></a><br /><a href="#plugin-EdJoPaTo" title="Plugin/utility libraries">πŸ”Œ</a> <a href="https://github.com/grammyjs/grammY/commits?author=EdJoPaTo" title="Documentation">πŸ“–</a> <a href="#ideas-EdJoPaTo" title="Ideas, Planning, & Feedback">πŸ€”</a> <a href="https://github.com/grammyjs/grammY/pulls?q=is%3Apr+reviewed-by%3AEdJoPaTo" title="Reviewed Pull Requests">πŸ‘€</a> <a href="https://github.com/grammyjs/grammY/issues?q=author%3AEdJoPaTo" title="Bug reports">πŸ›</a> <a href="https://github.com/grammyjs/grammY/commits?author=EdJoPaTo" title="Code">πŸ’»</a></td>
142
142
  <td align="center"><a href="https://github.com/Amir-Zouerami"><img src="https://avatars.githubusercontent.com/u/53701884?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Amir Zouerami</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/commits?author=Amir-Zouerami" title="Documentation">πŸ“–</a> <a href="#plugin-Amir-Zouerami" title="Plugin/utility libraries">πŸ”Œ</a> <a href="#example-Amir-Zouerami" title="Examples">πŸ’‘</a></td>
143
- <td align="center"><a href="https://github.com/roj1512"><img src="https://avatars.githubusercontent.com/u/49933115?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Roj</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/commits?author=roj1512" title="Documentation">πŸ“–</a> <a href="https://github.com/grammyjs/grammY/pulls?q=is%3Apr+reviewed-by%3Aroj1512" title="Reviewed Pull Requests">πŸ‘€</a> <a href="#infra-roj1512" title="Infrastructure (Hosting, Build-Tools, etc)">πŸš‡</a> <a href="#translation-roj1512" title="Translation">🌍</a> <a href="https://github.com/grammyjs/grammY/commits?author=roj1512" title="Code">πŸ’»</a> <a href="#ideas-roj1512" title="Ideas, Planning, & Feedback">πŸ€”</a> <a href="#mentoring-roj1512" title="Mentoring">πŸ§‘β€πŸ«</a></td>
143
+ <td align="center"><a href="https://github.com/roj1512"><img src="https://avatars.githubusercontent.com/u/49933115?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Roj</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/commits?author=roj1512" title="Documentation">πŸ“–</a> <a href="https://github.com/grammyjs/grammY/pulls?q=is%3Apr+reviewed-by%3Aroj1512" title="Reviewed Pull Requests">πŸ‘€</a> <a href="#infra-roj1512" title="Infrastructure (Hosting, Build-Tools, etc)">πŸš‡</a> <a href="#translation-roj1512" title="Translation">🌍</a> <a href="https://github.com/grammyjs/grammY/commits?author=roj1512" title="Code">πŸ’»</a> <a href="#ideas-roj1512" title="Ideas, Planning, & Feedback">πŸ€”</a> <a href="#mentoring-roj1512" title="Mentoring">πŸ§‘β€πŸ«</a> <a href="#example-roj1512" title="Examples">πŸ’‘</a></td>
144
144
  <td align="center"><a href="https://github.com/jokasimr"><img src="https://avatars.githubusercontent.com/u/20954731?v=4?s=100" width="100px;" alt=""/><br /><sub><b>jokasimr</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/issues?q=author%3Ajokasimr" title="Bug reports">πŸ›</a></td>
145
145
  <td align="center"><a href="https://github.com/CikiMomogi"><img src="https://avatars.githubusercontent.com/u/74030149?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ciki Momogi</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/commits?author=CikiMomogi" title="Documentation">πŸ“–</a></td>
146
146
  <td align="center"><a href="https://github.com/AndreoliBR"><img src="https://avatars.githubusercontent.com/u/15970011?v=4?s=100" width="100px;" alt=""/><br /><sub><b>AndreoliBR</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/pulls?q=is%3Apr+reviewed-by%3AAndreoliBR" title="Reviewed Pull Requests">πŸ‘€</a></td>
147
- <td align="center"><a href="https://github.com/Loskir"><img src="https://avatars.githubusercontent.com/u/21295738?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Kirill Loskutov</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/commits?author=Loskir" title="Documentation">πŸ“–</a> <a href="https://github.com/grammyjs/grammY/issues?q=author%3ALoskir" title="Bug reports">πŸ›</a> <a href="#ideas-Loskir" title="Ideas, Planning, & Feedback">πŸ€”</a></td>
147
+ <td align="center"><a href="https://github.com/Loskir"><img src="https://avatars.githubusercontent.com/u/21295738?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Kirill Loskutov</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/commits?author=Loskir" title="Documentation">πŸ“–</a> <a href="https://github.com/grammyjs/grammY/issues?q=author%3ALoskir" title="Bug reports">πŸ›</a> <a href="#ideas-Loskir" title="Ideas, Planning, & Feedback">πŸ€”</a> <a href="#design-Loskir" title="Design">🎨</a> <a href="#question-Loskir" title="Answering Questions">πŸ’¬</a> <a href="https://github.com/grammyjs/grammY/pulls?q=is%3Apr+reviewed-by%3ALoskir" title="Reviewed Pull Requests">πŸ‘€</a></td>
148
148
  </tr>
149
149
  <tr>
150
150
  <td align="center"><a href="https://lungers.com/"><img src="https://avatars.githubusercontent.com/u/32808683?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Andrew Lane</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/issues?q=author%3AAndrewLaneX" title="Bug reports">πŸ›</a> <a href="https://github.com/grammyjs/grammY/pulls?q=is%3Apr+reviewed-by%3AAndrewLaneX" title="Reviewed Pull Requests">πŸ‘€</a></td>
@@ -177,19 +177,19 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
177
177
  <td align="center"><a href="https://github.com/taotie111"><img src="https://avatars.githubusercontent.com/u/44166322?v=4?s=100" width="100px;" alt=""/><br /><sub><b>taotie111</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/commits?author=taotie111" title="Documentation">πŸ“–</a> <a href="#translation-taotie111" title="Translation">🌍</a></td>
178
178
  <td align="center"><a href="https://www.linkedin.com/in/merlin-brandes-42328717a/"><img src="https://avatars.githubusercontent.com/u/14237330?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Merlin</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/commits?author=FatalMerlin" title="Documentation">πŸ“–</a></td>
179
179
  <td align="center"><a href="https://darve.sh"><img src="https://avatars.githubusercontent.com/u/22394081?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Darvesh</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/issues?q=author%3Adarvesh" title="Bug reports">πŸ›</a> <a href="https://github.com/grammyjs/grammY/commits?author=darvesh" title="Code">πŸ’»</a> <a href="https://github.com/grammyjs/grammY/pulls?q=is%3Apr+reviewed-by%3Adarvesh" title="Reviewed Pull Requests">πŸ‘€</a></td>
180
- <td align="center"><a href="http://telegram.me/dcdunkan"><img src="https://avatars.githubusercontent.com/u/70066170?v=4?s=100" width="100px;" alt=""/><br /><sub><b>dcdunkan</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/issues?q=author%3Adcdunkan" title="Bug reports">πŸ›</a> <a href="https://github.com/grammyjs/grammY/commits?author=dcdunkan" title="Code">πŸ’»</a> <a href="#plugin-dcdunkan" title="Plugin/utility libraries">πŸ”Œ</a> <a href="https://github.com/grammyjs/grammY/pulls?q=is%3Apr+reviewed-by%3Adcdunkan" title="Reviewed Pull Requests">πŸ‘€</a> <a href="https://github.com/grammyjs/grammY/commits?author=dcdunkan" title="Documentation">πŸ“–</a></td>
180
+ <td align="center"><a href="http://telegram.me/dcdunkan"><img src="https://avatars.githubusercontent.com/u/70066170?v=4?s=100" width="100px;" alt=""/><br /><sub><b>dcdunkan</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/issues?q=author%3Adcdunkan" title="Bug reports">πŸ›</a> <a href="https://github.com/grammyjs/grammY/commits?author=dcdunkan" title="Code">πŸ’»</a> <a href="#plugin-dcdunkan" title="Plugin/utility libraries">πŸ”Œ</a> <a href="https://github.com/grammyjs/grammY/pulls?q=is%3Apr+reviewed-by%3Adcdunkan" title="Reviewed Pull Requests">πŸ‘€</a> <a href="https://github.com/grammyjs/grammY/commits?author=dcdunkan" title="Documentation">πŸ“–</a> <a href="#ideas-dcdunkan" title="Ideas, Planning, & Feedback">πŸ€”</a> <a href="#infra-dcdunkan" title="Infrastructure (Hosting, Build-Tools, etc)">πŸš‡</a></td>
181
181
  <td align="center"><a href="https://xuann.wang/"><img src="https://avatars.githubusercontent.com/u/44045911?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Kid</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/commits?author=kidonng" title="Documentation">πŸ“–</a> <a href="#translation-kidonng" title="Translation">🌍</a></td>
182
182
  <td align="center"><a href="http://slava.fomin.io/"><img src="https://avatars.githubusercontent.com/u/1702725?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Slava Fomin II</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/issues?q=author%3Aslavafomin" title="Bug reports">πŸ›</a> <a href="https://github.com/grammyjs/grammY/commits?author=slavafomin" title="Documentation">πŸ“–</a></td>
183
183
  <td align="center"><a href="https://kikobeats.com/"><img src="https://avatars.githubusercontent.com/u/2096101?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Kiko Beats</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/commits?author=Kikobeats" title="Documentation">πŸ“–</a></td>
184
184
  </tr>
185
185
  <tr>
186
186
  <td align="center"><a href="http://///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////kraftwerk28.pp.ua"><img src="https://avatars.githubusercontent.com/u/31807671?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Vsevolod</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/commits?author=kraftwerk28" title="Code">πŸ’»</a> <a href="#ideas-kraftwerk28" title="Ideas, Planning, & Feedback">πŸ€”</a> <a href="https://github.com/grammyjs/grammY/pulls?q=is%3Apr+reviewed-by%3Akraftwerk28" title="Reviewed Pull Requests">πŸ‘€</a></td>
187
- <td align="center"><a href="https://github.com/habemuscode"><img src="https://avatars.githubusercontent.com/u/34692207?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Habemuscode</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/pulls?q=is%3Apr+reviewed-by%3Ahabemuscode" title="Reviewed Pull Requests">πŸ‘€</a> <a href="https://github.com/grammyjs/grammY/commits?author=habemuscode" title="Documentation">πŸ“–</a></td>
187
+ <td align="center"><a href="https://github.com/habemuscode"><img src="https://avatars.githubusercontent.com/u/34692207?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Habemuscode</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/pulls?q=is%3Apr+reviewed-by%3Ahabemuscode" title="Reviewed Pull Requests">πŸ‘€</a> <a href="https://github.com/grammyjs/grammY/commits?author=habemuscode" title="Documentation">πŸ“–</a> <a href="#translation-habemuscode" title="Translation">🌍</a></td>
188
188
  <td align="center"><a href="https://borodutch.com/"><img src="https://avatars.githubusercontent.com/u/3192028?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Nikita Kolmogorov</b></sub></a><br /><a href="#plugin-backmeupplz" title="Plugin/utility libraries">πŸ”Œ</a></td>
189
189
  <td align="center"><a href="http://glukki.ru"><img src="https://avatars.githubusercontent.com/u/140462?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Vitaliy Meshchaninov</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/issues?q=author%3Aglukki" title="Bug reports">πŸ›</a> <a href="https://github.com/grammyjs/grammY/commits?author=glukki" title="Code">πŸ’»</a></td>
190
190
  <td align="center"><a href="https://github.com/dilyanpalauzov"><img src="https://avatars.githubusercontent.com/u/4992947?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Дилян ΠŸΠ°Π»Π°ΡƒΠ·ΠΎΠ²</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/issues?q=author%3Adilyanpalauzov" title="Bug reports">πŸ›</a> <a href="https://github.com/grammyjs/grammY/commits?author=dilyanpalauzov" title="Code">πŸ’»</a></td>
191
191
  <td align="center"><a href="https://github.com/lmx-Hexagram"><img src="https://avatars.githubusercontent.com/u/52130356?v=4?s=100" width="100px;" alt=""/><br /><sub><b>lmx-Hexagram</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/commits?author=lmx-Hexagram" title="Documentation">πŸ“–</a></td>
192
- <td align="center"><a href="https://github.com/IlyaSemenov"><img src="https://avatars.githubusercontent.com/u/128121?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ilya Semenov</b></sub></a><br /><a href="#ideas-IlyaSemenov" title="Ideas, Planning, & Feedback">πŸ€”</a> <a href="https://github.com/grammyjs/grammY/pulls?q=is%3Apr+reviewed-by%3AIlyaSemenov" title="Reviewed Pull Requests">πŸ‘€</a></td>
192
+ <td align="center"><a href="https://github.com/IlyaSemenov"><img src="https://avatars.githubusercontent.com/u/128121?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ilya Semenov</b></sub></a><br /><a href="#ideas-IlyaSemenov" title="Ideas, Planning, & Feedback">πŸ€”</a> <a href="https://github.com/grammyjs/grammY/pulls?q=is%3Apr+reviewed-by%3AIlyaSemenov" title="Reviewed Pull Requests">πŸ‘€</a> <a href="https://github.com/grammyjs/grammY/commits?author=IlyaSemenov" title="Code">πŸ’»</a></td>
193
193
  </tr>
194
194
  <tr>
195
195
  <td align="center"><a href="https://github.com/abdollahzadehAli"><img src="https://avatars.githubusercontent.com/u/96317431?v=4?s=100" width="100px;" alt=""/><br /><sub><b>abdollahzadehAli</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/commits?author=abdollahzadehAli" title="Documentation">πŸ“–</a> <a href="#example-abdollahzadehAli" title="Examples">πŸ’‘</a></td>
@@ -197,6 +197,15 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
197
197
  <td align="center"><a href="https://github.com/Scrip7"><img src="https://avatars.githubusercontent.com/u/37535505?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Hesoyam</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/commits?author=Scrip7" title="Documentation">πŸ“–</a></td>
198
198
  <td align="center"><a href="http://yrz.am"><img src="https://avatars.githubusercontent.com/u/96742416?v=4?s=100" width="100px;" alt=""/><br /><sub><b>yrzam</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/issues?q=author%3Ayrzam" title="Bug reports">πŸ›</a></td>
199
199
  <td align="center"><a href="https://github.com/drmikecrowe"><img src="https://avatars.githubusercontent.com/u/90312?v=4?s=100" width="100px;" alt=""/><br /><sub><b>drmikecrowe</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/pulls?q=is%3Apr+reviewed-by%3Adrmikecrowe" title="Reviewed Pull Requests">πŸ‘€</a></td>
200
+ <td align="center"><a href="https://rys.pw"><img src="https://avatars.githubusercontent.com/u/1641362?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Martin</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/commits?author=C0rn3j" title="Documentation">πŸ“–</a></td>
201
+ <td align="center"><a href="http://pavelpolyakov.com/"><img src="https://avatars.githubusercontent.com/u/839290?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Pavel</b></sub></a><br /><a href="#example-PavelPolyakov" title="Examples">πŸ’‘</a></td>
202
+ </tr>
203
+ <tr>
204
+ <td align="center"><a href="https://youtube.com/thorwebdev"><img src="https://avatars.githubusercontent.com/u/5748289?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Thor ι›·η₯ž Schaeff</b></sub></a><br /><a href="#example-thorwebdev" title="Examples">πŸ’‘</a></td>
205
+ <td align="center"><a href="https://github.com/x066it"><img src="https://avatars.githubusercontent.com/u/75589380?v=4?s=100" width="100px;" alt=""/><br /><sub><b>x066it</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/issues?q=author%3Ax066it" title="Bug reports">πŸ›</a> <a href="https://github.com/grammyjs/grammY/pulls?q=is%3Apr+reviewed-by%3Ax066it" title="Reviewed Pull Requests">πŸ‘€</a></td>
206
+ <td align="center"><a href="https://github.com/kolay-v"><img src="https://avatars.githubusercontent.com/u/49853802?v=4?s=100" width="100px;" alt=""/><br /><sub><b>kolay</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/pulls?q=is%3Apr+reviewed-by%3Akolay-v" title="Reviewed Pull Requests">πŸ‘€</a></td>
207
+ <td align="center"><a href="https://enepom.com/"><img src="https://avatars.githubusercontent.com/u/2511553?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Evgeny Nepomnyashchiy</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/pulls?q=is%3Apr+reviewed-by%3Apizzaeater" title="Reviewed Pull Requests">πŸ‘€</a></td>
208
+ <td align="center"><a href="https://github.com/anantakrishna"><img src="https://avatars.githubusercontent.com/u/6065071?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ananta Krsna dasa</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/commits?author=anantakrishna" title="Documentation">πŸ“–</a></td>
200
209
  </tr>
201
210
  </table>
202
211
 
package/out/composer.d.ts CHANGED
@@ -1,5 +1,6 @@
1
- import { type Context } from "./context.js";
1
+ import { type AliasProps, type Context } from "./context.js";
2
2
  import { type Filter, type FilterQuery } from "./filter.js";
3
+ import { type Chat } from "./platform.node.js";
3
4
  declare type MaybePromise<T> = T | Promise<T>;
4
5
  declare type MaybeArray<T> = T | T[];
5
6
  declare type StringWithSuggestions<S extends string> = (string & {}) | S;
@@ -212,7 +213,7 @@ export declare class Composer<C extends Context> implements MiddlewareObj<C> {
212
213
  * @param trigger The text to look for
213
214
  * @param middleware The middleware to register
214
215
  */
215
- hears(trigger: MaybeArray<string | RegExp>, ...middleware: Array<Middleware<HearsContext<C>>>): Composer<HearsContext<C>>;
216
+ hears(trigger: MaybeArray<string | RegExp>, ...middleware: Array<HearsMiddleware<C>>): Composer<HearsContext<C>>;
216
217
  /**
217
218
  * Registers some middleware that will only be executed when a certain
218
219
  * command is found.
@@ -268,7 +269,39 @@ export declare class Composer<C extends Context> implements MiddlewareObj<C> {
268
269
  * @param command The command to look for
269
270
  * @param middleware The middleware to register
270
271
  */
271
- command<S extends string>(command: MaybeArray<StringWithSuggestions<S | "start" | "help" | "settings">>, ...middleware: Array<Middleware<CommandContext<C>>>): Composer<CommandContext<C>>;
272
+ command<S extends string>(command: MaybeArray<StringWithSuggestions<S | "start" | "help" | "settings">>, ...middleware: Array<CommandMiddleware<C>>): Composer<CommandContext<C>>;
273
+ /**
274
+ * Registers some middleware for certain chat types only. For example, you
275
+ * can use this method to only receive updates from private chats. The four
276
+ * chat types are `"channel"`, `"supergroup"`, `"group"`, and `"private"`.
277
+ * This is especially useful when combined with other filtering logic. For
278
+ * example, this is how can you respond to `/start` commands only from
279
+ * private chats:
280
+ * ```ts
281
+ * bot.chatType("private").command("start", ctx => { ... })
282
+ * ```
283
+ *
284
+ * Naturally, you can also use this method on its own.
285
+ * ```ts
286
+ * // Private chats only
287
+ * bot.chatType("private", ctx => { ... });
288
+ * // Channels only
289
+ * bot.chatType("channel", ctx => { ... });
290
+ * ```
291
+ *
292
+ * You can pass an array of chat types if you want your middleware to run
293
+ * for any of several provided chat types.
294
+ * ```ts
295
+ * // Groups and supergroups only
296
+ * bot.chatType(["group", "supergroup"], ctx => { ... });
297
+ * ```
298
+ * [Remember](https://grammy.dev/guide/context.html#shortcuts) also that you
299
+ * can access the chat type via `ctx.chat.type`.
300
+ *
301
+ * @param chatType The chat type
302
+ * @param middleware The middleware to register
303
+ */
304
+ chatType<T extends Chat["type"]>(chatType: MaybeArray<T>, ...middleware: Array<Middleware<ChatTypeContext<C, T>>>): Composer<ChatTypeContext<C, T>>;
272
305
  /**
273
306
  * Registers some middleware for callback queries, i.e. the updates that
274
307
  * Telegram delivers to your bot when a user clicks an inline button (that
@@ -309,7 +342,7 @@ export declare class Composer<C extends Context> implements MiddlewareObj<C> {
309
342
  * @param trigger The string to look for in the payload
310
343
  * @param middleware The middleware to register
311
344
  */
312
- callbackQuery(trigger: MaybeArray<string | RegExp>, ...middleware: Array<Middleware<Filter<C, "callback_query:data">>>): Composer<Filter<C, "callback_query:data">>;
345
+ callbackQuery(trigger: MaybeArray<string | RegExp>, ...middleware: Array<CallbackQueryMiddleware<C>>): Composer<CallbackQueryContext<C>>;
313
346
  /**
314
347
  * Registers some middleware for game queries, i.e. the updates that
315
348
  * Telegram delivers to your bot when a user clicks an inline button for the
@@ -328,7 +361,7 @@ export declare class Composer<C extends Context> implements MiddlewareObj<C> {
328
361
  * @param trigger The string to look for in the payload
329
362
  * @param middleware The middleware to register
330
363
  */
331
- gameQuery(trigger: MaybeArray<string | RegExp>, ...middleware: Array<Middleware<Filter<C, "callback_query:game_short_name">>>): Composer<Filter<C, "callback_query:game_short_name">>;
364
+ gameQuery(trigger: MaybeArray<string | RegExp>, ...middleware: Array<GameQueryMiddleware<C>>): Composer<GameQueryContext<C>>;
332
365
  /**
333
366
  * Registers middleware for inline queries. Telegram sends an inline query
334
367
  * to your bot whenever a user types β€œ@your_bot_name ...” into a text field
@@ -351,7 +384,7 @@ export declare class Composer<C extends Context> implements MiddlewareObj<C> {
351
384
  * @param trigger The inline query text to match
352
385
  * @param middleware The middleware to register
353
386
  */
354
- inlineQuery(trigger: MaybeArray<string | RegExp>, ...middleware: Array<Middleware<Filter<C, "inline_query">>>): Composer<Filter<C, "inline_query">>;
387
+ inlineQuery(trigger: MaybeArray<string | RegExp>, ...middleware: Array<InlineQueryMiddleware<C>>): Composer<InlineQueryContext<C>>;
355
388
  /**
356
389
  * > This is an advanced method of grammY.
357
390
  *
@@ -553,10 +586,27 @@ export declare class Composer<C extends Context> implements MiddlewareObj<C> {
553
586
  */
554
587
  errorBoundary(errorHandler: (error: BotError<C>, next: NextFunction) => MaybePromise<unknown>, ...middleware: Array<Middleware<C>>): Composer<C>;
555
588
  }
556
- declare type HearsContext<C extends Context> = Filter<Omit<C, "match"> & {
589
+ export declare type HearsContext<C extends Context> = Filter<Omit<C, "match"> & {
557
590
  match: Extract<C["match"], string | RegExpMatchArray>;
558
591
  }, ":text" | ":caption">;
559
- declare type CommandContext<C extends Context> = Filter<Omit<C, "match"> & {
592
+ export declare type CommandContext<C extends Context> = Filter<Omit<C, "match"> & {
560
593
  match: Extract<C["match"], string>;
561
594
  }, ":entities:bot_command">;
595
+ export declare type CallbackQueryContext<C extends Context> = Filter<C, "callback_query:data">;
596
+ export declare type GameQueryContext<C extends Context> = Filter<C, "callback_query:game_short_name">;
597
+ export declare type InlineQueryContext<C extends Context> = Filter<C, "inline_query">;
598
+ export declare type ChatTypeContext<C extends Context, T extends Chat["type"]> = C & Record<"update", ChatTypeUpdate<T>> & ChatType<T> & ChatTypeRecord<"msg", T> & AliasProps<ChatTypeUpdate<T>>;
599
+ declare type ChatTypeUpdate<T extends Chat["type"]> = ChatTypeRecord<"message" | "edited_message" | "channel_post" | "edited_channel_post" | "my_chat_member" | "chat_member" | "chat_join_request", T> & Partial<Record<"callback_query", ChatTypeRecord<"message", T>>>;
600
+ declare type ChatTypeRecord<K extends string, T extends Chat["type"]> = Partial<Record<K, ChatType<T>>>;
601
+ interface ChatType<T extends Chat["type"]> {
602
+ chat: {
603
+ type: T;
604
+ };
605
+ }
606
+ export declare type HearsMiddleware<C extends Context> = Middleware<HearsContext<C>>;
607
+ export declare type CommandMiddleware<C extends Context> = Middleware<CommandContext<C>>;
608
+ export declare type CallbackQueryMiddleware<C extends Context> = Middleware<CallbackQueryContext<C>>;
609
+ export declare type GameQueryMiddleware<C extends Context> = Middleware<GameQueryContext<C>>;
610
+ export declare type InlineQueryMiddleware<C extends Context> = Middleware<InlineQueryContext<C>>;
611
+ export declare type ChatTypeMiddleware<C extends Context, T extends Chat["type"]> = Middleware<ChatTypeContext<C, T>>;
562
612
  export {};
package/out/composer.js CHANGED
@@ -317,6 +317,41 @@ class Composer {
317
317
  });
318
318
  }, ...middleware);
319
319
  }
320
+ /**
321
+ * Registers some middleware for certain chat types only. For example, you
322
+ * can use this method to only receive updates from private chats. The four
323
+ * chat types are `"channel"`, `"supergroup"`, `"group"`, and `"private"`.
324
+ * This is especially useful when combined with other filtering logic. For
325
+ * example, this is how can you respond to `/start` commands only from
326
+ * private chats:
327
+ * ```ts
328
+ * bot.chatType("private").command("start", ctx => { ... })
329
+ * ```
330
+ *
331
+ * Naturally, you can also use this method on its own.
332
+ * ```ts
333
+ * // Private chats only
334
+ * bot.chatType("private", ctx => { ... });
335
+ * // Channels only
336
+ * bot.chatType("channel", ctx => { ... });
337
+ * ```
338
+ *
339
+ * You can pass an array of chat types if you want your middleware to run
340
+ * for any of several provided chat types.
341
+ * ```ts
342
+ * // Groups and supergroups only
343
+ * bot.chatType(["group", "supergroup"], ctx => { ... });
344
+ * ```
345
+ * [Remember](https://grammy.dev/guide/context.html#shortcuts) also that you
346
+ * can access the chat type via `ctx.chat.type`.
347
+ *
348
+ * @param chatType The chat type
349
+ * @param middleware The middleware to register
350
+ */
351
+ chatType(chatType, ...middleware) {
352
+ const set = new Set(toArray(chatType));
353
+ return this.filter((ctx) => { var _a; return ((_a = ctx.chat) === null || _a === void 0 ? void 0 : _a.type) !== undefined && set.has(ctx.chat.type); }, ...middleware);
354
+ }
320
355
  /**
321
356
  * Registers some middleware for callback queries, i.e. the updates that
322
357
  * Telegram delivers to your bot when a user clicks an inline button (that
@@ -618,7 +653,7 @@ class Composer {
618
653
  }
619
654
  }
620
655
  exports.Composer = Composer;
621
- // === Util functions and types
656
+ // === Util functions
622
657
  function triggerFn(trigger) {
623
658
  return toArray(trigger).map((t) => typeof t === "string"
624
659
  ? (txt) => (txt === t ? t : null)
package/out/context.d.ts CHANGED
@@ -4,7 +4,7 @@ import { type Chat, type ChatPermissions, type InlineQueryResult, type InputFile
4
4
  declare type Other<M extends Methods<RawApi>, X extends string = never> = OtherApi<RawApi, M, X>;
5
5
  declare type SnakeToCamelCase<S extends string> = S extends `${infer L}_${infer R}` ? `${L}${Capitalize<SnakeToCamelCase<R>>}` : S;
6
6
  export declare type AliasProps<U> = {
7
- [key in string & keyof U as SnakeToCamelCase<key>]: U[key];
7
+ [K in string & keyof U as SnakeToCamelCase<K>]: U[K];
8
8
  };
9
9
  declare type RenamedUpdate = AliasProps<Omit<Update, "update_id">>;
10
10
  /**
@@ -106,14 +106,14 @@ export declare class Context implements RenamedUpdate {
106
106
  /** Alias for `ctx.update.chat_join_request` */
107
107
  get chatJoinRequest(): import("@grammyjs/types/manage").ChatJoinRequest | undefined;
108
108
  /**
109
- * Get message object from whereever possible. Alias for `ctx.message ??
109
+ * Get message object from wherever possible. Alias for `ctx.message ??
110
110
  * ctx.editedMessage ?? ctx.callbackQuery?.message ?? ctx.channelPost ??
111
111
  * ctx.editedChannelPost`
112
112
  */
113
113
  get msg(): Message | undefined;
114
114
  /**
115
- * Get chat object from whereever possible. Alias for `(this.msg ??
116
- * this.myChatMember ?? this.chatMember ?? this.chatJoinRequest)?.chat`
115
+ * Get chat object from wherever possible. Alias for `(ctx.msg ??
116
+ * ctx.myChatMember ?? ctx.chatMember ?? ctx.chatJoinRequest)?.chat`
117
117
  */
118
118
  get chat(): Chat | undefined;
119
119
  /**
@@ -122,14 +122,14 @@ export declare class Context implements RenamedUpdate {
122
122
  */
123
123
  get senderChat(): Chat | undefined;
124
124
  /**
125
- * Get message author from whereever possible. Alias for
125
+ * Get message author from wherever possible. Alias for
126
126
  * `(ctx.callbackQuery?? ctx.inlineQuery ?? ctx.shippingQuery ??
127
127
  * ctx.preCheckoutQuery ?? ctx.chosenInlineResult ?? ctx.msg ??
128
- * this.myChatMember ?? this.chatMember ?? this.chatJoinRequest)?.from`
128
+ * ctx.myChatMember ?? ctx.chatMember ?? ctx.chatJoinRequest)?.from`
129
129
  */
130
130
  get from(): User | undefined;
131
131
  /**
132
- * Get inline message ID from whereever possible. Alias for
132
+ * Get inline message ID from wherever possible. Alias for
133
133
  * `(ctx.callbackQuery ?? ctx.chosenInlineResult)?.inline_message_id`
134
134
  */
135
135
  get inlineMessageId(): string | undefined;
package/out/context.js CHANGED
@@ -116,7 +116,7 @@ class Context {
116
116
  }
117
117
  // AGGREGATION SHORTCUTS
118
118
  /**
119
- * Get message object from whereever possible. Alias for `ctx.message ??
119
+ * Get message object from wherever possible. Alias for `ctx.message ??
120
120
  * ctx.editedMessage ?? ctx.callbackQuery?.message ?? ctx.channelPost ??
121
121
  * ctx.editedChannelPost`
122
122
  */
@@ -126,8 +126,8 @@ class Context {
126
126
  return ((_e = (_d = (_b = (_a = this.message) !== null && _a !== void 0 ? _a : this.editedMessage) !== null && _b !== void 0 ? _b : (_c = this.callbackQuery) === null || _c === void 0 ? void 0 : _c.message) !== null && _d !== void 0 ? _d : this.channelPost) !== null && _e !== void 0 ? _e : this.editedChannelPost);
127
127
  }
128
128
  /**
129
- * Get chat object from whereever possible. Alias for `(this.msg ??
130
- * this.myChatMember ?? this.chatMember ?? this.chatJoinRequest)?.chat`
129
+ * Get chat object from wherever possible. Alias for `(ctx.msg ??
130
+ * ctx.myChatMember ?? ctx.chatMember ?? ctx.chatJoinRequest)?.chat`
131
131
  */
132
132
  get chat() {
133
133
  var _a, _b, _c, _d;
@@ -143,10 +143,10 @@ class Context {
143
143
  return (_a = this.msg) === null || _a === void 0 ? void 0 : _a.sender_chat;
144
144
  }
145
145
  /**
146
- * Get message author from whereever possible. Alias for
146
+ * Get message author from wherever possible. Alias for
147
147
  * `(ctx.callbackQuery?? ctx.inlineQuery ?? ctx.shippingQuery ??
148
148
  * ctx.preCheckoutQuery ?? ctx.chosenInlineResult ?? ctx.msg ??
149
- * this.myChatMember ?? this.chatMember ?? this.chatJoinRequest)?.from`
149
+ * ctx.myChatMember ?? ctx.chatMember ?? ctx.chatJoinRequest)?.from`
150
150
  */
151
151
  get from() {
152
152
  var _a, _b, _c, _d, _e, _f, _g, _h, _j;
@@ -154,7 +154,7 @@ class Context {
154
154
  return (_j = ((_h = (_g = (_f = (_e = (_d = (_c = (_b = (_a = this.callbackQuery) !== null && _a !== void 0 ? _a : this.inlineQuery) !== null && _b !== void 0 ? _b : this.shippingQuery) !== null && _c !== void 0 ? _c : this.preCheckoutQuery) !== null && _d !== void 0 ? _d : this.chosenInlineResult) !== null && _e !== void 0 ? _e : this.msg) !== null && _f !== void 0 ? _f : this.myChatMember) !== null && _g !== void 0 ? _g : this.chatMember) !== null && _h !== void 0 ? _h : this.chatJoinRequest)) === null || _j === void 0 ? void 0 : _j.from;
155
155
  }
156
156
  /**
157
- * Get inline message ID from whereever possible. Alias for
157
+ * Get inline message ID from wherever possible. Alias for
158
158
  * `(ctx.callbackQuery ?? ctx.chosenInlineResult)?.inline_message_id`
159
159
  */
160
160
  get inlineMessageId() {
@@ -3,38 +3,52 @@ import { type IncomingMessage, type ServerResponse } from "http";
3
3
  export declare const adapters: {
4
4
  http: (req: IncomingMessage, res: ServerResponse) => {
5
5
  update: Promise<any>;
6
+ header: string;
6
7
  end: () => ServerResponse;
7
8
  respond: (json: string) => ServerResponse;
9
+ unauthorized: () => ServerResponse;
8
10
  };
9
11
  https: (req: IncomingMessage, res: ServerResponse) => {
10
12
  update: Promise<any>;
13
+ header: string;
11
14
  end: () => ServerResponse;
12
15
  respond: (json: string) => ServerResponse;
16
+ unauthorized: () => ServerResponse;
13
17
  };
14
18
  express: (req: any, res: any) => {
15
19
  update: Promise<any>;
20
+ header: any;
16
21
  end: () => any;
17
22
  respond: (json: string) => void;
23
+ unauthorized: () => void;
18
24
  };
19
25
  koa: (ctx: any) => {
20
26
  update: Promise<any>;
27
+ header: any;
21
28
  end: () => void;
22
29
  respond: (json: string) => void;
30
+ unauthorized: () => void;
23
31
  };
24
32
  fastify: (req: any, reply: any) => {
25
33
  update: Promise<any>;
34
+ header: any;
26
35
  end: () => any;
27
36
  respond: (json: string) => any;
37
+ unauthorized: () => any;
28
38
  };
29
39
  worktop: (req: any, res: any) => {
30
40
  update: Promise<any>;
41
+ header: any;
31
42
  end: () => any;
32
43
  respond: (json: string) => any;
44
+ unauthorized: () => any;
33
45
  };
34
46
  "aws-lambda": (event: any, _context: any, callback: any) => {
35
47
  update: any;
48
+ header: any;
36
49
  end: () => any;
37
50
  respond: (json: string) => any;
51
+ unauthorized: () => any;
38
52
  };
39
53
  };
40
54
  export declare const defaultAdapter = "express";
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.defaultAdapter = exports.adapters = void 0;
4
+ const SECRET_HEADER = "X-Telegram-Bot-Api-Secret-Token";
4
5
  /** Node.js native 'http' and 'https' modules */
5
6
  const http = (req, res) => ({
6
7
  update: new Promise((resolve, reject) => {
@@ -10,21 +11,28 @@ const http = (req, res) => ({
10
11
  resolve(JSON.parse(raw));
11
12
  }).once("error", reject);
12
13
  }),
14
+ header: String(req.headers[SECRET_HEADER.toLowerCase()]),
13
15
  end: () => res.end(),
14
16
  respond: (json) => res.writeHead(200, { "Content-Type": "application/json" }).end(json),
17
+ unauthorized: () => res.writeHead(401).end("secret token is wrong"),
15
18
  });
16
19
  /** express web framework */
17
20
  const express = (req, res) => ({
18
21
  update: Promise.resolve(req.body),
22
+ header: req.header(SECRET_HEADER),
19
23
  end: () => res.end(),
20
24
  respond: (json) => {
21
25
  res.set("Content-Type", "application/json");
22
26
  res.send(json);
23
27
  },
28
+ unauthorized: () => {
29
+ res.send(401, "secret token is wrong");
30
+ },
24
31
  });
25
32
  /** koa web framework */
26
33
  const koa = (ctx) => ({
27
34
  update: Promise.resolve(ctx.request.body),
35
+ header: ctx.get(SECRET_HEADER),
28
36
  end: () => {
29
37
  ctx.body = "";
30
38
  },
@@ -32,24 +40,33 @@ const koa = (ctx) => ({
32
40
  ctx.set("Content-Type", "application/json");
33
41
  ctx.response.body = json;
34
42
  },
43
+ unauthorized: () => {
44
+ ctx.status = 401;
45
+ },
35
46
  });
36
47
  /** fastify web framework */
37
48
  const fastify = (req, reply) => ({
38
49
  update: Promise.resolve(req.body),
50
+ header: req.headers[SECRET_HEADER],
39
51
  end: () => reply.status(200).send(),
40
52
  respond: (json) => reply.send(json),
53
+ unauthorized: () => reply.code(401).send("secret token is wrong"),
41
54
  });
42
55
  /** worktop CloudFlare workers framework */
43
56
  const worktop = (req, res) => ({
44
57
  update: Promise.resolve(req.body.json()),
58
+ header: req.headers.get(SECRET_HEADER),
45
59
  end: () => res.end(),
46
60
  respond: (json) => res.send(200, json),
61
+ unauthorized: () => res.send(401, "secret token is wrong"),
47
62
  });
48
63
  /** AWS lambda serverless functions */
49
64
  const awsLambda = (event, _context, callback) => ({
50
65
  update: JSON.parse(event.body),
66
+ header: event.headers[SECRET_HEADER],
51
67
  end: () => callback(null, { statusCode: 200 }),
52
68
  respond: (json) => callback(null, { statusCode: 200, body: json }),
69
+ unauthorized: () => callback(null, { statusCode: 401 }),
53
70
  });
54
71
  // please open a PR if you want to add another
55
72
  exports.adapters = {
@@ -178,8 +178,8 @@ export declare class InlineKeyboard {
178
178
  webApp(text: string, url: string): this;
179
179
  /**
180
180
  * Adds a new login button. This can be used as a replacement for the
181
- * Telegram Login Widget. You must specify an HTTP URL used to automatically
182
- * authorize the user.
181
+ * Telegram Login Widget. You must specify an HTTPS URL used to
182
+ * automatically authorize the user.
183
183
  *
184
184
  * @param text The text to display
185
185
  * @param loginUrl The login URL as string or `LoginUrl` object
@@ -217,8 +217,8 @@ class InlineKeyboard {
217
217
  }
218
218
  /**
219
219
  * Adds a new login button. This can be used as a replacement for the
220
- * Telegram Login Widget. You must specify an HTTP URL used to automatically
221
- * authorize the user.
220
+ * Telegram Login Widget. You must specify an HTTPS URL used to
221
+ * automatically authorize the user.
222
222
  *
223
223
  * @param text The text to display
224
224
  * @param loginUrl The login URL as string or `LoginUrl` object
@@ -62,6 +62,7 @@ function session(options = {}) {
62
62
  ? undefined
63
63
  : (_a = (await storage.read(key))) !== null && _a !== void 0 ? _a : (_b = options.initial) === null || _b === void 0 ? void 0 : _b.call(options);
64
64
  Object.defineProperty(ctx, "session", {
65
+ enumerable: true,
65
66
  get() {
66
67
  if (key === undefined) {
67
68
  const msg = undef("access", getSessionKey);
@@ -153,6 +154,7 @@ function lazySession(options = {}) {
153
154
  return value;
154
155
  }
155
156
  Object.defineProperty(ctx, "session", {
157
+ enumerable: true,
156
158
  get() {
157
159
  if (wrote)
158
160
  return value;
@@ -6,42 +6,52 @@ declare const adapters: {
6
6
  callback: FrameworkAdapter;
7
7
  http: (req: import("http").IncomingMessage, res: import("http").ServerResponse) => {
8
8
  update: Promise<any>;
9
+ header: string;
9
10
  end: () => import("http").ServerResponse;
10
11
  respond: (json: string) => import("http").ServerResponse;
12
+ unauthorized: () => import("http").ServerResponse;
11
13
  };
12
14
  https: (req: import("http").IncomingMessage, res: import("http").ServerResponse) => {
13
15
  update: Promise<any>;
16
+ header: string;
14
17
  end: () => import("http").ServerResponse;
15
18
  respond: (json: string) => import("http").ServerResponse;
19
+ unauthorized: () => import("http").ServerResponse;
16
20
  };
17
21
  express: (req: any, res: any) => {
18
22
  update: Promise<any>;
23
+ header: any;
19
24
  end: () => any;
20
25
  respond: (json: string) => void;
26
+ unauthorized: () => void;
21
27
  };
22
28
  koa: (ctx: any) => {
23
29
  update: Promise<any>;
30
+ header: any;
24
31
  end: () => void;
25
32
  respond: (json: string) => void;
33
+ unauthorized: () => void;
26
34
  };
27
35
  fastify: (req: any, reply: any) => {
28
36
  update: Promise<any>;
37
+ header: any;
29
38
  end: () => any;
30
39
  respond: (json: string) => any;
40
+ unauthorized: () => any;
31
41
  };
32
42
  worktop: (req: any, res: any) => {
33
43
  update: Promise<any>;
34
- /**
35
- * Middleware for a web framework. Creates a request-response handler for a
36
- * request. The handler will be used to integrate with the compatible framework.
37
- */
44
+ header: any;
38
45
  end: () => any;
39
46
  respond: (json: string) => any;
47
+ unauthorized: () => any;
40
48
  };
41
49
  "aws-lambda": (event: any, _context: any, callback: any) => {
42
50
  update: any;
51
+ header: any;
43
52
  end: () => any;
44
53
  respond: (json: string) => any;
54
+ unauthorized: () => any;
45
55
  };
46
56
  };
47
57
  /**
@@ -59,6 +69,11 @@ interface ReqResHandler {
59
69
  * body
60
70
  */
61
71
  update: Promise<Update>;
72
+ /**
73
+ * X-Telegram-Bot-Api-Secret-Token header of the request, or undefined if
74
+ * not present
75
+ */
76
+ header?: string;
62
77
  /**
63
78
  * Ends the request immediately without body, called after every request
64
79
  * unless a webhook reply was performed
@@ -68,7 +83,12 @@ interface ReqResHandler {
68
83
  * Sends the specified JSON as a payload in the body, used for webhook
69
84
  * replies
70
85
  */
71
- respond: (json: string) => unknown;
86
+ respond: (json: string) => unknown | Promise<unknown>;
87
+ /**
88
+ * Responds that the request is unauthorized due to mismatching
89
+ * X-Telegram-Bot-Api-Secret-Token headers
90
+ */
91
+ unauthorized: () => unknown | Promise<unknown>;
72
92
  /**
73
93
  * Some frameworks (e.g. Deno's std/http `listenAndServe`) assume that
74
94
  * handler returns something
@@ -80,6 +100,14 @@ interface ReqResHandler {
80
100
  * request. The handler will be used to integrate with the compatible framework.
81
101
  */
82
102
  export declare type FrameworkAdapter = (...args: any[]) => ReqResHandler;
103
+ export interface WebhookOptions {
104
+ /** An optional strategy to handle timeouts (default: 'throw') */
105
+ onTimeout?: "throw" | "return" | ((...args: any[]) => unknown);
106
+ /** An optional number of timeout milliseconds (default: 10_000) */
107
+ timeoutMilliseconds?: number;
108
+ /** An optional string to compare to X-Telegram-Bot-Api-Secret-Token */
109
+ secretToken?: string;
110
+ }
83
111
  /**
84
112
  * Creates a callback function that you can pass to a web framework (such as
85
113
  * express) if you want to run your bot via webhooks. Use it like this:
@@ -99,5 +127,6 @@ export declare type FrameworkAdapter = (...args: any[]) => ReqResHandler;
99
127
  * @param onTimeout An optional strategy to handle timeouts (default: 'throw')
100
128
  * @param timeoutMilliseconds An optional number of timeout milliseconds (default: 10_000)
101
129
  */
102
- export declare function webhookCallback<C extends Context = Context>(bot: Bot<C>, adapter?: SupportedFrameworks | FrameworkAdapter, onTimeout?: "throw" | "return" | ((...args: any[]) => unknown), timeoutMilliseconds?: number): (...args: any[]) => Promise<any>;
130
+ export declare function webhookCallback<C extends Context = Context>(bot: Bot<C>, adapter?: SupportedFrameworks | FrameworkAdapter, onTimeout?: WebhookOptions["onTimeout"], timeoutMilliseconds?: WebhookOptions["timeoutMilliseconds"], secretToken?: WebhookOptions["secretToken"]): (...args: any[]) => any;
131
+ export declare function webhookCallback<C extends Context = Context>(bot: Bot<C>, adapter?: SupportedFrameworks | FrameworkAdapter, webhookOptions?: WebhookOptions): (...args: any[]) => any;
103
132
  export {};
@@ -4,31 +4,17 @@ exports.webhookCallback = void 0;
4
4
  const platform_node_js_1 = require("../platform.node.js");
5
5
  const frameworks_node_js_1 = require("./frameworks.node.js");
6
6
  const debugErr = (0, platform_node_js_1.debug)("grammy:error");
7
- const callbackAdapter = (update, callback) => ({
7
+ const callbackAdapter = (update, callback, header, unauthorized = () => callback('"unauthorized"')) => ({
8
8
  update: Promise.resolve(update),
9
9
  respond: callback,
10
+ header,
11
+ unauthorized,
10
12
  });
11
13
  const adapters = { ...frameworks_node_js_1.adapters, callback: callbackAdapter };
12
- /**
13
- * Creates a callback function that you can pass to a web framework (such as
14
- * express) if you want to run your bot via webhooks. Use it like this:
15
- * ```ts
16
- * const app = express() // or whatever you're using
17
- * const bot = new Bot('<token>')
18
- *
19
- * app.use(webhookCallback(bot, 'express'))
20
- * ```
21
- *
22
- * Confer the grammY
23
- * [documentation](https://grammy.dev/guide/deployment-types.html) to read more
24
- * about how to run your bot with webhooks.
25
- *
26
- * @param bot The bot for which to create a callback
27
- * @param adapter An optional string identifying the framework (default: 'express')
28
- * @param onTimeout An optional strategy to handle timeouts (default: 'throw')
29
- * @param timeoutMilliseconds An optional number of timeout milliseconds (default: 10_000)
30
- */
31
- function webhookCallback(bot, adapter = frameworks_node_js_1.defaultAdapter, onTimeout = "throw", timeoutMilliseconds = 10000) {
14
+ function webhookCallback(bot, adapter = frameworks_node_js_1.defaultAdapter, onTimeout = "throw", timeoutMilliseconds = 10000, secretToken) {
15
+ const { onTimeout: timeout = "throw", timeoutMilliseconds: ms = 10000, secretToken: token, } = typeof onTimeout === "object"
16
+ ? onTimeout
17
+ : { onTimeout, timeoutMilliseconds, secretToken };
32
18
  let initialized = false;
33
19
  const server = typeof adapter === "string"
34
20
  ? adapters[adapter]
@@ -39,7 +25,13 @@ function webhookCallback(bot, adapter = frameworks_node_js_1.defaultAdapter, onT
39
25
  await bot.init();
40
26
  initialized = true;
41
27
  }
42
- const { update, respond, end, handlerReturn } = server(...args);
28
+ const { update, respond, unauthorized, end, handlerReturn, header } = server(...args);
29
+ if (header !== token) {
30
+ await unauthorized();
31
+ // TODO: investigate deno bug that happens when this console logging is removed
32
+ console.log(handlerReturn);
33
+ return handlerReturn;
34
+ }
43
35
  let usedWebhookReply = false;
44
36
  const webhookReplyEnvelope = {
45
37
  async send(json) {
@@ -47,11 +39,9 @@ function webhookCallback(bot, adapter = frameworks_node_js_1.defaultAdapter, onT
47
39
  await respond(json);
48
40
  },
49
41
  };
50
- await timeoutIfNecessary(bot.handleUpdate(await update, webhookReplyEnvelope), typeof onTimeout === "function"
51
- ? () => onTimeout(...args)
52
- : onTimeout, timeoutMilliseconds);
53
- if (end !== undefined && !usedWebhookReply)
54
- end();
42
+ await timeoutIfNecessary(bot.handleUpdate(await update, webhookReplyEnvelope), typeof timeout === "function" ? () => timeout(...args) : timeout, ms);
43
+ if (!usedWebhookReply)
44
+ end === null || end === void 0 ? void 0 : end();
55
45
  return handlerReturn;
56
46
  };
57
47
  }
package/out/core/api.d.ts CHANGED
@@ -73,16 +73,16 @@ export declare class Api<R extends RawApi = RawApi> {
73
73
  */
74
74
  getUpdates(other?: Other<R, "getUpdates">, signal?: AbortSignal): Promise<import("@grammyjs/types/update").Update[]>;
75
75
  /**
76
- * Use this method to specify a url and receive incoming updates via an outgoing webhook. Whenever there is an update for the bot, we will send an HTTPS POST request to the specified url, containing a JSON-serialized Update. In case of an unsuccessful request, we will give up after a reasonable amount of attempts. Returns True on success.
76
+ * Use this method to specify a URL and receive incoming updates via an outgoing webhook. Whenever there is an update for the bot, we will send an HTTPS POST request to the specified URL, containing a JSON-serialized Update. In case of an unsuccessful request, we will give up after a reasonable amount of attempts. Returns True on success.
77
77
  *
78
- * If you'd like to make sure that the Webhook request comes from Telegram, we recommend using a secret path in the URL, e.g. https://www.example.com/<token>. Since nobody else knows your bot's token, you can be pretty sure it's us.
78
+ * If you'd like to make sure that the webhook was set by you, you can specify secret data in the parameter secret_token. If specified, the request will contain a header β€œX-Telegram-Bot-Api-Secret-Token” with the secret token as content.
79
79
  *
80
80
  * Notes
81
81
  * 1. You will not be able to receive updates using getUpdates for as long as an outgoing webhook is set up.
82
82
  * 2. To use a self-signed certificate, you need to upload your public key certificate using certificate parameter. Please upload as InputFile, sending a String will not work.
83
83
  * 3. Ports currently supported for Webhooks: 443, 80, 88, 8443.
84
84
  *
85
- * NEW! If you're having any trouble setting up webhooks, please check out this amazing guide to Webhooks.
85
+ * If you're having any trouble setting up webhooks, please check out this amazing guide to webhooks.
86
86
  *
87
87
  * @param url HTTPS url to send updates to. Use an empty string to remove webhook integration
88
88
  * @param other Optional remaining parameters, confer the official reference below
@@ -1004,6 +1004,21 @@ export declare class Api<R extends RawApi = RawApi> {
1004
1004
  * **Official reference:** https://core.telegram.org/bots/api#sendinvoice
1005
1005
  */
1006
1006
  sendInvoice(chat_id: number | string, title: string, description: string, payload: string, provider_token: string, currency: string, prices: readonly LabeledPrice[], other?: Other<R, "sendInvoice", "chat_id" | "title" | "description" | "payload" | "provider_token" | "currency" | "prices">, signal?: AbortSignal): Promise<import("@grammyjs/types/message").Message.InvoiceMessage>;
1007
+ /**
1008
+ * Use this method to create a link for an invoice. Returns the created invoice link as String on success.
1009
+ *
1010
+ * @param title Product name, 1-32 characters
1011
+ * @param description Product description, 1-255 characters
1012
+ * @param payload Bot-defined invoice payload, 1-128 bytes. This will not be displayed to the user, use for your internal processes.
1013
+ * @param provider_token Payment provider token, obtained via BotFather
1014
+ * @param currency Three-letter ISO 4217 currency code, see more on currencies
1015
+ * @param prices Price breakdown, a JSON-serialized list of components (e.g. product price, tax, discount, delivery cost, delivery tax, bonus, etc.)
1016
+ * @param other Optional remaining parameters, confer the official reference below
1017
+ * @param signal Optional `AbortSignal` to cancel the request
1018
+ *
1019
+ * **Official reference:** https://core.telegram.org/bots/api#createinvoicelink
1020
+ */
1021
+ createInvoiceLink(title: string, description: string, payload: string, provider_token: string, currency: string, prices: LabeledPrice[], other?: Other<R, "createInvoiceLink", "title" | "description" | "payload" | "provider_token" | "currency" | "prices">, signal?: AbortSignal): Promise<string>;
1007
1022
  /**
1008
1023
  * If you sent an invoice requesting a shipping address and the parameter is_flexible was specified, the Bot API will send an Update with a shipping_query field to the bot. Use this method to reply to shipping queries. On success, True is returned.
1009
1024
  *
package/out/core/api.js CHANGED
@@ -44,16 +44,16 @@ class Api {
44
44
  return this.raw.getUpdates({ ...other }, signal);
45
45
  }
46
46
  /**
47
- * Use this method to specify a url and receive incoming updates via an outgoing webhook. Whenever there is an update for the bot, we will send an HTTPS POST request to the specified url, containing a JSON-serialized Update. In case of an unsuccessful request, we will give up after a reasonable amount of attempts. Returns True on success.
47
+ * Use this method to specify a URL and receive incoming updates via an outgoing webhook. Whenever there is an update for the bot, we will send an HTTPS POST request to the specified URL, containing a JSON-serialized Update. In case of an unsuccessful request, we will give up after a reasonable amount of attempts. Returns True on success.
48
48
  *
49
- * If you'd like to make sure that the Webhook request comes from Telegram, we recommend using a secret path in the URL, e.g. https://www.example.com/<token>. Since nobody else knows your bot's token, you can be pretty sure it's us.
49
+ * If you'd like to make sure that the webhook was set by you, you can specify secret data in the parameter secret_token. If specified, the request will contain a header β€œX-Telegram-Bot-Api-Secret-Token” with the secret token as content.
50
50
  *
51
51
  * Notes
52
52
  * 1. You will not be able to receive updates using getUpdates for as long as an outgoing webhook is set up.
53
53
  * 2. To use a self-signed certificate, you need to upload your public key certificate using certificate parameter. Please upload as InputFile, sending a String will not work.
54
54
  * 3. Ports currently supported for Webhooks: 443, 80, 88, 8443.
55
55
  *
56
- * NEW! If you're having any trouble setting up webhooks, please check out this amazing guide to Webhooks.
56
+ * If you're having any trouble setting up webhooks, please check out this amazing guide to webhooks.
57
57
  *
58
58
  * @param url HTTPS url to send updates to. Use an empty string to remove webhook integration
59
59
  * @param other Optional remaining parameters, confer the official reference below
@@ -1160,6 +1160,31 @@ class Api {
1160
1160
  ...other,
1161
1161
  }, signal);
1162
1162
  }
1163
+ /**
1164
+ * Use this method to create a link for an invoice. Returns the created invoice link as String on success.
1165
+ *
1166
+ * @param title Product name, 1-32 characters
1167
+ * @param description Product description, 1-255 characters
1168
+ * @param payload Bot-defined invoice payload, 1-128 bytes. This will not be displayed to the user, use for your internal processes.
1169
+ * @param provider_token Payment provider token, obtained via BotFather
1170
+ * @param currency Three-letter ISO 4217 currency code, see more on currencies
1171
+ * @param prices Price breakdown, a JSON-serialized list of components (e.g. product price, tax, discount, delivery cost, delivery tax, bonus, etc.)
1172
+ * @param other Optional remaining parameters, confer the official reference below
1173
+ * @param signal Optional `AbortSignal` to cancel the request
1174
+ *
1175
+ * **Official reference:** https://core.telegram.org/bots/api#createinvoicelink
1176
+ */
1177
+ createInvoiceLink(title, description, payload, provider_token, currency, prices, other, signal) {
1178
+ return this.raw.createInvoiceLink({
1179
+ title,
1180
+ description,
1181
+ payload,
1182
+ provider_token,
1183
+ currency,
1184
+ prices,
1185
+ ...other,
1186
+ }, signal);
1187
+ }
1163
1188
  /**
1164
1189
  * If you sent an invoice requesting a shipping address and the parameter is_flexible was specified, the Bot API will send an Update with a shipping_query field to the bot. Use this method to reply to shipping queries. On success, True is returned.
1165
1190
  *
@@ -11,7 +11,7 @@ const platform_node_js_1 = require("../platform.node.js");
11
11
  * @param payload The payload to analyse
12
12
  */
13
13
  function requiresFormDataUpload(payload) {
14
- return (typeof payload === "object" &&
14
+ return payload instanceof platform_node_js_1.InputFile || (typeof payload === "object" &&
15
15
  payload !== null &&
16
16
  Object.values(payload).some((v) => Array.isArray(v)
17
17
  ? v.some(requiresFormDataUpload)
package/out/filter.d.ts CHANGED
@@ -30,10 +30,14 @@ declare const UPDATE_KEYS: {
30
30
  readonly new_chat_members: {
31
31
  readonly me: {};
32
32
  readonly is_bot: {};
33
+ readonly is_premium: {};
34
+ readonly added_to_attachment_menu: {};
33
35
  };
34
36
  readonly left_chat_member: {
35
37
  readonly me: {};
36
38
  readonly is_bot: {};
39
+ readonly is_premium: {};
40
+ readonly added_to_attachment_menu: {};
37
41
  };
38
42
  readonly group_chat_created: {};
39
43
  readonly supergroup_chat_created: {};
@@ -113,10 +117,14 @@ declare const UPDATE_KEYS: {
113
117
  readonly new_chat_members: {
114
118
  readonly me: {};
115
119
  readonly is_bot: {};
120
+ readonly is_premium: {};
121
+ readonly added_to_attachment_menu: {};
116
122
  };
117
123
  readonly left_chat_member: {
118
124
  readonly me: {};
119
125
  readonly is_bot: {};
126
+ readonly is_premium: {};
127
+ readonly added_to_attachment_menu: {};
120
128
  };
121
129
  readonly group_chat_created: {};
122
130
  readonly supergroup_chat_created: {};
@@ -344,12 +352,16 @@ declare const UPDATE_KEYS: {
344
352
  readonly from: {
345
353
  readonly me: {};
346
354
  readonly is_bot: {};
355
+ readonly is_premium: {};
356
+ readonly added_to_attachment_menu: {};
347
357
  };
348
358
  };
349
359
  readonly chat_member: {
350
360
  readonly from: {
351
361
  readonly me: {};
352
362
  readonly is_bot: {};
363
+ readonly is_premium: {};
364
+ readonly added_to_attachment_menu: {};
353
365
  };
354
366
  };
355
367
  readonly chat_join_request: {};
package/out/filter.js CHANGED
@@ -212,6 +212,8 @@ const ENTITY_KEYS = {
212
212
  const USER_KEYS = {
213
213
  me: {},
214
214
  is_bot: {},
215
+ is_premium: {},
216
+ added_to_attachment_menu: {},
215
217
  };
216
218
  // L2
217
219
  const EDITABLE_MESSAGE_KEYS = {
package/out/mod.d.ts CHANGED
@@ -4,7 +4,7 @@ export { Context } from "./context.js";
4
4
  export * from "./convenience/keyboard.js";
5
5
  export * from "./convenience/session.js";
6
6
  export * from "./convenience/webhook.js";
7
- export { Composer, type Middleware, type MiddlewareFn, type MiddlewareObj, type NextFunction, } from "./composer.js";
7
+ export { type CallbackQueryContext, type CallbackQueryMiddleware, type ChatTypeContext, type ChatTypeMiddleware, type CommandContext, type CommandMiddleware, Composer, type GameQueryContext, type GameQueryMiddleware, type HearsContext, type HearsMiddleware, type InlineQueryContext, type InlineQueryMiddleware, type Middleware, type MiddlewareFn, type MiddlewareObj, type NextFunction, } from "./composer.js";
8
8
  export { type Filter, type FilterQuery, matchFilter } from "./filter.js";
9
9
  export { Api } from "./core/api.js";
10
10
  export { type ApiCallFn, type ApiClientOptions, type RawApi, type TransformableApi, type Transformer, type WebhookReplyEnvelope, } from "./core/client.js";
package/out/types.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from "./types.node.js";
package/out/types.js ADDED
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./types.node.js"), exports);
@@ -0,0 +1,64 @@
1
+ /// <reference types="node" />
2
+ import { type InputFileProxy } from "@grammyjs/types";
3
+ import { toRaw } from "./platform.node";
4
+ import { URL } from "url";
5
+ import { type ReadStream } from "fs";
6
+ export * from "@grammyjs/types";
7
+ /** Something that looks like a URL. */
8
+ interface URLLike {
9
+ /**
10
+ * Identifier of the resouce. Must be in a format that can be parsed by the
11
+ * URL constructor.
12
+ */
13
+ url: string;
14
+ }
15
+ /**
16
+ * An `InputFile` wraps a number of different sources for [sending
17
+ * files](https://grammy.dev/guide/files.html#uploading-your-own-file).
18
+ *
19
+ * It corresponds to the `InputFile` type in the [Telegram Bot API
20
+ * Reference](https://core.telegram.org/bots/api#inputfile).
21
+ */
22
+ export declare class InputFile {
23
+ private consumed;
24
+ private readonly fileData;
25
+ /**
26
+ * Optional name of the constructed `InputFile` instance.
27
+ *
28
+ * Check out the
29
+ * [documenation](https://grammy.dev/guide/files.html#uploading-your-own-file)
30
+ * on sending files with `InputFile`.
31
+ */
32
+ readonly filename?: string;
33
+ /**
34
+ * Constructs an `InputFile` that can be used in the API to send files.
35
+ *
36
+ * @param file A path to a local file or a `Buffer` or a `fs.ReadStream` that specifies the file data
37
+ * @param filename Optional name of the file
38
+ */
39
+ constructor(file: string | URL | URLLike | Uint8Array | ReadStream | Iterable<Uint8Array> | AsyncIterable<Uint8Array>, filename?: string);
40
+ private guessFilename;
41
+ [toRaw](): Uint8Array | Iterable<Uint8Array> | AsyncIterable<Uint8Array>;
42
+ }
43
+ declare type GrammyTypes = InputFileProxy<InputFile>;
44
+ /** Wrapper type to bundle all methods of the Telegram API */
45
+ export declare type ApiMethods = GrammyTypes["Telegram"];
46
+ /** Utility type providing the argument type for the given method name or `{}` if the method does not take any parameters */
47
+ export declare type Opts<M extends keyof GrammyTypes["Telegram"]> = GrammyTypes["Opts"][M];
48
+ /** This object represents the content of a media message to be sent. It should be one of
49
+ - InputMediaAnimation
50
+ - InputMediaDocument
51
+ - InputMediaAudio
52
+ - InputMediaPhoto
53
+ - InputMediaVideo */
54
+ export declare type InputMedia = GrammyTypes["InputMedia"];
55
+ /** Represents a photo to be sent. */
56
+ export declare type InputMediaPhoto = GrammyTypes["InputMediaPhoto"];
57
+ /** Represents a video to be sent. */
58
+ export declare type InputMediaVideo = GrammyTypes["InputMediaVideo"];
59
+ /** Represents an animation file (GIF or H.264/MPEG-4 AVC video without sound) to be sent. */
60
+ export declare type InputMediaAnimation = GrammyTypes["InputMediaAnimation"];
61
+ /** Represents an audio file to be treated as music to be sent. */
62
+ export declare type InputMediaAudio = GrammyTypes["InputMediaAudio"];
63
+ /** Represents a general file to be sent. */
64
+ export declare type InputMediaDocument = GrammyTypes["InputMediaDocument"];
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.InputFile = void 0;
18
+ const platform_node_1 = require("./platform.node");
19
+ const path_1 = require("path");
20
+ const node_fetch_1 = require("node-fetch");
21
+ const url_1 = require("url");
22
+ const fs_1 = require("fs");
23
+ const debug = (0, platform_node_1.debug)("grammy:warn");
24
+ __exportStar(require("@grammyjs/types"), exports);
25
+ // === InputFile handling and File augmenting
26
+ /**
27
+ * An `InputFile` wraps a number of different sources for [sending
28
+ * files](https://grammy.dev/guide/files.html#uploading-your-own-file).
29
+ *
30
+ * It corresponds to the `InputFile` type in the [Telegram Bot API
31
+ * Reference](https://core.telegram.org/bots/api#inputfile).
32
+ */
33
+ class InputFile {
34
+ /**
35
+ * Constructs an `InputFile` that can be used in the API to send files.
36
+ *
37
+ * @param file A path to a local file or a `Buffer` or a `fs.ReadStream` that specifies the file data
38
+ * @param filename Optional name of the file
39
+ */
40
+ constructor(file, filename) {
41
+ this.consumed = false;
42
+ this.fileData = file;
43
+ filename !== null && filename !== void 0 ? filename : (filename = this.guessFilename(file));
44
+ this.filename = filename;
45
+ if (typeof file === "string" &&
46
+ (file.startsWith("http:") || file.startsWith("https:"))) {
47
+ debug(`InputFile received the local file path '${file}' that looks like a URL. Is this a mistake?`);
48
+ }
49
+ }
50
+ guessFilename(file) {
51
+ if (typeof file === "string")
52
+ return (0, path_1.basename)(file);
53
+ if (typeof file !== "object")
54
+ return undefined;
55
+ if ("url" in file)
56
+ return (0, path_1.basename)(file.url);
57
+ if (!(file instanceof url_1.URL))
58
+ return undefined;
59
+ return (0, path_1.basename)(file.pathname) || (0, path_1.basename)(file.hostname);
60
+ }
61
+ [platform_node_1.toRaw]() {
62
+ if (this.consumed) {
63
+ throw new Error("Cannot reuse InputFile data source!");
64
+ }
65
+ const data = this.fileData;
66
+ // Handle local files
67
+ if (typeof data === "string")
68
+ return (0, fs_1.createReadStream)(data);
69
+ // Handle URLs and URLLike objects
70
+ if (data instanceof url_1.URL) {
71
+ return data.protocol === "file" // node-fetch does not support file URLs
72
+ ? (0, fs_1.createReadStream)(data.pathname)
73
+ : fetchFile(data);
74
+ }
75
+ if ("url" in data)
76
+ return fetchFile(data.url);
77
+ // Mark streams and iterators as consumed
78
+ if (!(data instanceof Uint8Array))
79
+ this.consumed = true;
80
+ // Return buffers and byte streams as-is
81
+ return data;
82
+ }
83
+ }
84
+ exports.InputFile = InputFile;
85
+ async function* fetchFile(url) {
86
+ const { body } = await (0, node_fetch_1.default)(url);
87
+ for await (const chunk of body) {
88
+ if (typeof chunk === "string") {
89
+ throw new Error(`Could not transfer file, received string data instead of bytes from '${url}'`);
90
+ }
91
+ yield chunk;
92
+ }
93
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "grammy",
3
3
  "description": "The Telegram Bot Framework.",
4
- "version": "1.8.3",
4
+ "version": "1.9.0",
5
5
  "author": "KnorpelSenf",
6
6
  "license": "MIT",
7
7
  "engines": {
@@ -14,16 +14,11 @@
14
14
  },
15
15
  "scripts": {
16
16
  "prepare": "npm run backport",
17
- "cache": "deno cache src/mod.ts",
18
- "lint": "deno lint --config deno.json",
19
- "fmt": "deno fmt --config deno.json",
20
- "test": "deno test ./test/",
21
- "bundle": "cd bundling && ./bundle-all.sh",
22
17
  "backport": "deno2node tsconfig.json",
23
18
  "contribs": "all-contributors"
24
19
  },
25
20
  "dependencies": {
26
- "@grammyjs/types": "^2.7.0",
21
+ "@grammyjs/types": "^2.8.0",
27
22
  "abort-controller": "^3.0.0",
28
23
  "debug": "^4.3.4",
29
24
  "node-fetch": "^2.6.7"
@@ -31,7 +26,7 @@
31
26
  "devDependencies": {
32
27
  "@types/debug": "^4.1.7",
33
28
  "@types/node": "^12.20.50",
34
- "@types/node-fetch": "^2.6.1",
29
+ "@types/node-fetch": "^2.6.2",
35
30
  "all-contributors-cli": "^6.20.0",
36
31
  "deno2node": "^1.3.0"
37
32
  },