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