@ihazz/bitrix24 1.1.2 → 1.1.4

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.
Files changed (104) hide show
  1. package/README.md +5 -0
  2. package/dist/index.d.ts +30 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +55 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/src/access-control.d.ts +43 -0
  7. package/dist/src/access-control.d.ts.map +1 -0
  8. package/dist/src/access-control.js +128 -0
  9. package/dist/src/access-control.js.map +1 -0
  10. package/dist/src/api.d.ts +161 -0
  11. package/dist/src/api.d.ts.map +1 -0
  12. package/dist/src/api.js +357 -0
  13. package/dist/src/api.js.map +1 -0
  14. package/dist/src/bot-avatar.d.ts +7 -0
  15. package/dist/src/bot-avatar.d.ts.map +1 -0
  16. package/dist/src/bot-avatar.js +7 -0
  17. package/dist/src/bot-avatar.js.map +1 -0
  18. package/dist/src/channel.d.ts +216 -0
  19. package/dist/src/channel.d.ts.map +1 -0
  20. package/dist/src/channel.js +2324 -0
  21. package/dist/src/channel.js.map +1 -0
  22. package/dist/src/commands.d.ts +22 -0
  23. package/dist/src/commands.d.ts.map +1 -0
  24. package/dist/src/commands.js +160 -0
  25. package/dist/src/commands.js.map +1 -0
  26. package/dist/src/config-schema.d.ts +356 -0
  27. package/dist/src/config-schema.d.ts.map +1 -0
  28. package/dist/src/config-schema.js +43 -0
  29. package/dist/src/config-schema.js.map +1 -0
  30. package/dist/src/config.d.ts +11 -0
  31. package/dist/src/config.d.ts.map +1 -0
  32. package/dist/src/config.js +50 -0
  33. package/dist/src/config.js.map +1 -0
  34. package/dist/src/dedup.d.ts +22 -0
  35. package/dist/src/dedup.d.ts.map +1 -0
  36. package/dist/src/dedup.js +49 -0
  37. package/dist/src/dedup.js.map +1 -0
  38. package/dist/src/group-access.d.ts +52 -0
  39. package/dist/src/group-access.d.ts.map +1 -0
  40. package/dist/src/group-access.js +180 -0
  41. package/dist/src/group-access.js.map +1 -0
  42. package/dist/src/history-cache.d.ts +41 -0
  43. package/dist/src/history-cache.d.ts.map +1 -0
  44. package/dist/src/history-cache.js +82 -0
  45. package/dist/src/history-cache.js.map +1 -0
  46. package/dist/src/i18n.d.ts +22 -0
  47. package/dist/src/i18n.d.ts.map +1 -0
  48. package/dist/src/i18n.js +175 -0
  49. package/dist/src/i18n.js.map +1 -0
  50. package/dist/src/inbound-handler.d.ts +92 -0
  51. package/dist/src/inbound-handler.d.ts.map +1 -0
  52. package/dist/src/inbound-handler.js +417 -0
  53. package/dist/src/inbound-handler.js.map +1 -0
  54. package/dist/src/media-service.d.ts +52 -0
  55. package/dist/src/media-service.d.ts.map +1 -0
  56. package/dist/src/media-service.js +423 -0
  57. package/dist/src/media-service.js.map +1 -0
  58. package/dist/src/message-utils.d.ts +34 -0
  59. package/dist/src/message-utils.d.ts.map +1 -0
  60. package/dist/src/message-utils.js +392 -0
  61. package/dist/src/message-utils.js.map +1 -0
  62. package/dist/src/polling-service.d.ts +39 -0
  63. package/dist/src/polling-service.d.ts.map +1 -0
  64. package/dist/src/polling-service.js +204 -0
  65. package/dist/src/polling-service.js.map +1 -0
  66. package/dist/src/rate-limiter.d.ts +22 -0
  67. package/dist/src/rate-limiter.d.ts.map +1 -0
  68. package/dist/src/rate-limiter.js +72 -0
  69. package/dist/src/rate-limiter.js.map +1 -0
  70. package/dist/src/runtime.d.ts +106 -0
  71. package/dist/src/runtime.d.ts.map +1 -0
  72. package/dist/src/runtime.js +11 -0
  73. package/dist/src/runtime.js.map +1 -0
  74. package/dist/src/send-service.d.ts +66 -0
  75. package/dist/src/send-service.d.ts.map +1 -0
  76. package/dist/src/send-service.js +177 -0
  77. package/dist/src/send-service.js.map +1 -0
  78. package/dist/src/state-paths.d.ts +3 -0
  79. package/dist/src/state-paths.d.ts.map +1 -0
  80. package/dist/src/state-paths.js +23 -0
  81. package/dist/src/state-paths.js.map +1 -0
  82. package/dist/src/types.d.ts +381 -0
  83. package/dist/src/types.d.ts.map +1 -0
  84. package/dist/src/types.js +3 -0
  85. package/dist/src/types.js.map +1 -0
  86. package/dist/src/utils.d.ts +60 -0
  87. package/dist/src/utils.d.ts.map +1 -0
  88. package/dist/src/utils.js +131 -0
  89. package/dist/src/utils.js.map +1 -0
  90. package/index.ts +1 -1
  91. package/openclaw.plugin.json +278 -1
  92. package/package.json +11 -2
  93. package/src/api.ts +0 -3
  94. package/src/channel.ts +76 -73
  95. package/src/config-schema.ts +1 -2
  96. package/src/config.ts +6 -8
  97. package/src/group-access.ts +1 -8
  98. package/src/inbound-handler.ts +128 -15
  99. package/src/media-service.ts +160 -45
  100. package/src/polling-service.ts +2 -3
  101. package/src/send-service.ts +4 -3
  102. package/src/state-paths.ts +4 -0
  103. package/src/types.ts +1 -2
  104. package/src/utils.ts +31 -4
@@ -0,0 +1,423 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { isIP } from 'node:net';
3
+ import { createReadStream, createWriteStream } from 'node:fs';
4
+ import { writeFile, mkdir, stat, unlink, rename, realpath } from 'node:fs/promises';
5
+ import { join, basename, relative, sep } from 'node:path';
6
+ import { Readable, Transform } from 'node:stream';
7
+ import { pipeline } from 'node:stream/promises';
8
+ import { resolveManagedMediaDir } from './state-paths.js';
9
+ import { defaultLogger, maskUrlForLog, serializeError } from './utils.js';
10
+ const MIME_MAP = {
11
+ jpg: 'image/jpeg',
12
+ jpeg: 'image/jpeg',
13
+ png: 'image/png',
14
+ gif: 'image/gif',
15
+ webp: 'image/webp',
16
+ svg: 'image/svg+xml',
17
+ bmp: 'image/bmp',
18
+ ico: 'image/x-icon',
19
+ tiff: 'image/tiff',
20
+ tif: 'image/tiff',
21
+ mp4: 'video/mp4',
22
+ webm: 'video/webm',
23
+ avi: 'video/x-msvideo',
24
+ mov: 'video/quicktime',
25
+ mkv: 'video/x-matroska',
26
+ mp3: 'audio/mpeg',
27
+ wav: 'audio/wav',
28
+ ogg: 'audio/ogg',
29
+ flac: 'audio/flac',
30
+ pdf: 'application/pdf',
31
+ doc: 'application/msword',
32
+ docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
33
+ xls: 'application/vnd.ms-excel',
34
+ xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
35
+ ppt: 'application/vnd.ms-powerpoint',
36
+ pptx: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
37
+ zip: 'application/zip',
38
+ rar: 'application/x-rar-compressed',
39
+ gz: 'application/gzip',
40
+ tar: 'application/x-tar',
41
+ txt: 'text/plain',
42
+ csv: 'text/csv',
43
+ html: 'text/html',
44
+ css: 'text/css',
45
+ js: 'application/javascript',
46
+ json: 'application/json',
47
+ xml: 'application/xml',
48
+ };
49
+ function mimeFromExtension(ext) {
50
+ return MIME_MAP[ext.toLowerCase()] ?? 'application/octet-stream';
51
+ }
52
+ function normalizeResponseContentType(contentType) {
53
+ if (!contentType) {
54
+ return undefined;
55
+ }
56
+ const normalized = contentType.split(';', 1)[0]?.trim().toLowerCase();
57
+ return normalized ? normalized : undefined;
58
+ }
59
+ function isPrivateHost(hostname) {
60
+ if (hostname === 'localhost' || hostname === '::1')
61
+ return true;
62
+ const ipVersion = isIP(hostname);
63
+ if (ipVersion === 4) {
64
+ const [a, b] = hostname.split('.').map(Number);
65
+ return (a === 0 ||
66
+ a === 10 ||
67
+ a === 127 ||
68
+ (a === 172 && b >= 16 && b <= 31) ||
69
+ (a === 192 && b === 168) ||
70
+ (a === 169 && b === 254));
71
+ }
72
+ if (ipVersion === 6) {
73
+ const normalized = hostname.toLowerCase();
74
+ return normalized.startsWith('fc') || normalized.startsWith('fd') || normalized.startsWith('fe80:');
75
+ }
76
+ return false;
77
+ }
78
+ function normalizeDownloadUrl(downloadUrl, webhookUrl) {
79
+ try {
80
+ const sourceUrl = new URL(downloadUrl);
81
+ if (!isPrivateHost(sourceUrl.hostname)) {
82
+ return downloadUrl;
83
+ }
84
+ const webhook = new URL(webhookUrl);
85
+ sourceUrl.protocol = webhook.protocol;
86
+ sourceUrl.host = webhook.host;
87
+ return sourceUrl.toString();
88
+ }
89
+ catch {
90
+ return downloadUrl;
91
+ }
92
+ }
93
+ function replaceDownloadUrlOrigin(downloadUrl, webhookUrl) {
94
+ try {
95
+ const sourceUrl = new URL(downloadUrl);
96
+ const webhook = new URL(webhookUrl);
97
+ if (sourceUrl.protocol === webhook.protocol && sourceUrl.host === webhook.host) {
98
+ return null;
99
+ }
100
+ sourceUrl.protocol = webhook.protocol;
101
+ sourceUrl.host = webhook.host;
102
+ return sourceUrl.toString();
103
+ }
104
+ catch {
105
+ return null;
106
+ }
107
+ }
108
+ export { resolveManagedMediaDir } from './state-paths.js';
109
+ /** Maximum file size for download/upload (100 MB). */
110
+ const MAX_FILE_SIZE = 100 * 1024 * 1024;
111
+ /** Timeout for media download requests (30 seconds). */
112
+ const DOWNLOAD_TIMEOUT_MS = 30_000;
113
+ const EMPTY_BUFFER = Buffer.alloc(0);
114
+ class MaxFileSizeExceededError extends Error {
115
+ size;
116
+ maxSize;
117
+ constructor(size, maxSize) {
118
+ super(`File size ${size} exceeds limit ${maxSize}`);
119
+ this.name = 'MaxFileSizeExceededError';
120
+ this.size = size;
121
+ this.maxSize = maxSize;
122
+ }
123
+ }
124
+ export class MediaService {
125
+ api;
126
+ logger;
127
+ dirReady = false;
128
+ constructor(api, logger) {
129
+ this.api = api;
130
+ this.logger = logger ?? defaultLogger;
131
+ }
132
+ async ensureDir() {
133
+ if (this.dirReady)
134
+ return;
135
+ await mkdir(resolveManagedMediaDir(), { recursive: true });
136
+ this.dirReady = true;
137
+ }
138
+ buildManagedMediaPath(fileName, fallbackName = 'file') {
139
+ const safeFileName = basename(fileName).trim() || fallbackName;
140
+ const savePath = join(resolveManagedMediaDir(), `${randomUUID()}_${safeFileName}`);
141
+ return {
142
+ savePath,
143
+ tempPath: `${savePath}.tmp`,
144
+ safeFileName,
145
+ };
146
+ }
147
+ async streamResponseToFile(response, tempPath) {
148
+ const contentLength = Number(response.headers.get('content-length') ?? 0);
149
+ if (contentLength > MAX_FILE_SIZE) {
150
+ throw new MaxFileSizeExceededError(contentLength, MAX_FILE_SIZE);
151
+ }
152
+ if (!response.body) {
153
+ await writeFile(tempPath, EMPTY_BUFFER);
154
+ return 0;
155
+ }
156
+ let totalBytes = 0;
157
+ const sizeGuard = new Transform({
158
+ transform(chunk, _encoding, callback) {
159
+ const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
160
+ totalBytes += buffer.length;
161
+ if (totalBytes > MAX_FILE_SIZE) {
162
+ callback(new MaxFileSizeExceededError(totalBytes, MAX_FILE_SIZE));
163
+ return;
164
+ }
165
+ callback(null, buffer);
166
+ },
167
+ });
168
+ await pipeline(Readable.fromWeb(response.body), sizeGuard, createWriteStream(tempPath));
169
+ return totalBytes;
170
+ }
171
+ async encodeFileToBase64(localPath) {
172
+ const stream = createReadStream(localPath);
173
+ let encoded = '';
174
+ let carry = EMPTY_BUFFER;
175
+ for await (const chunk of stream) {
176
+ const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
177
+ const source = carry.length > 0 ? Buffer.concat([carry, buffer]) : buffer;
178
+ const remainder = source.length % 3;
179
+ const readyLength = remainder === 0 ? source.length : source.length - remainder;
180
+ if (readyLength > 0) {
181
+ encoded += source.subarray(0, readyLength).toString('base64');
182
+ }
183
+ carry = remainder === 0 ? EMPTY_BUFFER : source.subarray(readyLength);
184
+ }
185
+ if (carry.length > 0) {
186
+ encoded += carry.toString('base64');
187
+ }
188
+ return encoded;
189
+ }
190
+ async resolveManagedUploadPath(localPath) {
191
+ await this.ensureDir();
192
+ try {
193
+ const [mediaDir, filePath] = await Promise.all([
194
+ realpath(resolveManagedMediaDir()),
195
+ realpath(localPath),
196
+ ]);
197
+ const rel = relative(mediaDir, filePath);
198
+ return !rel.startsWith('..') && !rel.startsWith(sep) ? filePath : null;
199
+ }
200
+ catch {
201
+ return null;
202
+ }
203
+ }
204
+ async fetchDownloadResponse(params) {
205
+ try {
206
+ return await fetch(params.url, {
207
+ signal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS),
208
+ });
209
+ }
210
+ catch (err) {
211
+ this.logger.warn('Bitrix file fetch failed', {
212
+ fileId: params.fileId,
213
+ url: maskUrlForLog(params.url),
214
+ error: serializeError(err),
215
+ });
216
+ throw err;
217
+ }
218
+ }
219
+ /**
220
+ * Download a file from B24 using imbot.v2.File.download.
221
+ * Single-step: get download URL, then fetch the file.
222
+ */
223
+ async downloadMedia(params) {
224
+ const { fileId, fileName, extension, webhookUrl, bot, dialogId } = params;
225
+ try {
226
+ const numericFileId = Number(fileId);
227
+ if (!Number.isFinite(numericFileId) || numericFileId <= 0) {
228
+ this.logger.warn('Invalid fileId, skipping download', { fileId });
229
+ return null;
230
+ }
231
+ // Get download URL via imbot.v2.File.download
232
+ const downloadUrl = await this.api.getFileDownloadUrl(webhookUrl, bot, dialogId, numericFileId);
233
+ if (!downloadUrl) {
234
+ this.logger.warn('No downloadUrl for file', { fileId });
235
+ return null;
236
+ }
237
+ const safeDownloadUrl = normalizeDownloadUrl(downloadUrl, webhookUrl);
238
+ if (safeDownloadUrl !== downloadUrl) {
239
+ this.logger.warn('Rewriting private Bitrix file URL to webhook origin', {
240
+ fromHost: new URL(downloadUrl).host,
241
+ toHost: new URL(safeDownloadUrl).host,
242
+ fileId,
243
+ });
244
+ }
245
+ const webhookFallbackUrl = replaceDownloadUrlOrigin(downloadUrl, webhookUrl);
246
+ const canRetryWithWebhookOrigin = Boolean(webhookFallbackUrl && webhookFallbackUrl !== safeDownloadUrl);
247
+ // Download the file (with timeout)
248
+ let response;
249
+ try {
250
+ response = await this.fetchDownloadResponse({
251
+ url: safeDownloadUrl,
252
+ fileId,
253
+ });
254
+ }
255
+ catch (err) {
256
+ if (!canRetryWithWebhookOrigin || !webhookFallbackUrl) {
257
+ throw err;
258
+ }
259
+ this.logger.warn('Retrying Bitrix file download via webhook origin after fetch failure', {
260
+ fileId,
261
+ fromUrl: maskUrlForLog(safeDownloadUrl),
262
+ toUrl: maskUrlForLog(webhookFallbackUrl),
263
+ });
264
+ response = await this.fetchDownloadResponse({
265
+ url: webhookFallbackUrl,
266
+ fileId,
267
+ });
268
+ }
269
+ if (!response.ok) {
270
+ if (canRetryWithWebhookOrigin && webhookFallbackUrl) {
271
+ this.logger.warn('Retrying Bitrix file download via webhook origin after HTTP failure', {
272
+ fileId,
273
+ status: response.status,
274
+ fromUrl: maskUrlForLog(safeDownloadUrl),
275
+ toUrl: maskUrlForLog(webhookFallbackUrl),
276
+ });
277
+ response = await this.fetchDownloadResponse({
278
+ url: webhookFallbackUrl,
279
+ fileId,
280
+ });
281
+ }
282
+ if (!response.ok) {
283
+ this.logger.warn('Failed to download file', {
284
+ fileId,
285
+ status: response.status,
286
+ });
287
+ return null;
288
+ }
289
+ }
290
+ await this.ensureDir();
291
+ const { savePath, tempPath } = this.buildManagedMediaPath(fileName, `file_${fileId}`);
292
+ let size = 0;
293
+ try {
294
+ size = await this.streamResponseToFile(response, tempPath);
295
+ await rename(tempPath, savePath);
296
+ }
297
+ catch (err) {
298
+ await unlink(tempPath).catch(() => undefined);
299
+ if (err instanceof MaxFileSizeExceededError) {
300
+ this.logger.warn('Downloaded file exceeds size limit', {
301
+ fileId,
302
+ size: err.size,
303
+ maxSize: err.maxSize,
304
+ });
305
+ return null;
306
+ }
307
+ throw err;
308
+ }
309
+ const responseContentType = normalizeResponseContentType(response.headers.get('content-type'));
310
+ const contentType = responseContentType && responseContentType !== 'application/octet-stream'
311
+ ? responseContentType
312
+ : mimeFromExtension(extension);
313
+ this.logger.debug('Downloaded media', {
314
+ fileId,
315
+ fileName,
316
+ contentType,
317
+ size,
318
+ path: savePath,
319
+ });
320
+ return { path: savePath, contentType, name: fileName };
321
+ }
322
+ catch (err) {
323
+ this.logger.error('Error downloading media', {
324
+ fileId,
325
+ error: serializeError(err),
326
+ });
327
+ return null;
328
+ }
329
+ }
330
+ /**
331
+ * Upload a local file to a B24 chat using imbot.v2.File.upload.
332
+ * Single call replaces the old 3-step process (folder.get → upload → commit).
333
+ */
334
+ async uploadMediaToChat(params) {
335
+ const { localPath, fileName, webhookUrl, bot, dialogId, message } = params;
336
+ try {
337
+ const managedPath = await this.resolveManagedUploadPath(localPath);
338
+ if (!managedPath) {
339
+ this.logger.warn('Refusing outbound media upload from unmanaged local path', {
340
+ fileName,
341
+ path: localPath,
342
+ });
343
+ return { ok: false };
344
+ }
345
+ // Check file size before reading
346
+ const fileStat = await stat(managedPath);
347
+ if (fileStat.size > MAX_FILE_SIZE) {
348
+ this.logger.warn('File too large to upload', {
349
+ fileName,
350
+ size: fileStat.size,
351
+ maxSize: MAX_FILE_SIZE,
352
+ });
353
+ return { ok: false };
354
+ }
355
+ // Encode incrementally to avoid holding both the raw file and base64 string in memory.
356
+ const base64Content = await this.encodeFileToBase64(managedPath);
357
+ const result = await this.api.uploadFile(webhookUrl, bot, dialogId, {
358
+ name: basename(fileName).trim() || basename(managedPath),
359
+ content: base64Content,
360
+ message,
361
+ });
362
+ this.logger.debug('Uploaded media to chat', {
363
+ fileName,
364
+ dialogId,
365
+ messageId: result.messageId,
366
+ });
367
+ return { ok: true, messageId: result.messageId };
368
+ }
369
+ catch (err) {
370
+ this.logger.error('Error uploading media to chat', {
371
+ fileName,
372
+ dialogId,
373
+ error: serializeError(err),
374
+ });
375
+ return { ok: false };
376
+ }
377
+ }
378
+ async cleanupDownloadedMedia(paths) {
379
+ const uniquePaths = [...new Set(paths)];
380
+ for (const filePath of uniquePaths) {
381
+ if (!(await this.isManagedMediaPath(filePath))) {
382
+ this.logger.debug('Skipping cleanup for unmanaged media path', { path: filePath });
383
+ continue;
384
+ }
385
+ try {
386
+ await unlink(filePath);
387
+ }
388
+ catch (error) {
389
+ const errorCode = error instanceof Error && 'code' in error
390
+ ? String(error.code)
391
+ : undefined;
392
+ if (errorCode === 'ENOENT') {
393
+ continue;
394
+ }
395
+ this.logger.warn('Failed to cleanup downloaded media', {
396
+ path: filePath,
397
+ error: serializeError(error),
398
+ });
399
+ }
400
+ }
401
+ }
402
+ async isManagedMediaPath(filePath) {
403
+ try {
404
+ const resolvedPath = await realpath(filePath);
405
+ // Resolve the media dir too in case of symlinks (e.g. /tmp → /private/tmp on macOS)
406
+ let mediaDir;
407
+ try {
408
+ mediaDir = await realpath(resolveManagedMediaDir());
409
+ }
410
+ catch {
411
+ mediaDir = resolveManagedMediaDir();
412
+ }
413
+ // relative() returns '..' prefix if path escapes the base directory
414
+ const rel = relative(mediaDir, resolvedPath);
415
+ return !rel.startsWith('..') && !rel.startsWith(sep);
416
+ }
417
+ catch {
418
+ // File doesn't exist or is inaccessible — treat as unmanaged
419
+ return false;
420
+ }
421
+ }
422
+ }
423
+ //# sourceMappingURL=media-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media-service.js","sourceRoot":"","sources":["../../src/media-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import type { B24Keyboard } from './types.js';
2
+ /**
3
+ * Convert Markdown (CommonMark + GFM subset) to Bitrix24 BB-code chat format.
4
+ *
5
+ * 4-phase pipeline:
6
+ * 1. Protect literals — escape sequences, fenced code, inline code → placeholders
7
+ * 2. Block rules — indented code, setext headings, horizontal rules, ATX headings,
8
+ * blockquotes, unordered lists
9
+ * 3. Inline rules — images, bold+italic, bold, italic, strikethrough, HTML inline
10
+ * formatting, links, autolinks
11
+ * 4. Restore — placeholders → BB-code equivalents
12
+ */
13
+ export declare function markdownToBbCode(md: string): string;
14
+ /**
15
+ * Split a long message into chunks respecting B24's 20000 char limit.
16
+ * Tries to split at line boundaries.
17
+ */
18
+ export declare function splitMessage(text: string, maxLen?: number): string[];
19
+ /**
20
+ * Build a KEYBOARD array for imbot.v2.Chat.Message.send.
21
+ *
22
+ * @param rows - Array of button rows. Each row is an array of buttons.
23
+ */
24
+ export declare function buildKeyboard(rows: Array<Array<{
25
+ text: string;
26
+ command?: string;
27
+ commandParams?: string;
28
+ link?: string;
29
+ bgColor?: string;
30
+ textColor?: string;
31
+ fullWidth?: boolean;
32
+ disableAfterClick?: boolean;
33
+ }>>): B24Keyboard;
34
+ //# sourceMappingURL=message-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-utils.d.ts","sourceRoot":"","sources":["../../src/message-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,WAAW,EAAE,MAAM,YAAY,CAAC;AAW9D;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CA4KnD;AAaD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,GAAE,MAAc,GAAG,MAAM,EAAE,CAwB3E;AAkND;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,KAAK,CACT,KAAK,CAAC;IACJ,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B,CAAC,CACH,GACA,WAAW,CAsBb"}