@effect-ak/tg-bot-client 1.0.0 → 1.2.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 +294 -0
- package/dist/index.cjs +95 -116
- package/dist/index.d.cts +53 -50
- package/dist/index.d.ts +53 -50
- package/dist/index.js +90 -101
- package/package.json +1 -4
- package/src/client-file.ts +58 -55
- package/src/client.ts +17 -29
- package/src/config.ts +7 -10
- package/src/errors.ts +16 -12
- package/src/execute.ts +46 -49
- package/src/index.ts +1 -0
- package/src/utils.ts +3 -0
package/README.md
ADDED
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
# @effect-ak/tg-bot-client
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@effect-ak/tg-bot-client)
|
|
4
|
+

|
|
5
|
+

|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
Type-safe HTTP client for Telegram Bot API with complete TypeScript support.
|
|
9
|
+
|
|
10
|
+
## Table of Contents
|
|
11
|
+
|
|
12
|
+
- [Motivation](#motivation)
|
|
13
|
+
- [Features](#features)
|
|
14
|
+
- [Installation](#installation)
|
|
15
|
+
- [Quick Start](#quick-start)
|
|
16
|
+
- [Usage Examples](#usage-examples)
|
|
17
|
+
- [Sending Messages](#sending-messages)
|
|
18
|
+
- [Sending Files](#sending-files)
|
|
19
|
+
- [Downloading Files](#downloading-files)
|
|
20
|
+
- [Using Message Effects](#using-message-effects)
|
|
21
|
+
- [Error Handling](#error-handling)
|
|
22
|
+
- [API Reference](#api-reference)
|
|
23
|
+
- [Configuration](#configuration)
|
|
24
|
+
- [Related Packages](#related-packages)
|
|
25
|
+
- [Contributing](#contributing)
|
|
26
|
+
- [License](#license)
|
|
27
|
+
|
|
28
|
+
## Motivation
|
|
29
|
+
|
|
30
|
+
**Telegram** does not offer an official TypeScript **SDK** for their **API** but they provide documentation in HTML format.
|
|
31
|
+
|
|
32
|
+
This package provides a lightweight, type-safe HTTP client that uses types generated from the [official Telegram Bot API documentation](https://core.telegram.org/bots/api), ensuring it stays in sync with the latest API updates.
|
|
33
|
+
|
|
34
|
+
## Features
|
|
35
|
+
|
|
36
|
+
- **Type-Safe**: Full TypeScript support with types generated from official documentation
|
|
37
|
+
- **Lightweight**: Minimal dependencies
|
|
38
|
+
- **Complete API Coverage**: All Bot API methods are supported
|
|
39
|
+
- **Smart Type Conversion**: Automatic mapping of Telegram types to TypeScript:
|
|
40
|
+
- `Integer` → `number`
|
|
41
|
+
- `True` → `boolean`
|
|
42
|
+
- `String or Number` → `string | number`
|
|
43
|
+
- Enumerated types → Union of literal types (e.g., `"private" | "group" | "supergroup" | "channel"`)
|
|
44
|
+
- **File Handling**: Simplified file upload and download
|
|
45
|
+
- **Message Effects**: Built-in constants for message effects
|
|
46
|
+
- **Custom Base URL**: Support for custom Telegram Bot API servers
|
|
47
|
+
|
|
48
|
+
## Installation
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npm install @effect-ak/tg-bot-client
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
pnpm add @effect-ak/tg-bot-client
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
yarn add @effect-ak/tg-bot-client
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Quick Start
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
import { makeTgBotClient } from "@effect-ak/tg-bot-client"
|
|
66
|
+
|
|
67
|
+
const client = makeTgBotClient({
|
|
68
|
+
bot_token: "YOUR_BOT_TOKEN" // Token from @BotFather
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
// Send a message
|
|
72
|
+
await client.execute("send_message", {
|
|
73
|
+
chat_id: "123456789",
|
|
74
|
+
text: "Hello, World!"
|
|
75
|
+
})
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Usage Examples
|
|
79
|
+
|
|
80
|
+
### Sending Messages
|
|
81
|
+
|
|
82
|
+
#### Basic Text Message
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
await client.execute("send_message", {
|
|
86
|
+
chat_id: "123456789",
|
|
87
|
+
text: "Hello from TypeScript!"
|
|
88
|
+
})
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
#### Message with Formatting
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
await client.execute("send_message", {
|
|
95
|
+
chat_id: "123456789",
|
|
96
|
+
text: "*Bold* _italic_ `code`",
|
|
97
|
+
parse_mode: "Markdown"
|
|
98
|
+
})
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
#### Message with Inline Keyboard
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
await client.execute("send_message", {
|
|
105
|
+
chat_id: "123456789",
|
|
106
|
+
text: "Choose an option:",
|
|
107
|
+
reply_markup: {
|
|
108
|
+
inline_keyboard: [
|
|
109
|
+
[
|
|
110
|
+
{ text: "Option 1", callback_data: "opt_1" },
|
|
111
|
+
{ text: "Option 2", callback_data: "opt_2" }
|
|
112
|
+
]
|
|
113
|
+
]
|
|
114
|
+
}
|
|
115
|
+
})
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Sending Files
|
|
119
|
+
|
|
120
|
+
#### Sending a Dice
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
await client.execute("send_dice", {
|
|
124
|
+
chat_id: "123456789",
|
|
125
|
+
emoji: "🎲"
|
|
126
|
+
})
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
#### Sending a Document
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
await client.execute("send_document", {
|
|
133
|
+
chat_id: "123456789",
|
|
134
|
+
document: {
|
|
135
|
+
file_content: new TextEncoder().encode("Hello from file!"),
|
|
136
|
+
file_name: "hello.txt"
|
|
137
|
+
},
|
|
138
|
+
caption: "Simple text file"
|
|
139
|
+
})
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
#### Sending a Photo
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
await client.execute("send_photo", {
|
|
146
|
+
chat_id: "123456789",
|
|
147
|
+
photo: {
|
|
148
|
+
file_content: photoBuffer,
|
|
149
|
+
file_name: "image.jpg"
|
|
150
|
+
},
|
|
151
|
+
caption: "Check out this photo!"
|
|
152
|
+
})
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Downloading Files
|
|
156
|
+
|
|
157
|
+
To download a file from Telegram servers, use the `getFile` method. It handles both the API call and file download in one step:
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
// Get file by file_id (from a message, for example)
|
|
161
|
+
const file = await client.getFile({
|
|
162
|
+
file_id: "AgACAgIAAxkBAAI..."
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
// file is a standard File object
|
|
166
|
+
console.log(file.name) // filename.jpg
|
|
167
|
+
console.log(file.size) // file size in bytes
|
|
168
|
+
|
|
169
|
+
// Read file contents
|
|
170
|
+
const arrayBuffer = await file.arrayBuffer()
|
|
171
|
+
const text = await file.text()
|
|
172
|
+
const blob = await file.blob()
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Using Message Effects
|
|
176
|
+
|
|
177
|
+
The library includes built-in constants for message effects:
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
import { MESSAGE_EFFECTS } from "@effect-ak/tg-bot-client"
|
|
181
|
+
|
|
182
|
+
await client.execute("send_message", {
|
|
183
|
+
chat_id: "123456789",
|
|
184
|
+
text: "Message with fire effect!",
|
|
185
|
+
message_effect_id: MESSAGE_EFFECTS["🔥"]
|
|
186
|
+
})
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Available effects:
|
|
190
|
+
- `MESSAGE_EFFECTS["🔥"]` - Fire
|
|
191
|
+
- `MESSAGE_EFFECTS["👍"]` - Thumbs up
|
|
192
|
+
- `MESSAGE_EFFECTS["👎"]` - Thumbs down
|
|
193
|
+
- `MESSAGE_EFFECTS["❤️"]` - Heart
|
|
194
|
+
- `MESSAGE_EFFECTS["🎉"]` - Party
|
|
195
|
+
- `MESSAGE_EFFECTS["💩"]` - Poop
|
|
196
|
+
|
|
197
|
+
## Error Handling
|
|
198
|
+
|
|
199
|
+
The client throws `TgBotClientError` for all errors:
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
import { TgBotClientError } from "@effect-ak/tg-bot-client"
|
|
203
|
+
|
|
204
|
+
try {
|
|
205
|
+
await client.execute("send_message", {
|
|
206
|
+
chat_id: "invalid",
|
|
207
|
+
text: "Test"
|
|
208
|
+
})
|
|
209
|
+
} catch (error) {
|
|
210
|
+
if (error instanceof TgBotClientError) {
|
|
211
|
+
console.error("Error type:", error.cause._tag)
|
|
212
|
+
|
|
213
|
+
switch (error.cause._tag) {
|
|
214
|
+
case "NotOkResponse":
|
|
215
|
+
console.error("API error:", error.cause.errorCode, error.cause.details)
|
|
216
|
+
break
|
|
217
|
+
case "UnexpectedResponse":
|
|
218
|
+
console.error("Unexpected response:", error.cause.response)
|
|
219
|
+
break
|
|
220
|
+
case "ClientInternalError":
|
|
221
|
+
console.error("Internal error:", error.cause.cause)
|
|
222
|
+
break
|
|
223
|
+
case "UnableToGetFile":
|
|
224
|
+
console.error("File download error:", error.cause.cause)
|
|
225
|
+
break
|
|
226
|
+
case "NotJsonResponse":
|
|
227
|
+
console.error("Invalid JSON response:", error.cause.response)
|
|
228
|
+
break
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
## API Reference
|
|
235
|
+
|
|
236
|
+
### `makeTgBotClient(config)`
|
|
237
|
+
|
|
238
|
+
Creates a new Telegram Bot API client.
|
|
239
|
+
|
|
240
|
+
**Parameters:**
|
|
241
|
+
- `config.bot_token` (string, required): Your bot token from @BotFather
|
|
242
|
+
- `config.base_url` (string, optional): Custom API base URL (default: `https://api.telegram.org`)
|
|
243
|
+
|
|
244
|
+
**Returns:** `TgBotClient`
|
|
245
|
+
|
|
246
|
+
### `client.execute(method, input)`
|
|
247
|
+
|
|
248
|
+
Executes a Telegram Bot API method.
|
|
249
|
+
|
|
250
|
+
**Parameters:**
|
|
251
|
+
- `method` (string): API method name in snake_case (e.g., `"send_message"`, `"get_updates"`)
|
|
252
|
+
- `input` (object): Method parameters as defined in Telegram Bot API
|
|
253
|
+
|
|
254
|
+
**Returns:** `Promise<ApiResponse>` - Typed response based on the method
|
|
255
|
+
|
|
256
|
+
**Note:** Method names use snake_case (e.g., `send_message`) instead of camelCase for better readability and consistency with the Telegram API documentation.
|
|
257
|
+
|
|
258
|
+
### `client.getFile(input)`
|
|
259
|
+
|
|
260
|
+
Downloads a file from Telegram servers.
|
|
261
|
+
|
|
262
|
+
**Parameters:**
|
|
263
|
+
- `input.file_id` (string): File identifier from a message
|
|
264
|
+
|
|
265
|
+
**Returns:** `Promise<File>` - Standard [File](https://developer.mozilla.org/en-US/docs/Web/API/File) object
|
|
266
|
+
|
|
267
|
+
## Configuration
|
|
268
|
+
|
|
269
|
+
### Custom Base URL
|
|
270
|
+
|
|
271
|
+
If you're running your own Telegram Bot API server:
|
|
272
|
+
|
|
273
|
+
```typescript
|
|
274
|
+
const client = makeTgBotClient({
|
|
275
|
+
bot_token: "YOUR_BOT_TOKEN",
|
|
276
|
+
base_url: "https://your-custom-server.com"
|
|
277
|
+
})
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
## Related Packages
|
|
281
|
+
|
|
282
|
+
This package is part of the `tg-bot-client` monorepo:
|
|
283
|
+
|
|
284
|
+
- **[@effect-ak/tg-bot-api](../api)** - TypeScript types for Telegram Bot API and Mini Apps
|
|
285
|
+
- **[@effect-ak/tg-bot](../bot)** - Effect-based bot runner for building Telegram bots
|
|
286
|
+
- **[@effect-ak/tg-bot-codegen](../codegen)** - Code generator that parses official documentation
|
|
287
|
+
|
|
288
|
+
## Contributing
|
|
289
|
+
|
|
290
|
+
Contributions are welcome! Please check out the [issues](https://github.com/effect-ak/tg-bot-client/issues) or submit a pull request.
|
|
291
|
+
|
|
292
|
+
## License
|
|
293
|
+
|
|
294
|
+
MIT © [Aleksandr Kondaurov](https://github.com/effect-ak)
|
package/dist/index.cjs
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
2
|
var __defProp = Object.defineProperty;
|
|
4
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
6
|
var __export = (target, all) => {
|
|
9
7
|
for (var name in all)
|
|
@@ -17,52 +15,42 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
15
|
}
|
|
18
16
|
return to;
|
|
19
17
|
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
19
|
|
|
30
20
|
// src/index.ts
|
|
31
21
|
var index_exports = {};
|
|
32
22
|
__export(index_exports, {
|
|
33
|
-
ClientFileService: () => ClientFileService,
|
|
34
23
|
MESSAGE_EFFECTS: () => MESSAGE_EFFECTS,
|
|
35
24
|
TG_BOT_API_URL: () => TG_BOT_API_URL,
|
|
36
|
-
TgBotApiBaseUrl: () => TgBotApiBaseUrl,
|
|
37
|
-
TgBotApiToken: () => TgBotApiToken,
|
|
38
25
|
TgBotClientError: () => TgBotClientError,
|
|
39
26
|
executeTgBotMethod: () => executeTgBotMethod,
|
|
27
|
+
getBaseUrl: () => getBaseUrl,
|
|
28
|
+
getFile: () => getFile,
|
|
29
|
+
getFileBytes: () => getFileBytes,
|
|
40
30
|
isFileContent: () => isFileContent,
|
|
41
31
|
isMessageEffect: () => isMessageEffect,
|
|
42
32
|
isTgBotApiResponse: () => isTgBotApiResponse,
|
|
43
|
-
isTgBotApiUpdate: () => isTgBotApiUpdate,
|
|
44
33
|
makePayload: () => makePayload,
|
|
45
34
|
makeTgBotClient: () => makeTgBotClient,
|
|
46
|
-
messageEffectIdCodes: () => messageEffectIdCodes
|
|
35
|
+
messageEffectIdCodes: () => messageEffectIdCodes,
|
|
36
|
+
snakeToCamel: () => snakeToCamel
|
|
47
37
|
});
|
|
48
38
|
module.exports = __toCommonJS(index_exports);
|
|
49
39
|
|
|
50
|
-
// src/execute.ts
|
|
51
|
-
var String = __toESM(require("effect/String"), 1);
|
|
52
|
-
var Micro = __toESM(require("effect/Micro"), 1);
|
|
53
|
-
|
|
54
40
|
// src/errors.ts
|
|
55
|
-
var
|
|
56
|
-
|
|
41
|
+
var TgBotClientError = class extends Error {
|
|
42
|
+
_tag = "TgBotClientError";
|
|
43
|
+
cause;
|
|
44
|
+
constructor(options) {
|
|
45
|
+
super(`TgBotClientError: ${options.cause._tag}`);
|
|
46
|
+
this.cause = options.cause;
|
|
47
|
+
this.name = "TgBotClientError";
|
|
48
|
+
}
|
|
57
49
|
};
|
|
58
50
|
|
|
59
51
|
// src/guards.ts
|
|
60
52
|
var isFileContent = (input) => typeof input == "object" && input != null && "file_content" in input && input.file_content instanceof Uint8Array && "file_name" in input && typeof input.file_name == "string";
|
|
61
53
|
var isTgBotApiResponse = (input) => typeof input == "object" && input != null && "ok" in input && typeof input.ok == "boolean";
|
|
62
|
-
var isTgBotApiUpdate = (input) => typeof input == "object" && input != null && "update_id" in input && typeof input.update_id == "number";
|
|
63
|
-
|
|
64
|
-
// src/config.ts
|
|
65
|
-
var Context = __toESM(require("effect/Context"), 1);
|
|
66
54
|
|
|
67
55
|
// src/const.ts
|
|
68
56
|
var TG_BOT_API_URL = "https://api.telegram.org";
|
|
@@ -82,53 +70,58 @@ var isMessageEffect = (input) => {
|
|
|
82
70
|
};
|
|
83
71
|
|
|
84
72
|
// src/config.ts
|
|
85
|
-
var
|
|
86
|
-
|
|
87
|
-
{ defaultValue: () => TG_BOT_API_URL }
|
|
88
|
-
) {
|
|
73
|
+
var getBaseUrl = (config) => {
|
|
74
|
+
return config?.baseUrl ?? TG_BOT_API_URL;
|
|
89
75
|
};
|
|
90
|
-
|
|
76
|
+
|
|
77
|
+
// src/utils.ts
|
|
78
|
+
var snakeToCamel = (str) => {
|
|
79
|
+
return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
91
80
|
};
|
|
92
81
|
|
|
93
82
|
// src/execute.ts
|
|
94
|
-
|
|
95
|
-
const
|
|
96
|
-
const baseUrl =
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
83
|
+
async function executeTgBotMethod(params) {
|
|
84
|
+
const { config, method, input } = params;
|
|
85
|
+
const baseUrl = getBaseUrl(config);
|
|
86
|
+
const botToken = config.botToken;
|
|
87
|
+
let httpResponse;
|
|
88
|
+
try {
|
|
89
|
+
httpResponse = await fetch(
|
|
90
|
+
`${baseUrl}/bot${botToken}/${snakeToCamel(method)}`,
|
|
91
|
+
{
|
|
92
|
+
body: makePayload(input) ?? null,
|
|
93
|
+
method: "POST"
|
|
94
|
+
}
|
|
95
|
+
);
|
|
96
|
+
} catch (cause) {
|
|
97
|
+
throw new TgBotClientError({
|
|
103
98
|
cause: { _tag: "ClientInternalError", cause }
|
|
104
|
-
})
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
let response;
|
|
102
|
+
try {
|
|
103
|
+
response = await httpResponse.json();
|
|
104
|
+
} catch {
|
|
105
|
+
throw new TgBotClientError({
|
|
109
106
|
cause: { _tag: "NotJsonResponse", response: httpResponse }
|
|
110
|
-
})
|
|
111
|
-
}
|
|
107
|
+
});
|
|
108
|
+
}
|
|
112
109
|
if (!isTgBotApiResponse(response)) {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
})
|
|
117
|
-
);
|
|
110
|
+
throw new TgBotClientError({
|
|
111
|
+
cause: { _tag: "UnexpectedResponse", response }
|
|
112
|
+
});
|
|
118
113
|
}
|
|
119
114
|
if (!httpResponse.ok) {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
})
|
|
128
|
-
);
|
|
115
|
+
throw new TgBotClientError({
|
|
116
|
+
cause: {
|
|
117
|
+
_tag: "NotOkResponse",
|
|
118
|
+
...response.error_code ? { errorCode: response.error_code } : {},
|
|
119
|
+
...response.description ? { details: response.description } : {}
|
|
120
|
+
}
|
|
121
|
+
});
|
|
129
122
|
}
|
|
130
123
|
return response.result;
|
|
131
|
-
}
|
|
124
|
+
}
|
|
132
125
|
var makePayload = (body) => {
|
|
133
126
|
const entries = Object.entries(body);
|
|
134
127
|
if (entries.length == 0) return void 0;
|
|
@@ -147,84 +140,70 @@ var makePayload = (body) => {
|
|
|
147
140
|
};
|
|
148
141
|
|
|
149
142
|
// src/client-file.ts
|
|
150
|
-
var
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
static live = () => {
|
|
154
|
-
return _ClientFileService.context({
|
|
155
|
-
getFile
|
|
156
|
-
});
|
|
157
|
-
};
|
|
158
|
-
};
|
|
159
|
-
var getFile = ({ fileId, type }) => getFileBytes(fileId).pipe(
|
|
160
|
-
Micro2.andThen(
|
|
161
|
-
({ content, file_name }) => new File([content], file_name, {
|
|
162
|
-
...type ? { type } : void 0
|
|
163
|
-
})
|
|
164
|
-
)
|
|
165
|
-
);
|
|
166
|
-
var getFileBytes = (fileId) => Micro2.gen(function* () {
|
|
167
|
-
const response = yield* executeTgBotMethod("get_file", { file_id: fileId });
|
|
143
|
+
var getFileBytes = async (fileId, context) => {
|
|
144
|
+
const { config, execute } = context;
|
|
145
|
+
const response = await execute("get_file", { file_id: fileId });
|
|
168
146
|
const file_path = response.file_path;
|
|
169
|
-
if (!file_path || file_path.length
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
})
|
|
177
|
-
);
|
|
147
|
+
if (!file_path || file_path.length === 0) {
|
|
148
|
+
throw new TgBotClientError({
|
|
149
|
+
cause: {
|
|
150
|
+
_tag: "UnableToGetFile",
|
|
151
|
+
cause: "File path not defined"
|
|
152
|
+
}
|
|
153
|
+
});
|
|
178
154
|
}
|
|
179
155
|
const file_name = file_path.replaceAll("/", "-");
|
|
180
|
-
const baseUrl =
|
|
181
|
-
const botToken =
|
|
156
|
+
const baseUrl = getBaseUrl(config);
|
|
157
|
+
const botToken = config.botToken;
|
|
182
158
|
const url = `${baseUrl}/file/bot${botToken}/${file_path}`;
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
159
|
+
let content;
|
|
160
|
+
try {
|
|
161
|
+
content = await fetch(url).then((_) => _.arrayBuffer());
|
|
162
|
+
} catch (cause) {
|
|
163
|
+
throw new TgBotClientError({
|
|
186
164
|
cause: { _tag: "UnableToGetFile", cause }
|
|
187
|
-
})
|
|
188
|
-
}
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
const base64String = () => Buffer.from(content).toString("base64");
|
|
189
168
|
return {
|
|
190
169
|
content,
|
|
191
|
-
file_name
|
|
170
|
+
file_name,
|
|
171
|
+
base64String
|
|
192
172
|
};
|
|
193
|
-
}
|
|
173
|
+
};
|
|
174
|
+
var getFile = async (input, context) => {
|
|
175
|
+
const { content, file_name } = await getFileBytes(input.fileId, context);
|
|
176
|
+
return new File([content], file_name, {
|
|
177
|
+
...input.type ? { type: input.type } : {}
|
|
178
|
+
});
|
|
179
|
+
};
|
|
194
180
|
|
|
195
181
|
// src/client.ts
|
|
196
|
-
var Micro3 = __toESM(require("effect/Micro"), 1);
|
|
197
|
-
var Context3 = __toESM(require("effect/Context"), 1);
|
|
198
182
|
function makeTgBotClient(config) {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
const
|
|
204
|
-
const execute = (method, input) => executeTgBotMethod(method, input).pipe(
|
|
205
|
-
Micro3.provideContext(context),
|
|
206
|
-
Micro3.runPromise
|
|
207
|
-
);
|
|
208
|
-
const getFile2 = (input) => file.getFile(input).pipe(Micro3.provideContext(context), Micro3.runPromise);
|
|
183
|
+
const tgConfig = {
|
|
184
|
+
botToken: config.bot_token,
|
|
185
|
+
...config.base_url ? { baseUrl: config.base_url } : {}
|
|
186
|
+
};
|
|
187
|
+
const execute = (method, input) => executeTgBotMethod({ config: tgConfig, method, input });
|
|
209
188
|
return {
|
|
210
189
|
execute,
|
|
211
|
-
getFile:
|
|
190
|
+
getFile: (input) => getFile(input, { config: tgConfig, execute })
|
|
212
191
|
};
|
|
213
|
-
}
|
|
192
|
+
}
|
|
214
193
|
// Annotate the CommonJS export names for ESM import in node:
|
|
215
194
|
0 && (module.exports = {
|
|
216
|
-
ClientFileService,
|
|
217
195
|
MESSAGE_EFFECTS,
|
|
218
196
|
TG_BOT_API_URL,
|
|
219
|
-
TgBotApiBaseUrl,
|
|
220
|
-
TgBotApiToken,
|
|
221
197
|
TgBotClientError,
|
|
222
198
|
executeTgBotMethod,
|
|
199
|
+
getBaseUrl,
|
|
200
|
+
getFile,
|
|
201
|
+
getFileBytes,
|
|
223
202
|
isFileContent,
|
|
224
203
|
isMessageEffect,
|
|
225
204
|
isTgBotApiResponse,
|
|
226
|
-
isTgBotApiUpdate,
|
|
227
205
|
makePayload,
|
|
228
206
|
makeTgBotClient,
|
|
229
|
-
messageEffectIdCodes
|
|
207
|
+
messageEffectIdCodes,
|
|
208
|
+
snakeToCamel
|
|
230
209
|
});
|