gramio 0.0.31 → 0.0.35

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
@@ -1,7 +1,46 @@
1
1
  # GramIO
2
2
 
3
- Work in progress.
3
+ <div align="center">
4
4
 
5
- Currently support Bot API 7.3
5
+ [![Bot API](https://img.shields.io/badge/Bot%20API-7.3-blue?logo=telegram&style=flat&labelColor=000&color=3b82f6)](https://core.telegram.org/bots/api)
6
+ [![npm](https://img.shields.io/npm/v/gramio?logo=npm&style=flat&labelColor=000&color=3b82f6)](https://www.npmjs.org/package/@gramio/core)
7
+ [![JSR](https://jsr.io/badges/@gramio/core)](https://jsr.io/@gramio/core)
8
+ [![JSR Score](https://jsr.io/badges/@gramio/core/score)](https://jsr.io/@gramio/core)
6
9
 
7
- See [Documentation](https://gramio.netlify.app/)
10
+ </div>
11
+
12
+ TypeScript/JavaScript Telegram Bot API Framework for create your bots with convenience!
13
+
14
+ ✨ **Extensible** - Our plugin and hook system is awesome
15
+
16
+ 🛡️ **Type-safe** - Written in TypeScript with love ❤️
17
+
18
+ 🌐 **Multi-runtime** - Works on [Node.js](https://nodejs.org/), [Bun](https://bun.sh/) and [Deno](https://deno.com/)\*
19
+
20
+ ⚙️ **Code-generated** - Many parts are code-generated (for example, [code-generated and auto-published Telegram Bot API types](https://github.com/gramiojs/types))
21
+
22
+ **Deno\*** [windows-specific issue with undici](https://github.com/denoland/deno/issues/19532)
23
+
24
+ ## [Get started](https://gramio.dev/get-started)
25
+
26
+ To create your new bot, you just need to write it to the console:
27
+
28
+ ```bash [npm]
29
+ npm create gramio ./bot
30
+ ```
31
+
32
+ and GramIO customize your project the way you want it!
33
+
34
+ ### Example
35
+
36
+ ```typescript
37
+ import { Bot } from "gramio";
38
+
39
+ const bot = new Bot()
40
+ .command("start", (context) => context.send("Hello!"))
41
+ .onStart(({ info }) => console.log(`✨ Bot ${info.username} was started!`));
42
+
43
+ bot.start();
44
+ ```
45
+
46
+ For more, please see [documentation](https://gramio.dev).
package/dist/bot.d.ts CHANGED
@@ -1,25 +1,71 @@
1
1
  import { CallbackData } from "@gramio/callback-data";
2
2
  import { type Attachment, type Context, type ContextType, type MaybeArray, type UpdateName } from "@gramio/contexts";
3
3
  import type { APIMethodParams, APIMethods, SetMyCommandsParams, TelegramBotCommand, TelegramReactionTypeEmojiEmoji, TelegramUser } from "@gramio/types";
4
- import { Plugin } from "./plugin";
5
- import type { BotOptions, DeriveDefinitions, ErrorDefinitions, Handler, Hooks, MaybePromise, SuppressedAPIMethods } from "./types";
4
+ import type { AnyBot, AnyPlugin, BotOptions, DeriveDefinitions, ErrorDefinitions, Handler, Hooks, MaybePromise, SuppressedAPIMethods } from "./types";
6
5
  import { Updates } from "./updates";
6
+ /** Bot instance
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * import { Bot } from "gramio";
11
+ *
12
+ * const bot = new Bot("") // put you token here
13
+ * .command("start", (context) => context.send("Hi!"))
14
+ * .onStart(console.log);
15
+ *
16
+ * bot.start();
17
+ * ```
18
+ */
7
19
  export declare class Bot<Errors extends ErrorDefinitions = {}, Derives extends DeriveDefinitions = DeriveDefinitions> {
8
- /** @internal */
20
+ /** @internal. Remap generic */
9
21
  __Derives: Derives;
22
+ /** Options provided to instance */
10
23
  readonly options: BotOptions;
24
+ /** Bot data (filled in when calling bot.init/bot.start) */
11
25
  info: TelegramUser | undefined;
26
+ /**
27
+ * Send API Request to Telegram Bot API
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * const response = await bot.api.sendMessage({
32
+ * chat_id: "@gramio_forum",
33
+ * text: "some text",
34
+ * });
35
+ * ```
36
+ *
37
+ * [Documentation](https://gramio.dev/bot-api.html)
38
+ */
12
39
  readonly api: SuppressedAPIMethods;
13
40
  private lazyloadPlugins;
14
41
  private dependencies;
15
42
  private errorsDefinitions;
16
43
  private errorHandler;
44
+ /** This instance handle updates */
17
45
  updates: Updates;
18
46
  private hooks;
47
+ /** Create new Bot instance */
19
48
  constructor(token: string, options?: Omit<BotOptions, "token">);
20
49
  private runHooks;
21
50
  private runImmutableHooks;
22
51
  private _callApi;
52
+ /**
53
+ * Download file
54
+ *
55
+ * @example
56
+ * ```ts
57
+ * bot.on("message", async (context) => {
58
+ * if (!context.document) return;
59
+ * // download to ./file-name
60
+ * await context.download(context.document.fileName || "file-name");
61
+ * // get ArrayBuffer
62
+ * const buffer = await context.download();
63
+ *
64
+ * return context.send("Thank you!");
65
+ * });
66
+ * ```
67
+ * [Documentation](https://gramio.dev/files/download.html)
68
+ */
23
69
  downloadFile(attachment: Attachment | {
24
70
  file_id: string;
25
71
  } | string): Promise<ArrayBuffer>;
@@ -71,30 +117,214 @@ export declare class Bot<Errors extends ErrorDefinitions = {}, Derives extends D
71
117
  */
72
118
  onError<T extends UpdateName>(updateName: MaybeArray<T>, handler: Hooks.OnError<Errors, ContextType<typeof this, T> & Derives["global"] & Derives[T]>): this;
73
119
  onError(handler: Hooks.OnError<Errors, Context<typeof this> & Derives["global"]>): this;
120
+ /**
121
+ * Derive some data to handlers
122
+ *
123
+ * @example
124
+ * ```ts
125
+ * new Bot("token").derive((context) => {
126
+ * return {
127
+ * superSend: () => context.send("Derived method")
128
+ * }
129
+ * })
130
+ * ```
131
+ */
74
132
  derive<Handler extends Hooks.Derive<Context<typeof this>>>(handler: Handler): Bot<Errors, Derives & {
75
133
  global: Awaited<ReturnType<Handler>>;
76
134
  }>;
77
135
  derive<Update extends UpdateName, Handler extends Hooks.Derive<ContextType<typeof this, Update>>>(updateName: MaybeArray<Update>, handler: Handler): Bot<Errors, Derives & {
78
136
  [K in Update]: Awaited<ReturnType<Handler>>;
79
137
  }>;
138
+ /**
139
+ * This hook called when the bot is `started`.
140
+ *
141
+ * @example
142
+ * ```typescript
143
+ * import { Bot } from "gramio";
144
+ *
145
+ * const bot = new Bot(process.env.TOKEN!).onStart(
146
+ * ({ plugins, info, updatesFrom }) => {
147
+ * console.log(`plugin list - ${plugins.join(", ")}`);
148
+ * console.log(`bot username is @${info.username}`);
149
+ * console.log(`updates from ${updatesFrom}`);
150
+ * }
151
+ * );
152
+ *
153
+ * bot.start();
154
+ * ```
155
+ *
156
+ * [Documentation](https://gramio.dev/hooks/on-start.html)
157
+ * */
80
158
  onStart(handler: Hooks.OnStart): this;
159
+ /**
160
+ * This hook called when the bot stops.
161
+ *
162
+ * @example
163
+ * ```typescript
164
+ * import { Bot } from "gramio";
165
+ *
166
+ * const bot = new Bot(process.env.TOKEN!).onStop(
167
+ * ({ plugins, info, updatesFrom }) => {
168
+ * console.log(`plugin list - ${plugins.join(", ")}`);
169
+ * console.log(`bot username is @${info.username}`);
170
+ * }
171
+ * );
172
+ *
173
+ * bot.start();
174
+ * bot.stop();
175
+ * ```
176
+ *
177
+ * [Documentation](https://gramio.dev/hooks/on-stop.html)
178
+ * */
81
179
  onStop(handler: Hooks.OnStop): this;
180
+ /**
181
+ * This hook called before sending a request to Telegram Bot API (allows us to impact the sent parameters).
182
+ *
183
+ * @example
184
+ * ```typescript
185
+ * import { Bot } from "gramio";
186
+ *
187
+ * const bot = new Bot(process.env.TOKEN!).preRequest((context) => {
188
+ * if (context.method === "sendMessage") {
189
+ * context.params.text = "mutate params";
190
+ * }
191
+ *
192
+ * return context;
193
+ * });
194
+ *
195
+ * bot.start();
196
+ * ```
197
+ *
198
+ * [Documentation](https://gramio.dev/hooks/pre-request.html)
199
+ * */
82
200
  preRequest<Methods extends keyof APIMethods, Handler extends Hooks.PreRequest<Methods>>(methods: MaybeArray<Methods>, handler: Handler): this;
83
201
  preRequest(handler: Hooks.PreRequest): this;
202
+ /**
203
+ * This hook called when API return successful response
204
+ *
205
+ * [Documentation](https://gramio.dev/hooks/on-response.html)
206
+ * */
84
207
  onResponse<Methods extends keyof APIMethods, Handler extends Hooks.OnResponse<Methods>>(methods: MaybeArray<Methods>, handler: Handler): this;
85
208
  onResponse(handler: Hooks.OnResponse): this;
209
+ /**
210
+ * This hook called when API return an error
211
+ *
212
+ * [Documentation](https://gramio.dev/hooks/on-response-error.html)
213
+ * */
86
214
  onResponseError<Methods extends keyof APIMethods, Handler extends Hooks.OnResponseError<Methods>>(methods: MaybeArray<Methods>, handler: Handler): this;
87
215
  onResponseError(handler: Hooks.OnResponseError): this;
216
+ /** Register handler to one or many Updates */
88
217
  on<T extends UpdateName>(updateName: MaybeArray<T>, handler: Handler<ContextType<typeof this, T> & Derives["global"] & Derives[T]>): this;
218
+ /** Register handler to any Updates */
89
219
  use(handler: Handler<Context<typeof this> & Derives["global"]>): this;
90
- extend<NewPlugin extends Plugin<any, any>>(plugin: MaybePromise<NewPlugin>): Bot<Errors & NewPlugin["Errors"], Derives & NewPlugin["Derives"]>;
220
+ /**
221
+ * Extend {@link Plugin} logic and types
222
+ *
223
+ * @example
224
+ * ```ts
225
+ * import { Plugin, Bot } from "gramio";
226
+ *
227
+ * export class PluginError extends Error {
228
+ * wow: "type" | "safe" = "type";
229
+ * }
230
+ *
231
+ * const plugin = new Plugin("gramio-example")
232
+ * .error("PLUGIN", PluginError)
233
+ * .derive(() => {
234
+ * return {
235
+ * some: ["derived", "props"] as const,
236
+ * };
237
+ * });
238
+ *
239
+ * const bot = new Bot(process.env.TOKEN!)
240
+ * .extend(plugin)
241
+ * .onError(({ context, kind, error }) => {
242
+ * if (context.is("message") && kind === "PLUGIN") {
243
+ * console.log(error.wow);
244
+ * }
245
+ * })
246
+ * .use((context) => {
247
+ * console.log(context.some);
248
+ * });
249
+ * ```
250
+ */
251
+ extend<NewPlugin extends AnyPlugin>(plugin: MaybePromise<NewPlugin>): Bot<Errors & NewPlugin["_"]["Errors"], Derives & NewPlugin["_"]["Derives"]>;
252
+ /**
253
+ * Register handler to reaction (`message_reaction` update)
254
+ *
255
+ * @example
256
+ * ```ts
257
+ * new Bot().reaction("👍", async (context) => {
258
+ * await context.reply(`Thank you!`);
259
+ * });
260
+ * ```
261
+ * */
91
262
  reaction(trigger: MaybeArray<TelegramReactionTypeEmojiEmoji>, handler: (context: ContextType<typeof this, "message_reaction"> & Derives["global"] & Derives["message_reaction"]) => unknown): this;
263
+ /**
264
+ * Register handler to `callback_query` event
265
+ *
266
+ * @example
267
+ * ```ts
268
+ * const someData = new CallbackData("example").number("id");
269
+ *
270
+ * new Bot()
271
+ * .command("start", (context) =>
272
+ * context.send("some", {
273
+ * reply_markup: new InlineKeyboard().text(
274
+ * "example",
275
+ * someData.pack({
276
+ * id: 1,
277
+ * })
278
+ * ),
279
+ * })
280
+ * )
281
+ * .callbackQuery(someData, (context) => {
282
+ * context.queryData; // is type-safe
283
+ * });
284
+ * ```
285
+ */
92
286
  callbackQuery<Trigger extends CallbackData | string | RegExp>(trigger: Trigger, handler: (context: Omit<ContextType<typeof this, "callback_query">, "data"> & Derives["global"] & Derives["callback_query"] & {
93
287
  queryData: Trigger extends CallbackData ? ReturnType<Trigger["unpack"]> : RegExpMatchArray | null;
94
288
  }) => unknown): this;
289
+ /** Register handler to `chosen_inline_result` update */
95
290
  chosenInlineResult<Ctx = ContextType<typeof this, "chosen_inline_result"> & Derives["global"] & Derives["chosen_inline_result"]>(trigger: RegExp | string | ((context: Ctx) => boolean), handler: (context: Ctx & {
96
291
  args: RegExpMatchArray | null;
97
292
  }) => unknown): this;
293
+ /**
294
+ * Register handler to `inline_query` update
295
+ *
296
+ * @example
297
+ * ```ts
298
+ * new Bot().inlineQuery(
299
+ * /regular expression with (.*)/i,
300
+ * async (context) => {
301
+ * if (context.args) {
302
+ * await context.answer(
303
+ * [
304
+ * InlineQueryResult.article(
305
+ * "id-1",
306
+ * context.args[1],
307
+ * InputMessageContent.text("some"),
308
+ * {
309
+ * reply_markup: new InlineKeyboard().text(
310
+ * "some",
311
+ * "callback-data"
312
+ * ),
313
+ * }
314
+ * ),
315
+ * ],
316
+ * {
317
+ * cache_time: 0,
318
+ * }
319
+ * );
320
+ * }
321
+ * },
322
+ * {
323
+ * onResult: (context) => context.editText("Message edited!"),
324
+ * }
325
+ * );
326
+ * ```
327
+ * */
98
328
  inlineQuery<Ctx = ContextType<typeof this, "inline_query"> & Derives["global"] & Derives["inline_query"]>(trigger: RegExp | string | ((context: Ctx) => boolean), handler: (context: Ctx & {
99
329
  args: RegExpMatchArray | null;
100
330
  }) => unknown, options?: {
@@ -102,20 +332,54 @@ export declare class Bot<Errors extends ErrorDefinitions = {}, Derives extends D
102
332
  args: RegExpMatchArray | null;
103
333
  }) => unknown;
104
334
  }): this;
335
+ /**
336
+ * Register handler to `message` and `business_message` event
337
+ *
338
+ * new Bot().hears(/regular expression with (.*)/i, async (context) => {
339
+ * if (context.args) await context.send(`Params ${context.args[1]}`);
340
+ * });
341
+ */
105
342
  hears<Ctx = ContextType<typeof this, "message"> & Derives["global"] & Derives["message"]>(trigger: RegExp | string | ((context: Ctx) => boolean), handler: (context: Ctx & {
106
343
  args: RegExpMatchArray | null;
107
344
  }) => unknown): this;
345
+ /**
346
+ * Register handler to `message` and `business_message` event when entities contains a command
347
+ *
348
+ * new Bot().command("start", async (context) => {
349
+ * return context.send(`You message is /start ${context.args}`);
350
+ * });
351
+ */
108
352
  command(command: string, handler: (context: ContextType<typeof this, "message"> & Derives["global"] & Derives["message"] & {
109
353
  args: string | null;
110
354
  }) => unknown, options?: Omit<SetMyCommandsParams, "commands"> & Omit<TelegramBotCommand, "command">): this;
111
355
  /** Currently not isolated!!! */
112
- group(grouped: (bot: typeof this) => Bot<any, any>): typeof this;
356
+ group(grouped: (bot: typeof this) => AnyBot): typeof this;
357
+ /**
358
+ * Init bot. Call it manually only if you doesn't use {@link Bot.start}
359
+ */
113
360
  init(): Promise<void>;
361
+ /**
362
+ * Start receive updates via long-polling or webhook
363
+ *
364
+ * @example
365
+ * ```ts
366
+ * import { Bot } from "gramio";
367
+ *
368
+ * const bot = new Bot("") // put you token here
369
+ * .command("start", (context) => context.send("Hi!"))
370
+ * .onStart(console.log);
371
+ *
372
+ * bot.start();
373
+ * ```
374
+ */
114
375
  start({ webhook, dropPendingUpdates, allowedUpdates, }?: {
115
376
  webhook?: Omit<APIMethodParams<"setWebhook">, "drop_pending_updates" | "allowed_updates">;
116
377
  dropPendingUpdates?: boolean;
117
378
  allowedUpdates?: NonNullable<APIMethodParams<"getUpdates">>["allowed_updates"];
118
379
  }): Promise<TelegramUser | undefined>;
119
- /** Currently does not implement graceful shutdown */
380
+ /**
381
+ * Stops receiving events via long-polling or webhook
382
+ * Currently does not implement graceful shutdown
383
+ * */
120
384
  stop(): Promise<void>;
121
385
  }