maxbot-api-client-ts 1.0.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/api.mjs ADDED
@@ -0,0 +1,860 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
3
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
4
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
5
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
+ var __spreadValues = (a, b) => {
7
+ for (var prop in b || (b = {}))
8
+ if (__hasOwnProp.call(b, prop))
9
+ __defNormalProp(a, prop, b[prop]);
10
+ if (__getOwnPropSymbols)
11
+ for (var prop of __getOwnPropSymbols(b)) {
12
+ if (__propIsEnum.call(b, prop))
13
+ __defNormalProp(a, prop, b[prop]);
14
+ }
15
+ return a;
16
+ };
17
+ var __async = (__this, __arguments, generator) => {
18
+ return new Promise((resolve, reject) => {
19
+ var fulfilled = (value) => {
20
+ try {
21
+ step(generator.next(value));
22
+ } catch (e) {
23
+ reject(e);
24
+ }
25
+ };
26
+ var rejected = (value) => {
27
+ try {
28
+ step(generator.throw(value));
29
+ } catch (e) {
30
+ reject(e);
31
+ }
32
+ };
33
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
34
+ step((generator = generator.apply(__this, __arguments)).next());
35
+ });
36
+ };
37
+
38
+ // src/models/const.ts
39
+ var Defaultbase_url = "https://platform-api.max.ru";
40
+ var Paths = {
41
+ Me: "me",
42
+ Chats: "chats",
43
+ Answers: "answers",
44
+ Updates: "updates",
45
+ Uploads: "uploads",
46
+ Messages: "messages",
47
+ Subscriptions: "subscriptions",
48
+ Videos: "videos"
49
+ };
50
+
51
+ // src/client/client.ts
52
+ var RateLimiter = class {
53
+ constructor(rps) {
54
+ this.queue = [];
55
+ this.timeoutId = null;
56
+ this.rps = rps;
57
+ this.tokens = rps;
58
+ this.lastRefill = Date.now();
59
+ }
60
+ wait() {
61
+ return __async(this, null, function* () {
62
+ return new Promise((resolve) => {
63
+ this.queue.push(resolve);
64
+ this.processQueue();
65
+ });
66
+ });
67
+ }
68
+ processQueue() {
69
+ const now = Date.now();
70
+ const timePassed = now - this.lastRefill;
71
+ this.tokens += timePassed * (this.rps / 1e3);
72
+ if (this.tokens > this.rps) {
73
+ this.tokens = this.rps;
74
+ }
75
+ this.lastRefill = now;
76
+ while (this.queue.length > 0 && this.tokens >= 1) {
77
+ this.tokens -= 1;
78
+ const resolve = this.queue.shift();
79
+ if (resolve) resolve();
80
+ }
81
+ if (this.queue.length > 0 && !this.timeoutId) {
82
+ const timeToNextToken = Math.ceil(1 / this.rps * 1e3);
83
+ this.timeoutId = setTimeout(() => {
84
+ this.timeoutId = null;
85
+ this.processQueue();
86
+ }, timeToNextToken);
87
+ }
88
+ }
89
+ setLimit(rps) {
90
+ this.rps = rps;
91
+ this.tokens = rps;
92
+ }
93
+ };
94
+ var APIClient = class {
95
+ constructor(cfg) {
96
+ if (!cfg.token) {
97
+ throw new Error("Token is not set");
98
+ }
99
+ this.base_url = cfg.base_url || Defaultbase_url;
100
+ this.token = cfg.token;
101
+ this.timeout = cfg.timeout || 35e3;
102
+ const rps = cfg.globalRPS && cfg.globalRPS > 0 ? cfg.globalRPS : 25;
103
+ this.rateLimiter = new RateLimiter(rps);
104
+ }
105
+ request(_0, _1) {
106
+ return __async(this, arguments, function* (method, path, opts = {}) {
107
+ let urlObj;
108
+ if (path.startsWith("http://") || path.startsWith("https://")) {
109
+ urlObj = new URL(path);
110
+ } else {
111
+ urlObj = new URL(path, this.base_url);
112
+ }
113
+ if (opts.query) {
114
+ Object.entries(opts.query).forEach(([key, value]) => {
115
+ if (value !== void 0 && value !== null) {
116
+ if (Array.isArray(value)) {
117
+ value.forEach((v) => urlObj.searchParams.append(key, String(v)));
118
+ } else {
119
+ urlObj.searchParams.set(key, String(value));
120
+ }
121
+ }
122
+ });
123
+ }
124
+ const headers = __spreadValues({
125
+ "Authorization": this.token
126
+ }, opts.headers);
127
+ let body = opts.body;
128
+ if (opts.payload && !body) {
129
+ body = JSON.stringify(opts.payload);
130
+ headers["Content-Type"] = "application/json";
131
+ } else if (!headers["Content-Type"] && !opts.body) {
132
+ headers["Content-Type"] = "application/json";
133
+ }
134
+ const controller = new AbortController();
135
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
136
+ try {
137
+ yield this.rateLimiter.wait();
138
+ const response = yield fetch(urlObj.toString(), {
139
+ method,
140
+ headers,
141
+ body,
142
+ signal: controller.signal
143
+ });
144
+ const text = yield response.text();
145
+ if (!response.ok) {
146
+ throw new Error(`[${method} ${urlObj.pathname}] HTTP ${response.status}: ${text}`);
147
+ }
148
+ if (!text) {
149
+ return {};
150
+ }
151
+ return JSON.parse(text);
152
+ } catch (error) {
153
+ throw error;
154
+ } finally {
155
+ clearTimeout(timeoutId);
156
+ }
157
+ });
158
+ }
159
+ setGlobalRateLimit(rps) {
160
+ this.rateLimiter.setLimit(rps);
161
+ }
162
+ getTimeout() {
163
+ return this.timeout;
164
+ }
165
+ };
166
+
167
+ // src/api/bots.ts
168
+ var BotsService = class {
169
+ constructor(client) {
170
+ this.client = client;
171
+ }
172
+ /**
173
+ * GetBot returns information about the current bot (ID, name, description).
174
+ * @returns Promise<BotInfo>
175
+ * @example
176
+ * const response = await bot.bots.getBot();
177
+ * console.log("Connected as:", info.first_name);
178
+ */
179
+ getBot() {
180
+ return __async(this, null, function* () {
181
+ return this.client.request("GET", Paths.Me);
182
+ });
183
+ }
184
+ /**
185
+ * PatchBot updates bot information.
186
+ * Fill in only the fields you want to change.
187
+ * @param req - The bot data to update.
188
+ * @returns Promise<BotInfo>
189
+ * @example
190
+ * const response = await bot.bots.patchBot({
191
+ * name: "New Name",
192
+ * description: "New description"
193
+ * });
194
+ */
195
+ patchBot(req) {
196
+ return __async(this, null, function* () {
197
+ return this.client.request("PATCH", Paths.Me, { payload: req });
198
+ });
199
+ }
200
+ };
201
+
202
+ // src/api/chats.ts
203
+ var ChatsService = class {
204
+ constructor(client) {
205
+ this.client = client;
206
+ }
207
+ /**
208
+ * GetChats returns a list of group chats in which the bot participated.
209
+ * @param req - Filter parameters for chats.
210
+ * @example
211
+ * const response = await bot.chats.getChats({ limit: 10 });
212
+ */
213
+ getChats(req) {
214
+ return __async(this, null, function* () {
215
+ return this.client.request("GET", Paths.Chats, {
216
+ query: req
217
+ });
218
+ });
219
+ }
220
+ /**
221
+ * GetChat returns information about a group chat by its ID.
222
+ * @param req - Object containing the chat_id.
223
+ * @example
224
+ * const response = await bot.chats.getChat({ chat_id: 123456789 });
225
+ */
226
+ getChat(req) {
227
+ return __async(this, null, function* () {
228
+ return this.client.request("GET", `${Paths.Chats}/${req.chat_id}`);
229
+ });
230
+ }
231
+ /**
232
+ * EditChat allows you to edit information about a group chat.
233
+ * @param req - Chat edit parameters.
234
+ * @example
235
+ * await bot.chats.editChat({ chat_id: 123456789, title: "New Title" });
236
+ */
237
+ editChat(req) {
238
+ return __async(this, null, function* () {
239
+ return this.client.request("PATCH", `${Paths.Chats}/${req.chat_id}`, {
240
+ payload: req
241
+ });
242
+ });
243
+ }
244
+ /**
245
+ * DeleteChat deletes a group chat for all participants.
246
+ * @example
247
+ * await bot.chats.deleteChat({ chat_id: 123456789 });
248
+ */
249
+ deleteChat(req) {
250
+ return __async(this, null, function* () {
251
+ return this.client.request("DELETE", `${Paths.Chats}/${req.chat_id}`);
252
+ });
253
+ }
254
+ /**
255
+ * SendAction allows sending bot actions to a group chat (e.g., "typing").
256
+ * @example
257
+ * await bot.chats.sendAction({ chat_id: 123456789, action: "typing" });
258
+ */
259
+ sendAction(req) {
260
+ return __async(this, null, function* () {
261
+ return this.client.request("POST", `${Paths.Chats}/${req.chat_id}/actions`, {
262
+ payload: req
263
+ });
264
+ });
265
+ }
266
+ /**
267
+ * GetPinnedMessage returns the pinned message in a chat.
268
+ * @example
269
+ * const response = await bot.chats.getPinnedMessage({ chat_id: 123456789 });
270
+ */
271
+ getPinnedMessage(req) {
272
+ return __async(this, null, function* () {
273
+ return this.client.request("GET", `${Paths.Chats}/${req.chat_id}/pin`);
274
+ });
275
+ }
276
+ /**
277
+ * PinMessage pins a message in a group chat.
278
+ * @example
279
+ * await bot.chats.pinMessage({ chat_id: 123456789, message_id: "456" });
280
+ */
281
+ pinMessage(req) {
282
+ return __async(this, null, function* () {
283
+ return this.client.request("PUT", `${Paths.Chats}/${req.chat_id}/pin`, {
284
+ payload: req
285
+ });
286
+ });
287
+ }
288
+ /**
289
+ * UnpinMessage removes the pinned message in a group chat.
290
+ * @example
291
+ * await bot.chats.unpinMessage({ chat_id: 123456789 });
292
+ */
293
+ unpinMessage(req) {
294
+ return __async(this, null, function* () {
295
+ return this.client.request("DELETE", `${Paths.Chats}/${req.chat_id}/pin`);
296
+ });
297
+ }
298
+ /**
299
+ * GetChatMembership returns the bot's membership details in a group chat.
300
+ * @example
301
+ * const response = await bot.chats.getChatMembership({ chat_id: 123456789 });
302
+ */
303
+ getChatMembership(req) {
304
+ return __async(this, null, function* () {
305
+ return this.client.request("GET", `${Paths.Chats}/${req.chat_id}/members/me`);
306
+ });
307
+ }
308
+ /**
309
+ * LeaveChat removes the bot from a group chat.
310
+ * @example
311
+ * await bot.chats.leaveChat({ chat_id: 123456789 });
312
+ */
313
+ leaveChat(req) {
314
+ return __async(this, null, function* () {
315
+ return this.client.request("DELETE", `${Paths.Chats}/${req.chat_id}/members/me`);
316
+ });
317
+ }
318
+ /**
319
+ * GetChatAdmins returns a list of all group chat administrators.
320
+ * @example
321
+ * const response = await bot.chats.getChatAdmins({ chat_id: 123456789 });
322
+ */
323
+ getChatAdmins(req) {
324
+ return __async(this, null, function* () {
325
+ return this.client.request("GET", `${Paths.Chats}/${req.chat_id}/members/admins`);
326
+ });
327
+ }
328
+ /**
329
+ * SetChatAdmins assigns a group member as an administrator.
330
+ * @example
331
+ * await bot.chats.setChatAdmins({ chat_id: 123456789, user_id: 456 });
332
+ */
333
+ setChatAdmins(req) {
334
+ return __async(this, null, function* () {
335
+ return this.client.request("POST", `${Paths.Chats}/${req.chat_id}/members/admins`, {
336
+ payload: req
337
+ });
338
+ });
339
+ }
340
+ /**
341
+ * DeleteAdmin revokes the user's administrator rights in a group chat.
342
+ * @example
343
+ * await bot.chats.deleteAdmin({ chat_id: 123456789, user_id: 456 });
344
+ */
345
+ deleteAdmin(req) {
346
+ return __async(this, null, function* () {
347
+ return this.client.request("DELETE", `${Paths.Chats}/${req.chat_id}/members/admins/${req.user_id}`);
348
+ });
349
+ }
350
+ /**
351
+ * GetChatMembers returns a list of participants in a group chat.
352
+ * @example
353
+ * const response = await bot.chats.getChatMembers({ chat_id: 123456789, limit: 50 });
354
+ */
355
+ getChatMembers(req) {
356
+ return __async(this, null, function* () {
357
+ return this.client.request("GET", `${Paths.Chats}/${req.chat_id}/members`, {
358
+ query: req
359
+ });
360
+ });
361
+ }
362
+ /**
363
+ * AddMembers adds participants to a group chat.
364
+ * @example
365
+ * await bot.chats.addMembers({ chat_id: 123456789, user_ids: [456, 789] });
366
+ */
367
+ addMembers(req) {
368
+ return __async(this, null, function* () {
369
+ return this.client.request("POST", `${Paths.Chats}/${req.chat_id}/members`, {
370
+ payload: req
371
+ });
372
+ });
373
+ }
374
+ /**
375
+ * DeleteMember removes a participant from a group chat.
376
+ * @example
377
+ * await bot.chats.deleteMember({ chat_id: 123456789, user_id: 456 });
378
+ */
379
+ deleteMember(req) {
380
+ return __async(this, null, function* () {
381
+ return this.client.request("DELETE", `${Paths.Chats}/${req.chat_id}/members`, {
382
+ query: req
383
+ });
384
+ });
385
+ }
386
+ };
387
+
388
+ // src/api/helpers.ts
389
+ import { tmpdir } from "os";
390
+ import { join, extname, basename as basename2 } from "path";
391
+ import { writeFile } from "fs/promises";
392
+
393
+ // src/api/uploads.ts
394
+ import { readFile } from "fs/promises";
395
+ import { basename } from "path";
396
+ import { randomBytes } from "crypto";
397
+ var UploadsService = class {
398
+ constructor(client) {
399
+ this.client = client;
400
+ }
401
+ /**
402
+ * UploadFile uploads a file to MAX servers for subsequent transmission.
403
+ * It handles both the initial request for an upload URL and the actual multipart upload.
404
+ * @param req - Upload parameters (type, file_path).
405
+ * @returns Promise<UploadedInfo> containing the file token.
406
+ * @example
407
+ * const response = await bot.uploads.uploadFile({ type: "image", file_path: "./corgi.png" });
408
+ * console.log("File token:", file.token);
409
+ */
410
+ uploadFile(req) {
411
+ return __async(this, null, function* () {
412
+ const initResp = yield this.getupload_url(req.type);
413
+ if (!initResp.url) {
414
+ if (initResp.token) {
415
+ return { token: initResp.token };
416
+ }
417
+ throw new Error("Upload failed: server did not return an upload URL or token.");
418
+ }
419
+ let multipartResp;
420
+ try {
421
+ multipartResp = yield this.uploadMultipart(initResp.url, req.file_path);
422
+ if (multipartResp) {
423
+ if (multipartResp.token) {
424
+ return { token: multipartResp.token };
425
+ }
426
+ const anyResp = multipartResp;
427
+ if (anyResp.photos) {
428
+ const photoKeys = Object.keys(anyResp.photos);
429
+ if (photoKeys.length > 0 && anyResp.photos[photoKeys[0]].token) {
430
+ return { token: anyResp.photos[photoKeys[0]].token };
431
+ }
432
+ }
433
+ }
434
+ } catch (err) {
435
+ if (initResp.token) {
436
+ return { token: initResp.token };
437
+ }
438
+ throw err;
439
+ }
440
+ if (initResp.token) {
441
+ return { token: initResp.token };
442
+ }
443
+ throw new Error(`Server did not return a token after upload. Response: ${JSON.stringify(multipartResp)}`);
444
+ });
445
+ }
446
+ getupload_url(uploadType) {
447
+ return __async(this, null, function* () {
448
+ return this.client.request("POST", Paths.Uploads, {
449
+ query: { type: uploadType }
450
+ });
451
+ });
452
+ }
453
+ uploadMultipart(upload_url, file_path) {
454
+ return __async(this, null, function* () {
455
+ const fileData = yield readFile(file_path);
456
+ const filename = basename(file_path);
457
+ const boundary = "----MaxBotFormBoundary" + randomBytes(16).toString("hex");
458
+ const CRLF = "\r\n";
459
+ const header = Buffer.from(
460
+ `--${boundary}${CRLF}Content-Disposition: form-data; name="file"; filename="${filename}"${CRLF}Content-Type: application/octet-stream${CRLF}${CRLF}`
461
+ );
462
+ const footer = Buffer.from(`${CRLF}--${boundary}--${CRLF}`);
463
+ const payload = Buffer.concat([header, fileData, footer]);
464
+ return this.client.request("POST", upload_url, {
465
+ body: payload,
466
+ headers: {
467
+ "Content-Type": `multipart/form-data; boundary=${boundary}`,
468
+ "Content-Length": payload.length.toString()
469
+ }
470
+ });
471
+ });
472
+ }
473
+ };
474
+
475
+ // src/models/schema.ts
476
+ function attachImage(token, url) {
477
+ const payload = {};
478
+ if (token) payload.token = token;
479
+ if (url) payload.url = url;
480
+ return {
481
+ type: "image" /* Image */,
482
+ payload
483
+ };
484
+ }
485
+ function attachVideo(token, url) {
486
+ const payload = {};
487
+ if (token) payload.token = token;
488
+ if (url) payload.url = url;
489
+ return {
490
+ type: "video" /* Video */,
491
+ payload
492
+ };
493
+ }
494
+ function attachAudio(token, url) {
495
+ const payload = {};
496
+ if (token) payload.token = token;
497
+ if (url) payload.url = url;
498
+ return {
499
+ type: "audio" /* Audio */,
500
+ payload
501
+ };
502
+ }
503
+ function attachFile(token, url, filename) {
504
+ const payload = { filename: filename || "" };
505
+ if (token) payload.token = token;
506
+ if (url) payload.url = url;
507
+ return {
508
+ type: "file" /* File */,
509
+ payload
510
+ };
511
+ }
512
+
513
+ // src/api/helpers.ts
514
+ var MIME_TO_EXT = {
515
+ "image/jpeg": ".jpg",
516
+ "image/png": ".png",
517
+ "image/webp": ".webp",
518
+ "video/mp4": ".mp4",
519
+ "audio/mpeg": ".mp3",
520
+ "audio/ogg": ".ogg",
521
+ "audio/wav": ".wav",
522
+ "application/pdf": ".pdf"
523
+ };
524
+ var HelpersService = class {
525
+ constructor(client) {
526
+ this.client = client;
527
+ }
528
+ /**
529
+ * SendFile simplifies file sending by automatically determining if the source is a URL or a local path.
530
+ * @param req - File send request parameters.
531
+ * @example
532
+ * await bot.helpers.sendFile({ chat_id: 123, file_source: "./photo.jpg" });
533
+ * await bot.helpers.sendFile({ chat_id: 123, file_source: "https://site.com/image.png" });
534
+ */
535
+ sendFile(req) {
536
+ return __async(this, null, function* () {
537
+ if (this.isURL(req.file_source)) {
538
+ return this.sendFileByUrl(req);
539
+ }
540
+ return this.sendFileByUpload(req);
541
+ });
542
+ }
543
+ /**
544
+ * SendFileByUrl sends a file using a direct URL. If the file is not an image,
545
+ * it will be downloaded to a temporary directory and uploaded to MAX servers.
546
+ * @param req - File send request with a URL in file_source.
547
+ */
548
+ sendFileByUrl(req) {
549
+ return __async(this, null, function* () {
550
+ const extInUrl = this.getExtension(req.file_source);
551
+ if (this.determineUploadType(extInUrl) === "image" /* Image */) {
552
+ const attachment2 = {
553
+ type: "image" /* Image */,
554
+ payload: { url: req.file_source }
555
+ };
556
+ return this.sendInternal(req, attachment2);
557
+ }
558
+ const { tempPath, ext } = yield this.downloadTempFile(req.file_source);
559
+ const uploadType = this.determineUploadType(ext);
560
+ const uploader = new UploadsService(this.client);
561
+ const uploadResp = yield uploader.uploadFile({
562
+ type: uploadType,
563
+ file_path: tempPath
564
+ });
565
+ const filename = basename2(req.file_source);
566
+ const attachment = this.buildAttachmentFromToken(uploadType, uploadResp.token, filename);
567
+ return this.sendInternal(req, attachment);
568
+ });
569
+ }
570
+ /**
571
+ * SendFileByUpload uploads a local file to MAX servers and sends it to the chat.
572
+ * @param req - File send request with a local path in file_source.
573
+ */
574
+ sendFileByUpload(req) {
575
+ return __async(this, null, function* () {
576
+ const ext = this.getExtension(req.file_source);
577
+ const uploadType = this.determineUploadType(ext);
578
+ const uploader = new UploadsService(this.client);
579
+ const uploadResp = yield uploader.uploadFile({
580
+ type: uploadType,
581
+ file_path: req.file_source
582
+ });
583
+ if (!uploadResp.token) {
584
+ throw new Error("Failed to auto-upload file: no token returned");
585
+ }
586
+ const filename = basename2(req.file_source);
587
+ const attachment = this.buildAttachmentFromToken(uploadType, uploadResp.token, filename);
588
+ return this.sendInternal(req, attachment);
589
+ });
590
+ }
591
+ sendInternal(req, attachment) {
592
+ return __async(this, null, function* () {
593
+ const allAttachments = [...req.attachments || [], attachment];
594
+ const requestPayload = {
595
+ user_id: req.user_id,
596
+ chat_id: req.chat_id,
597
+ text: req.text,
598
+ format: req.format,
599
+ attachments: allAttachments,
600
+ notify: req.notify,
601
+ link: req.link,
602
+ disable_link_preview: req.disable_link_preview
603
+ };
604
+ let lastErr;
605
+ for (let i = 0; i < 3; i++) {
606
+ try {
607
+ const response = yield this.client.request("POST", Paths.Messages, {
608
+ query: requestPayload,
609
+ payload: requestPayload
610
+ });
611
+ return response;
612
+ } catch (err) {
613
+ lastErr = err;
614
+ if (err.message && err.message.includes("not.ready")) {
615
+ yield new Promise((resolve) => setTimeout(resolve, 3e3));
616
+ continue;
617
+ }
618
+ break;
619
+ }
620
+ }
621
+ throw lastErr;
622
+ });
623
+ }
624
+ isURL(str) {
625
+ try {
626
+ const u = new URL(str);
627
+ return u.protocol === "http:" || u.protocol === "https:";
628
+ } catch (e) {
629
+ return false;
630
+ }
631
+ }
632
+ getExtension(source) {
633
+ if (this.isURL(source)) {
634
+ try {
635
+ const u = new URL(source);
636
+ return extname(u.pathname).toLowerCase();
637
+ } catch (e) {
638
+ return "";
639
+ }
640
+ }
641
+ return extname(source).toLowerCase();
642
+ }
643
+ determineUploadType(ext) {
644
+ switch (ext) {
645
+ case ".jpg":
646
+ case ".jpeg":
647
+ case ".png":
648
+ case ".webp":
649
+ return "image" /* Image */;
650
+ case ".mp4":
651
+ case ".avi":
652
+ case ".mov":
653
+ return "video" /* Video */;
654
+ case ".mp3":
655
+ case ".ogg":
656
+ case ".wav":
657
+ return "audio" /* Audio */;
658
+ default:
659
+ return "file" /* File */;
660
+ }
661
+ }
662
+ buildAttachmentFromToken(uType, token, filename) {
663
+ switch (uType) {
664
+ case "image" /* Image */:
665
+ return attachImage(token, "");
666
+ case "video" /* Video */:
667
+ return attachVideo(token, "");
668
+ case "audio" /* Audio */:
669
+ return attachAudio(token, "");
670
+ default:
671
+ return attachFile(token, "", filename);
672
+ }
673
+ }
674
+ downloadTempFile(urlStr) {
675
+ return __async(this, null, function* () {
676
+ const resp = yield fetch(urlStr);
677
+ if (!resp.ok) {
678
+ throw new Error(`Failed to download file: ${resp.statusText}`);
679
+ }
680
+ let contentType = resp.headers.get("Content-Type") || "";
681
+ contentType = contentType.split(";")[0].trim();
682
+ let ext = MIME_TO_EXT[contentType];
683
+ if (!ext) {
684
+ ext = this.getExtension(urlStr);
685
+ }
686
+ if (!ext) {
687
+ ext = ".bin";
688
+ }
689
+ const buffer = yield resp.arrayBuffer();
690
+ const tempFileName = `maxbot_${Date.now()}_${Math.floor(Math.random() * 1e4)}${ext}`;
691
+ const tempPath = join(tmpdir(), tempFileName);
692
+ yield writeFile(tempPath, Buffer.from(buffer));
693
+ return { tempPath, ext };
694
+ });
695
+ }
696
+ };
697
+
698
+ // src/api/messages.ts
699
+ var MessagesService = class {
700
+ constructor(client) {
701
+ this.client = client;
702
+ }
703
+ /**
704
+ * GetMessages returns information about a message or an array of messages from a chat.
705
+ * @param req - Query parameters (chat_id, user_id, limit, etc.).
706
+ * @example
707
+ * const response = await bot.messages.getMessages({ chat_id: 123, limit: 10 });
708
+ */
709
+ getMessages(req) {
710
+ return __async(this, null, function* () {
711
+ return this.client.request("GET", Paths.Messages, {
712
+ query: req
713
+ });
714
+ });
715
+ }
716
+ /**
717
+ * SendMessage sends a text or media message to a specified user or chat.
718
+ * @param req - Message parameters including text and attachments.
719
+ * @example
720
+ * await bot.messages.sendMessage({ user_id: 123, text: "Hello!" });
721
+ */
722
+ sendMessage(req) {
723
+ return __async(this, null, function* () {
724
+ return this.client.request("POST", Paths.Messages, {
725
+ query: req,
726
+ payload: req
727
+ });
728
+ });
729
+ }
730
+ /**
731
+ * EditMessage edits the text or media of a previously sent message.
732
+ * @param req - Edit parameters (message_id, new text, etc.).
733
+ * @example
734
+ * await bot.messages.editMessage({ message_id: 456, text: "Updated text" });
735
+ */
736
+ editMessage(req) {
737
+ return __async(this, null, function* () {
738
+ return this.client.request("PUT", Paths.Messages, {
739
+ query: req,
740
+ payload: req
741
+ });
742
+ });
743
+ }
744
+ /**
745
+ * DeleteMessage deletes a message from a chat.
746
+ * @example
747
+ * await bot.messages.deleteMessage({ chat_id: 123, message_id: 456 });
748
+ */
749
+ deleteMessage(req) {
750
+ return __async(this, null, function* () {
751
+ return this.client.request("DELETE", Paths.Messages, {
752
+ query: req
753
+ });
754
+ });
755
+ }
756
+ /**
757
+ * GetMessage extracts the content and metadata of a specific message by its ID.
758
+ * @example
759
+ * const response = await bot.messages.getMessage({ message_id: 456 });
760
+ */
761
+ getMessage(req) {
762
+ return __async(this, null, function* () {
763
+ return this.client.request("GET", `${Paths.Messages}/${req.message_id}`);
764
+ });
765
+ }
766
+ /**
767
+ * GetVideoInfo returns detailed information about an attached video.
768
+ * @example
769
+ * const response = await bot.messages.getVideoInfo({ video_token: "video123" });
770
+ */
771
+ getVideoInfo(req) {
772
+ return __async(this, null, function* () {
773
+ return this.client.request("GET", `${Paths.Videos}/${req.video_token}`);
774
+ });
775
+ }
776
+ /**
777
+ * AnswerCallback sends a response after a user clicks a button.
778
+ * @example
779
+ * await bot.messages.answerCallback({ callback_id: "cb123", text: "Got it!" });
780
+ */
781
+ answerCallback(req) {
782
+ return __async(this, null, function* () {
783
+ return this.client.request("POST", Paths.Answers, {
784
+ query: req,
785
+ payload: req
786
+ });
787
+ });
788
+ }
789
+ };
790
+
791
+ // src/api/subscriptions.ts
792
+ var SubscriptionsService = class {
793
+ constructor(client) {
794
+ this.client = client;
795
+ }
796
+ /**
797
+ * GetSubscriptions returns a list of webhook notification subscriptions.
798
+ * @example
799
+ * const response = await bot.subscriptions.getSubscriptions();
800
+ */
801
+ getSubscriptions() {
802
+ return __async(this, null, function* () {
803
+ return this.client.request("GET", Paths.Subscriptions);
804
+ });
805
+ }
806
+ /**
807
+ * Subscribe configures the delivery of bot events via a webhook.
808
+ * @param req - Subscription parameters (url, types).
809
+ * @example
810
+ * await bot.subscriptions.subscribe({ url: "https://my.site/webhook", types: ["message.created"] });
811
+ */
812
+ subscribe(req) {
813
+ return __async(this, null, function* () {
814
+ return this.client.request("POST", Paths.Subscriptions, {
815
+ payload: req
816
+ });
817
+ });
818
+ }
819
+ /**
820
+ * Unsubscribe cancels the bot's subscription to receiving updates via webhook.
821
+ * @example
822
+ * await bot.subscriptions.unsubscribe({ url: "https://my.site/webhook" });
823
+ */
824
+ unsubscribe(req) {
825
+ return __async(this, null, function* () {
826
+ return this.client.request("DELETE", Paths.Subscriptions, {
827
+ query: req
828
+ });
829
+ });
830
+ }
831
+ /**
832
+ * GetUpdates retrieves incoming updates (Long-polling).
833
+ * @param req - Polling parameters (marker, timeout, limit).
834
+ * @example
835
+ * const response = await bot.subscriptions.getUpdates({ timeout: 25 });
836
+ */
837
+ getUpdates(req) {
838
+ return __async(this, null, function* () {
839
+ return this.client.request("GET", Paths.Updates, {
840
+ query: req
841
+ });
842
+ });
843
+ }
844
+ };
845
+
846
+ // src/api/api.ts
847
+ var MaxBotAPI = class {
848
+ constructor(cfg) {
849
+ this.client = new APIClient(cfg);
850
+ this.bots = new BotsService(this.client);
851
+ this.chats = new ChatsService(this.client);
852
+ this.helpers = new HelpersService(this.client);
853
+ this.messages = new MessagesService(this.client);
854
+ this.subscriptions = new SubscriptionsService(this.client);
855
+ this.uploads = new UploadsService(this.client);
856
+ }
857
+ };
858
+ export {
859
+ MaxBotAPI
860
+ };