gramio 0.0.50 → 0.1.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/dist/types.d.ts DELETED
@@ -1,242 +0,0 @@
1
- import type { Context, UpdateName } from "@gramio/contexts";
2
- import type { APIMethodParams, APIMethodReturn, APIMethods, TelegramUser } from "@gramio/types";
3
- import type { NextMiddleware } from "middleware-io";
4
- import type { Bot } from "./bot";
5
- import type { TelegramError } from "./errors";
6
- import type { Plugin } from "./plugin";
7
- /** Bot options that you can provide to {@link Bot} constructor */
8
- export interface BotOptions {
9
- /** Bot token */
10
- token: string;
11
- /** List of plugins enabled by default */
12
- plugins?: {
13
- /** Pass `false` to disable plugin. @default true */
14
- format?: boolean;
15
- };
16
- /** Options to configure how to send requests to the Telegram Bot API */
17
- api: {
18
- /** Configure {@link fetch} parameters */
19
- fetchOptions?: Parameters<typeof fetch>[1];
20
- /** URL which will be used to send requests to. @default "https://api.telegram.org/bot" */
21
- baseURL: string;
22
- /**
23
- * Should we send requests to `test` data center?
24
- * The test environment is completely separate from the main environment, so you will need to create a new user account and a new bot with `@BotFather`.
25
- *
26
- * [Documentation](https://core.telegram.org/bots/webapps#using-bots-in-the-test-environment)
27
- * @default false
28
- * */
29
- useTest?: boolean;
30
- /**
31
- * Time in milliseconds before calling {@link APIMethods.getUpdates | getUpdates} again
32
- * @default 1000
33
- */
34
- retryGetUpdatesWait?: number;
35
- };
36
- }
37
- /**
38
- * Handler is a function with context and next function arguments
39
- *
40
- * @example
41
- * ```ts
42
- * const handler: Handler<ContextType<Bot, "message">> = (context, _next) => context.send("HI!");
43
- *
44
- * bot.on("message", handler)
45
- * ```
46
- */
47
- export type Handler<T> = (context: T, next: NextMiddleware) => unknown;
48
- interface ErrorHandlerParams<Ctx extends Context<AnyBot>, Kind extends string, Err> {
49
- context: Ctx;
50
- kind: Kind;
51
- error: Err;
52
- }
53
- type AnyTelegramError<Methods extends keyof APIMethods = keyof APIMethods> = {
54
- [APIMethod in Methods]: TelegramError<APIMethod>;
55
- }[Methods];
56
- type AnyTelegramMethod<Methods extends keyof APIMethods> = {
57
- [APIMethod in Methods]: {
58
- method: APIMethod;
59
- params: MaybeSuppressedParams<APIMethod>;
60
- };
61
- }[Methods];
62
- /**
63
- * Interface for add `suppress` param to params
64
- */
65
- export interface Suppress<IsSuppressed extends boolean | undefined = undefined> {
66
- /**
67
- * Pass `true` if you want to suppress throwing errors of this method.
68
- *
69
- * **But this does not undo getting into the `onResponseError` hook**.
70
- *
71
- * @example
72
- * ```ts
73
- * const response = await bot.api.sendMessage({
74
- * suppress: true,
75
- * chat_id: "@not_found",
76
- * text: "Suppressed method"
77
- * });
78
- *
79
- * if(response instanceof TelegramError) console.error("sendMessage returns an error...")
80
- * else console.log("Message has been sent successfully");
81
- * ```
82
- *
83
- * */
84
- suppress?: IsSuppressed;
85
- }
86
- /** Type that assign API params with {@link Suppress} */
87
- export type MaybeSuppressedParams<Method extends keyof APIMethods, IsSuppressed extends boolean | undefined = undefined> = APIMethodParams<Method> & Suppress<IsSuppressed>;
88
- /** Return method params but with {@link Suppress} */
89
- export type SuppressedAPIMethodParams<Method extends keyof APIMethods> = undefined extends APIMethodParams<Method> ? Suppress<true> : MaybeSuppressedParams<Method, true>;
90
- /** Type that return MaybeSuppressed API method ReturnType */
91
- type MaybeSuppressedReturn<Method extends keyof APIMethods, IsSuppressed extends boolean | undefined = undefined> = true extends IsSuppressed ? TelegramError<Method> | APIMethodReturn<Method> : APIMethodReturn<Method>;
92
- /** Type that return {@link Suppress | Suppressed} API method ReturnType */
93
- export type SuppressedAPIMethodReturn<Method extends keyof APIMethods> = MaybeSuppressedReturn<Method, true>;
94
- /** Map of APIMethods but with {@link Suppress} */
95
- export type SuppressedAPIMethods<Methods extends keyof APIMethods = keyof APIMethods> = {
96
- [APIMethod in Methods]: APIMethodParams<APIMethod> extends undefined ? <IsSuppressed extends boolean | undefined = undefined>(params?: Suppress<IsSuppressed>) => Promise<MaybeSuppressedReturn<APIMethod, IsSuppressed>> : undefined extends APIMethodParams<APIMethod> ? <IsSuppressed extends boolean | undefined = undefined>(params?: MaybeSuppressedParams<APIMethod, IsSuppressed>) => Promise<MaybeSuppressedReturn<APIMethod, IsSuppressed>> : <IsSuppressed extends boolean | undefined = undefined>(params: MaybeSuppressedParams<APIMethod, IsSuppressed>) => Promise<MaybeSuppressedReturn<APIMethod, IsSuppressed>>;
97
- };
98
- type AnyTelegramMethodWithReturn<Methods extends keyof APIMethods> = {
99
- [APIMethod in Methods]: {
100
- method: APIMethod;
101
- params: APIMethodParams<APIMethod>;
102
- response: APIMethodReturn<APIMethod>;
103
- };
104
- }[Methods];
105
- /** Type for maybe {@link Promise} or may not */
106
- export type MaybePromise<T> = Promise<T> | T;
107
- /**
108
- * Namespace with GramIO hooks types
109
- *
110
- * [Documentation](https://gramio.dev/hooks/overview.html)
111
- * */
112
- export declare namespace Hooks {
113
- /** Derive */
114
- type Derive<Ctx> = (context: Ctx) => MaybePromise<Record<string, unknown>>;
115
- /** Argument type for {@link PreRequest} */
116
- type PreRequestContext<Methods extends keyof APIMethods> = AnyTelegramMethod<Methods>;
117
- /**
118
- * Type for `preRequest` hook
119
- *
120
- * @example
121
- * ```typescript
122
- * import { Bot } from "gramio";
123
- *
124
- * const bot = new Bot(process.env.TOKEN!).preRequest((context) => {
125
- * if (context.method === "sendMessage") {
126
- * context.params.text = "mutate params";
127
- * }
128
- *
129
- * return context;
130
- * });
131
- *
132
- * bot.start();
133
- * ```
134
- *
135
- * [Documentation](https://gramio.dev/hooks/pre-request.html)
136
- * */
137
- type PreRequest<Methods extends keyof APIMethods = keyof APIMethods> = (ctx: PreRequestContext<Methods>) => MaybePromise<PreRequestContext<Methods>>;
138
- /** Argument type for {@link OnError} */
139
- type OnErrorContext<Ctx extends Context<AnyBot>, T extends ErrorDefinitions> = ErrorHandlerParams<Ctx, "TELEGRAM", AnyTelegramError> | ErrorHandlerParams<Ctx, "UNKNOWN", Error> | {
140
- [K in keyof T]: ErrorHandlerParams<Ctx, K & string, T[K & string]>;
141
- }[keyof T];
142
- /**
143
- * Type for `onError` hook
144
- *
145
- * @example
146
- * ```typescript
147
- * bot.on("message", () => {
148
- * bot.api.sendMessage({
149
- * chat_id: "@not_found",
150
- * text: "Chat not exists....",
151
- * });
152
- * });
153
- *
154
- * bot.onError(({ context, kind, error }) => {
155
- * if (context.is("message")) return context.send(`${kind}: ${error.message}`);
156
- * });
157
- * ```
158
- *
159
- * [Documentation](https://gramio.dev/hooks/on-error.html)
160
- * */
161
- type OnError<T extends ErrorDefinitions, Ctx extends Context<any> = Context<AnyBot>> = (options: OnErrorContext<Ctx, T>) => unknown;
162
- /**
163
- * Type for `onStart` hook
164
- *
165
- * @example
166
- * ```typescript
167
- * import { Bot } from "gramio";
168
- *
169
- * const bot = new Bot(process.env.TOKEN!).onStart(
170
- * ({ plugins, info, updatesFrom }) => {
171
- * console.log(`plugin list - ${plugins.join(", ")}`);
172
- * console.log(`bot username is @${info.username}`);
173
- * console.log(`updates from ${updatesFrom}`);
174
- * }
175
- * );
176
- *
177
- * bot.start();
178
- * ```
179
- *
180
- * [Documentation](https://gramio.dev/hooks/on-start.html)
181
- * */
182
- type OnStart = (context: {
183
- plugins: string[];
184
- info: TelegramUser;
185
- updatesFrom: "webhook" | "long-polling";
186
- }) => unknown;
187
- /**
188
- * Type for `onStop` hook
189
- *
190
- * @example
191
- * ```typescript
192
- * import { Bot } from "gramio";
193
- *
194
- * const bot = new Bot(process.env.TOKEN!).onStop(
195
- * ({ plugins, info, updatesFrom }) => {
196
- * console.log(`plugin list - ${plugins.join(", ")}`);
197
- * console.log(`bot username is @${info.username}`);
198
- * }
199
- * );
200
- *
201
- * bot.start();
202
- * bot.stop();
203
- * ```
204
- *
205
- * [Documentation](https://gramio.dev/hooks/on-stop.html)
206
- * */
207
- type OnStop = (context: {
208
- plugins: string[];
209
- info: TelegramUser;
210
- }) => unknown;
211
- /**
212
- * Type for `onResponseError` hook
213
- *
214
- * [Documentation](https://gramio.dev/hooks/on-response-error.html)
215
- * */
216
- type OnResponseError<Methods extends keyof APIMethods = keyof APIMethods> = (context: AnyTelegramError<Methods>, api: Bot["api"]) => unknown;
217
- /**
218
- * Type for `onResponse` hook
219
- *
220
- * [Documentation](https://gramio.dev/hooks/on-response.html)
221
- * */
222
- type OnResponse<Methods extends keyof APIMethods = keyof APIMethods> = (context: AnyTelegramMethodWithReturn<Methods>) => unknown;
223
- /** Store hooks */
224
- interface Store<T extends ErrorDefinitions> {
225
- preRequest: PreRequest[];
226
- onResponse: OnResponse[];
227
- onResponseError: OnResponseError[];
228
- onError: OnError<T>[];
229
- onStart: OnStart[];
230
- onStop: OnStop[];
231
- }
232
- }
233
- /** Error map should be map of string: error */
234
- export type ErrorDefinitions = Record<string, Error>;
235
- /** Map of derives */
236
- export type DeriveDefinitions = Record<UpdateName | "global", {}>;
237
- export type FilterDefinitions = Record<string, (...args: any[]) => (context: Context<Bot>) => boolean>;
238
- /** Type of Bot that accepts any generics */
239
- export type AnyBot = Bot<any, any>;
240
- /** Type of Bot that accepts any generics */
241
- export type AnyPlugin = Plugin<any, any>;
242
- export {};
package/dist/types.js DELETED
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
package/dist/updates.d.ts DELETED
@@ -1,17 +0,0 @@
1
- import { type Context } from "@gramio/contexts";
2
- import type { APIMethodParams, TelegramUpdate } from "@gramio/types";
3
- import type { CaughtMiddlewareHandler } from "middleware-io";
4
- import { Composer } from "./composer";
5
- import type { AnyBot } from "./types";
6
- export declare class Updates {
7
- private readonly bot;
8
- isStarted: boolean;
9
- private offset;
10
- composer: Composer;
11
- constructor(bot: AnyBot, onError: CaughtMiddlewareHandler<Context<any>>);
12
- handleUpdate(data: TelegramUpdate): Promise<void>;
13
- /** @deprecated use bot.start instead @internal */
14
- startPolling(params?: APIMethodParams<"getUpdates">): Promise<void>;
15
- startFetchLoop(params?: APIMethodParams<"getUpdates">): Promise<void>;
16
- stopPolling(): void;
17
- }
package/dist/updates.js DELETED
@@ -1,87 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Updates = void 0;
4
- const promises_1 = require("node:timers/promises");
5
- const contexts_1 = require("@gramio/contexts");
6
- const composer_1 = require("./composer");
7
- class Updates {
8
- bot;
9
- isStarted = false;
10
- offset = 0;
11
- composer;
12
- constructor(bot, onError) {
13
- this.bot = bot;
14
- this.composer = new composer_1.Composer(onError);
15
- }
16
- async handleUpdate(data) {
17
- const updateType = Object.keys(data).at(1);
18
- this.offset = data.update_id + 1;
19
- const UpdateContext = contexts_1.contextsMappings[updateType];
20
- if (!UpdateContext)
21
- throw new Error(updateType);
22
- const updatePayload = data[updateType];
23
- if (!updatePayload)
24
- throw new Error("");
25
- try {
26
- let context = new UpdateContext({
27
- bot: this.bot,
28
- update: data,
29
- // @ts-expect-error
30
- payload: updatePayload,
31
- type: updateType,
32
- updateId: data.update_id,
33
- });
34
- if ("isEvent" in context && context.isEvent() && context.eventType) {
35
- const payload = data.message ??
36
- data.edited_message ??
37
- data.channel_post ??
38
- data.edited_channel_post ??
39
- data.business_message;
40
- if (!payload)
41
- throw new Error("Unsupported event??");
42
- context = new contexts_1.contextsMappings[context.eventType]({
43
- bot: this.bot,
44
- update: data,
45
- payload,
46
- // @ts-expect-error
47
- type: context.eventType,
48
- updateId: data.update_id,
49
- });
50
- }
51
- this.composer.compose(context);
52
- }
53
- catch (error) {
54
- throw new Error(`[UPDATES] Update type ${updateType} not supported.`);
55
- }
56
- }
57
- /** @deprecated use bot.start instead @internal */
58
- async startPolling(params = {}) {
59
- if (this.isStarted)
60
- throw new Error("[UPDATES] Polling already started!");
61
- this.isStarted = true;
62
- this.startFetchLoop(params);
63
- return;
64
- }
65
- async startFetchLoop(params = {}) {
66
- while (this.isStarted) {
67
- try {
68
- const updates = await this.bot.api.getUpdates({
69
- ...params,
70
- offset: this.offset,
71
- });
72
- for await (const update of updates) {
73
- //TODO: update errors
74
- await this.handleUpdate(update).catch(console.error);
75
- }
76
- }
77
- catch (error) {
78
- console.error("Error received when fetching updates", error);
79
- await promises_1.scheduler.wait(this.bot.options.api.retryGetUpdatesWait);
80
- }
81
- }
82
- }
83
- stopPolling() {
84
- this.isStarted = false;
85
- }
86
- }
87
- exports.Updates = Updates;
@@ -1,53 +0,0 @@
1
- import type { TelegramUpdate } from "@gramio/types";
2
- import type { MaybePromise } from "../types";
3
- export interface FrameworkHandler {
4
- update: MaybePromise<TelegramUpdate>;
5
- header: string;
6
- unauthorized: () => unknown;
7
- response?: () => unknown;
8
- }
9
- export type FrameworkAdapter = (...args: any[]) => FrameworkHandler;
10
- export declare const frameworks: {
11
- elysia: ({ body, headers }: any) => {
12
- update: any;
13
- header: any;
14
- unauthorized: () => import("bun-types/fetch").Response;
15
- };
16
- fastify: (request: any, reply: any) => {
17
- update: any;
18
- header: any;
19
- unauthorized: () => any;
20
- };
21
- hono: (c: any) => {
22
- update: any;
23
- header: any;
24
- unauthorized: () => any;
25
- };
26
- express: (req: any, res: any) => {
27
- update: any;
28
- header: any;
29
- unauthorized: () => any;
30
- };
31
- koa: (ctx: any) => {
32
- update: any;
33
- header: any;
34
- unauthorized: () => void;
35
- };
36
- http: (req: any, res: any) => {
37
- update: Promise<TelegramUpdate>;
38
- header: any;
39
- unauthorized: () => any;
40
- };
41
- "std/http": (req: any) => {
42
- update: any;
43
- header: any;
44
- response: () => import("bun-types/fetch").Response;
45
- unauthorized: () => import("bun-types/fetch").Response;
46
- };
47
- "Bun.serve": (req: any) => {
48
- update: any;
49
- header: any;
50
- response: () => import("bun-types/fetch").Response;
51
- unauthorized: () => import("bun-types/fetch").Response;
52
- };
53
- };
@@ -1,58 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.frameworks = void 0;
4
- const SECRET_TOKEN_HEADER = "X-Telegram-Bot-Api-Secret-Token";
5
- const WRONG_TOKEN_ERROR = "secret token is invalid";
6
- exports.frameworks = {
7
- elysia: ({ body, headers }) => ({
8
- update: body,
9
- header: headers[SECRET_TOKEN_HEADER],
10
- unauthorized: () => new Response(WRONG_TOKEN_ERROR, { status: 401 }),
11
- }),
12
- fastify: (request, reply) => ({
13
- update: request.body,
14
- header: request.headers[SECRET_TOKEN_HEADER],
15
- unauthorized: () => reply.code(401).send(WRONG_TOKEN_ERROR),
16
- }),
17
- hono: (c) => ({
18
- update: c.req.json(),
19
- header: c.req.header(SECRET_TOKEN_HEADER),
20
- unauthorized: () => c.text(WRONG_TOKEN_ERROR, 401),
21
- }),
22
- express: (req, res) => ({
23
- update: req.body,
24
- header: req.header(SECRET_TOKEN_HEADER),
25
- unauthorized: () => res.status(401).send(WRONG_TOKEN_ERROR),
26
- }),
27
- koa: (ctx) => ({
28
- update: ctx.request.body,
29
- header: ctx.get(SECRET_TOKEN_HEADER),
30
- unauthorized: () => {
31
- ctx.status === 401;
32
- ctx.body = WRONG_TOKEN_ERROR;
33
- },
34
- }),
35
- http: (req, res) => ({
36
- update: new Promise((resolve) => {
37
- let body = "";
38
- req.on("data", (chunk) => {
39
- body += chunk.toString();
40
- });
41
- req.on("end", () => resolve(JSON.parse(body)));
42
- }),
43
- header: req.headers[SECRET_TOKEN_HEADER.toLowerCase()],
44
- unauthorized: () => res.writeHead(401).end(WRONG_TOKEN_ERROR),
45
- }),
46
- "std/http": (req) => ({
47
- update: req.json(),
48
- header: req.headers.get(SECRET_TOKEN_HEADER),
49
- response: () => new Response("ok!"),
50
- unauthorized: () => new Response(WRONG_TOKEN_ERROR, { status: 401 }),
51
- }),
52
- "Bun.serve": (req) => ({
53
- update: req.json(),
54
- header: req.headers.get(SECRET_TOKEN_HEADER),
55
- response: () => new Response("ok!"),
56
- unauthorized: () => new Response(WRONG_TOKEN_ERROR, { status: 401 }),
57
- }),
58
- };
@@ -1,35 +0,0 @@
1
- import type { Bot } from "../bot";
2
- import { frameworks } from "./adapters";
3
- /** Union type of webhook handlers name */
4
- export type WebhookHandlers = keyof typeof frameworks;
5
- /**
6
- * Setup handler with yours web-framework to receive updates via webhook
7
- *
8
- * @example
9
- * ```ts
10
- * import { Bot } from "gramio";
11
- * import Fastify from "fastify";
12
- *
13
- * const bot = new Bot(process.env.TOKEN as string).on(
14
- * "message",
15
- * (context) => {
16
- * return context.send("Fastify!");
17
- * },
18
- * );
19
- *
20
- * const fastify = Fastify();
21
- *
22
- * fastify.post("/telegram-webhook", webhookHandler(bot, "fastify"));
23
- *
24
- * fastify.listen({ port: 3445, host: "::" });
25
- *
26
- * bot.start({
27
- * webhook: {
28
- * url: "https://example.com:3445/telegram-webhook",
29
- * },
30
- * });
31
- * ```
32
- */
33
- export declare function webhookHandler<Framework extends keyof typeof frameworks>(bot: Bot, framework: Framework, secretToken?: string): ReturnType<(typeof frameworks)[Framework]> extends {
34
- response: () => any;
35
- } ? (...args: Parameters<(typeof frameworks)[Framework]>) => ReturnType<ReturnType<(typeof frameworks)[Framework]>["response"]> : (...args: Parameters<(typeof frameworks)[Framework]>) => void;
@@ -1,46 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.webhookHandler = webhookHandler;
4
- const adapters_1 = require("./adapters");
5
- /**
6
- * Setup handler with yours web-framework to receive updates via webhook
7
- *
8
- * @example
9
- * ```ts
10
- * import { Bot } from "gramio";
11
- * import Fastify from "fastify";
12
- *
13
- * const bot = new Bot(process.env.TOKEN as string).on(
14
- * "message",
15
- * (context) => {
16
- * return context.send("Fastify!");
17
- * },
18
- * );
19
- *
20
- * const fastify = Fastify();
21
- *
22
- * fastify.post("/telegram-webhook", webhookHandler(bot, "fastify"));
23
- *
24
- * fastify.listen({ port: 3445, host: "::" });
25
- *
26
- * bot.start({
27
- * webhook: {
28
- * url: "https://example.com:3445/telegram-webhook",
29
- * },
30
- * });
31
- * ```
32
- */
33
- function webhookHandler(bot, framework, secretToken) {
34
- const frameworkAdapter = adapters_1.frameworks[framework];
35
- return (async (...args) => {
36
- // @ts-expect-error
37
- const { update, response, header, unauthorized } = frameworkAdapter(
38
- // @ts-expect-error
39
- ...args);
40
- if (secretToken && header !== secretToken)
41
- return unauthorized();
42
- await bot.updates.handleUpdate(await update);
43
- if (response)
44
- return response();
45
- });
46
- }