teledzik 1.0.6 → 1.0.7

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.
@@ -1,12 +1,7 @@
1
1
  "use strict";
2
- /**
3
- * Converts Rich HTML strings (containing unsupported Telegram HTML tags like
4
- * <table>, <ul>, <ol>, <li>, <details>, <h1>-<h6>, <aside>, <p>, <hr>, etc.)
5
- * into standard Telegram HTML compatible with parse_mode: 'HTML' (editMessageText/sendMessage).
6
- */
7
2
  Object.defineProperty(exports, "__esModule", { value: true });
8
3
  exports.sanitizeRichHtml = void 0;
9
- function convertTableToText(tableHtml) {
4
+ function formatTableToCard(tableHtml) {
10
5
  const rows = [];
11
6
  const rowMatches = tableHtml.match(/<tr[^>]*>([\s\S]*?)<\/tr>/gi) || [];
12
7
  for (const row of rowMatches) {
@@ -21,45 +16,37 @@ function convertTableToText(tableHtml) {
21
16
  }
22
17
  if (rows.length === 0)
23
18
  return '';
24
- // Calculate column widths
25
- const colWidths = [];
26
- rows.forEach((r) => {
27
- r.forEach((c, idx) => {
28
- const textLen = c.replace(/<[^>]+>/g, '').length;
29
- colWidths[idx] = Math.max(colWidths[idx] || 0, textLen);
19
+ // Header vs Row handling (Format sebagai Kartu Elegan)
20
+ const isKeyValue = rows.length > 1 && rows.every((r) => r.length === 2);
21
+ let cardText = '';
22
+ if (isKeyValue) {
23
+ const lines = rows.slice(1).map((r) => `• <b>${r[0]}:</b> ${r[1]}`);
24
+ cardText = `<blockquote>\n${lines.join('\n')}\n</blockquote>\n\n`;
25
+ }
26
+ else {
27
+ const lines = rows.map((r, idx) => {
28
+ if (idx === 0)
29
+ return `<b>${r.join(' │ ')}</b>`;
30
+ return `${r.join(' │ ')}`;
30
31
  });
31
- });
32
- // Format table rows
33
- const formattedRows = rows.map((r, rowIdx) => {
34
- const line = r
35
- .map((c, colIdx) => {
36
- const textLen = c.replace(/<[^>]+>/g, '').length;
37
- const pad = ' '.repeat(Math.max(0, (colWidths[colIdx] || 0) - textLen));
38
- return `${c}${pad}`;
39
- })
40
- .join(' │ ');
41
- if (rowIdx === 0 && rows.length > 1) {
42
- const sep = colWidths.map((w) => '─'.repeat(w)).join('─┼─');
43
- return `${line}\n${sep}`;
44
- }
45
- return line;
46
- });
47
- return `<pre>\n${formattedRows.join('\n')}\n</pre>\n\n`;
32
+ cardText = `<blockquote>\n${lines.join('\n')}\n</blockquote>\n\n`;
33
+ }
34
+ return cardText;
48
35
  }
49
36
  function sanitizeRichHtml(html) {
50
37
  if (!html)
51
38
  return html;
52
39
  let result = html;
53
- // 1. Convert Tables: <table>...</table> -> <pre>formatted table</pre>
54
- result = result.replace(/<table[^>]*>([\s\S]*?)<\/table>/gi, (_, content) => convertTableToText(content));
55
- // 2. Convert Details / Expandable: <details><summary>Title</summary>Content</details>
40
+ // 1. Convert Tables to Clean Modern Cards
41
+ result = result.replace(/<table[^>]*>([\s\S]*?)<\/table>/gi, (_, content) => formatTableToCard(content));
42
+ // 2. Convert Details to Telegram Native Expandable Blockquotes
56
43
  result = result.replace(/<details[^>]*>\s*<summary[^>]*>(.*?)<\/summary>([\s\S]*?)<\/details>/gi, (_, title, body) => {
57
- return `<b>▶ ${title.trim()}</b>\n<blockquote>${body.trim()}</blockquote>\n\n`;
44
+ return `<blockquote expandable><b>▶ ${title.trim()}</b>\n${body.trim()}</blockquote>\n\n`;
58
45
  });
59
- // 3. Convert Headings
60
- result = result.replace(/<h1[^>]*>([\s\S]*?)<\/h1>/gi, (_, c) => `<b>${c.trim().toUpperCase()}</b>\n\n`);
46
+ // 3. Clean Headings
47
+ result = result.replace(/<h1[^>]*>([\s\S]*?)<\/h1>/gi, (_, c) => `<b>${c.trim()}</b>\n\n`);
61
48
  result = result.replace(/<h[2-6][^>]*>([\s\S]*?)<\/h[2-6]>/gi, (_, c) => `<b>${c.trim()}</b>\n\n`);
62
- // 4. Convert Task Lists & Unordered/Ordered Lists
49
+ // 4. Task Lists & Bullet Lists
63
50
  result = result.replace(/<ul[^>]*>([\s\S]*?)<\/ul>/gi, (_, listContent) => {
64
51
  return (listContent
65
52
  .replace(/<li[^>]*>\s*<input[^>]*type="checkbox"[^>]*checked[^>]*>\s*([\s\S]*?)<\/li>/gi, '☑ $1\n')
@@ -73,29 +60,24 @@ function sanitizeRichHtml(html) {
73
60
  .replace(/<li[^>]*>([\s\S]*?)<\/li>/gi, (_match, item) => `${index++}. ${item.trim()}\n`)
74
61
  .trim() + '\n\n');
75
62
  });
76
- // 5. Convert Pull Quotes / Asides
63
+ // 5. Clean Blockquotes & Dividers
77
64
  result = result.replace(/<aside[^>]*>([\s\S]*?)(?:<cite[^>]*>([\s\S]*?)<\/cite>)?<\/aside>/gi, (_, quote, cite) => {
78
65
  return `<blockquote>${quote.trim()}${cite ? `\n— <i>${cite.trim()}</i>` : ''}</blockquote>\n\n`;
79
66
  });
80
- // 6. Convert Special Bot API 10.1 tags
81
67
  result = result.replace(/<tg-thinking[^>]*>([\s\S]*?)<\/tg-thinking>/gi, (_, c) => `<blockquote>💭 <i>${c.trim()}</i></blockquote>\n\n`);
82
68
  result = result.replace(/<tg-math-block[^>]*>([\s\S]*?)<\/tg-math-block>/gi, (_, c) => `<pre><code>${c.trim()}</code></pre>\n\n`);
83
69
  result = result.replace(/<tg-reference[^>]*>([\s\S]*?)<\/tg-reference>/gi, (_, c) => `<i>${c.trim()}</i>`);
84
70
  result = result.replace(/<mark[^>]*>([\s\S]*?)<\/mark>/gi, (_, c) => `<b>[${c.trim()}]</b>`);
85
- // 7. Convert Figures & Captions
86
71
  result = result.replace(/<figure[^>]*>[\s\S]*?<figcaption[^>]*>([\s\S]*?)<\/figcaption><\/figure>/gi, (_, cap) => `\n<i>📷 ${cap.trim()}</i>\n`);
87
- // 8. Convert Paragraphs & Linebreaks
88
72
  result = result.replace(/<p[^>]*>([\s\S]*?)<\/p>/gi, (_, c) => `${c.trim()}\n\n`);
89
73
  result = result.replace(/<footer[^>]*>([\s\S]*?)<\/footer>/gi, (_, c) => `<i>${c.trim()}</i>\n`);
90
74
  result = result.replace(/<br\s*\/?>/gi, '\n');
91
- result = result.replace(/<hr\s*\/?>/gi, '──────────\n');
92
- // 9. Strip unsupported media & sub/sup tags but keep text
75
+ result = result.replace(/<hr\s*\/?>/gi, '\n');
76
+ // Strip unsupported tags
93
77
  result = result.replace(/<sub[^>]*>([\s\S]*?)<\/sub>/gi, '$1');
94
78
  result = result.replace(/<sup[^>]*>([\s\S]*?)<\/sup>/gi, '$1');
95
79
  result = result.replace(/<tg-(map|collage|slideshow)[^>]*>([\s\S]*?)<\/tg-\1>/gi, '$2');
96
80
  result = result.replace(/<(img|video|audio|tg-map)[^>]*\/?>/gi, '');
97
- // 10. Clean up extra newlines (> 2 consecutive newlines)
98
- result = result.replace(/\n{3,}/g, '\n\n');
99
- return result.trim();
81
+ return result.replace(/\n{3,}/g, '\n\n').trim();
100
82
  }
101
83
  exports.sanitizeRichHtml = sanitizeRichHtml;
package/lib/telegram.js CHANGED
@@ -1272,22 +1272,66 @@ class Telegram extends client_1.default {
1272
1272
  });
1273
1273
  }
1274
1274
  /**
1275
- * Edit a rich message in-place while preserving 100% Native Rich UI layout (tables, headings, cards).
1276
- * @see https://core.telegram.org/bots/api#editrichmessage
1277
- */
1278
- async editRichMessage(chatId, messageId, richMessage, extra) {
1275
+ * Universal in-place message editor with Modern Rich UI formatting.
1276
+ */
1277
+ async editRichMessage(chatId, messageId, content, extra) {
1278
+ let htmlText = '';
1279
+ let replyMarkup = extra?.reply_markup;
1280
+ if (typeof content?.build === 'function') {
1281
+ const built = content.build();
1282
+ if (typeof built === 'object' && built !== null) {
1283
+ htmlText = built.html || built.text || built.caption || '';
1284
+ if (built.reply_markup) {
1285
+ replyMarkup = replyMarkup || built.reply_markup;
1286
+ }
1287
+ }
1288
+ else {
1289
+ htmlText = String(built || '');
1290
+ }
1291
+ }
1292
+ else if (typeof content === 'object' && content !== null) {
1293
+ htmlText = content.html || content.text || content.caption || '';
1294
+ if (content.reply_markup) {
1295
+ replyMarkup = replyMarkup || content.reply_markup;
1296
+ }
1297
+ }
1298
+ else if (typeof content === 'string') {
1299
+ htmlText = content;
1300
+ }
1301
+ // Format ke Telegram Modern HTML
1302
+ htmlText = (0, rich_sanitizer_1.sanitizeRichHtml)(htmlText);
1279
1303
  const payload = {
1280
1304
  chat_id: chatId,
1281
1305
  message_id: Number(messageId),
1282
- rich_message: typeof richMessage?.build === 'function' ? richMessage.build() : richMessage,
1306
+ text: htmlText,
1307
+ parse_mode: 'HTML',
1283
1308
  ...extra,
1284
1309
  };
1310
+ if (replyMarkup)
1311
+ payload.reply_markup = replyMarkup;
1285
1312
  try {
1286
- return await this.callApi('editRichMessage', payload);
1313
+ return await this.callApi('editMessageText', payload);
1287
1314
  }
1288
1315
  catch (err) {
1289
1316
  const desc = String(err?.description || err?.message || '');
1290
- // Silent ignore jika konten pesan tidak mengalami perubahan
1317
+ // Fallback jika pesan berupa Media (Foto/Video)
1318
+ if (desc.includes('no text in the message') || desc.includes('message to edit not found')) {
1319
+ try {
1320
+ return await this.callApi('editMessageCaption', {
1321
+ chat_id: chatId,
1322
+ message_id: Number(messageId),
1323
+ caption: htmlText,
1324
+ parse_mode: 'HTML',
1325
+ reply_markup: replyMarkup,
1326
+ ...extra,
1327
+ });
1328
+ }
1329
+ catch (captionErr) {
1330
+ if (String(captionErr?.description).includes('message is not modified'))
1331
+ return false;
1332
+ throw captionErr;
1333
+ }
1334
+ }
1291
1335
  if (desc.includes('message is not modified')) {
1292
1336
  return false;
1293
1337
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "teledzik",
3
- "version": "1.0.6",
3
+ "version": "1.0.7",
4
4
  "description": "Modern Telegram Bot Framework",
5
5
  "keywords": [
6
6
  "telekaf",
@@ -1,13 +1,6 @@
1
- /**
2
- * Converts Rich HTML strings (containing unsupported Telegram HTML tags like
3
- * <table>, <ul>, <ol>, <li>, <details>, <h1>-<h6>, <aside>, <p>, <hr>, etc.)
4
- * into standard Telegram HTML compatible with parse_mode: 'HTML' (editMessageText/sendMessage).
5
- */
6
-
7
- function convertTableToText(tableHtml: string): string {
1
+ function formatTableToCard(tableHtml: string): string {
8
2
  const rows: string[][] = []
9
3
  const rowMatches = tableHtml.match(/<tr[^>]*>([\s\S]*?)<\/tr>/gi) || []
10
-
11
4
  for (const row of rowMatches) {
12
5
  const cells: string[] = []
13
6
  const cellMatches = row.match(/<(th|td)[^>]*>([\s\S]*?)<\/\1>/gi) || []
@@ -17,56 +10,41 @@ function convertTableToText(tableHtml: string): string {
17
10
  }
18
11
  if (cells.length > 0) rows.push(cells)
19
12
  }
20
-
21
13
  if (rows.length === 0) return ''
22
14
 
23
- // Calculate column widths
24
- const colWidths: number[] = []
25
- rows.forEach((r) => {
26
- r.forEach((c, idx) => {
27
- const textLen = c.replace(/<[^>]+>/g, '').length
28
- colWidths[idx] = Math.max(colWidths[idx] || 0, textLen)
15
+ // Header vs Row handling (Format sebagai Kartu Elegan)
16
+ const isKeyValue = rows.length > 1 && rows.every((r) => r.length === 2)
17
+ let cardText = ''
18
+ if (isKeyValue) {
19
+ const lines = rows.slice(1).map((r) => `• <b>${r[0]}:</b> ${r[1]}`)
20
+ cardText = `<blockquote>\n${lines.join('\n')}\n</blockquote>\n\n`
21
+ } else {
22
+ const lines = rows.map((r, idx) => {
23
+ if (idx === 0) return `<b>${r.join(' │ ')}</b>`
24
+ return `${r.join(' │ ')}`
29
25
  })
30
- })
31
-
32
- // Format table rows
33
- const formattedRows = rows.map((r, rowIdx) => {
34
- const line = r
35
- .map((c, colIdx) => {
36
- const textLen = c.replace(/<[^>]+>/g, '').length
37
- const pad = ' '.repeat(Math.max(0, (colWidths[colIdx] || 0) - textLen))
38
- return `${c}${pad}`
39
- })
40
- .join(' │ ')
41
-
42
- if (rowIdx === 0 && rows.length > 1) {
43
- const sep = colWidths.map((w) => '─'.repeat(w)).join('─┼─')
44
- return `${line}\n${sep}`
45
- }
46
- return line
47
- })
48
-
49
- return `<pre>\n${formattedRows.join('\n')}\n</pre>\n\n`
26
+ cardText = `<blockquote>\n${lines.join('\n')}\n</blockquote>\n\n`
27
+ }
28
+ return cardText
50
29
  }
51
30
 
52
31
  export function sanitizeRichHtml(html: string): string {
53
32
  if (!html) return html
54
-
55
33
  let result = html
56
34
 
57
- // 1. Convert Tables: <table>...</table> -> <pre>formatted table</pre>
58
- result = result.replace(/<table[^>]*>([\s\S]*?)<\/table>/gi, (_, content) => convertTableToText(content))
35
+ // 1. Convert Tables to Clean Modern Cards
36
+ result = result.replace(/<table[^>]*>([\s\S]*?)<\/table>/gi, (_, content) => formatTableToCard(content))
59
37
 
60
- // 2. Convert Details / Expandable: <details><summary>Title</summary>Content</details>
38
+ // 2. Convert Details to Telegram Native Expandable Blockquotes
61
39
  result = result.replace(/<details[^>]*>\s*<summary[^>]*>(.*?)<\/summary>([\s\S]*?)<\/details>/gi, (_, title, body) => {
62
- return `<b>▶ ${title.trim()}</b>\n<blockquote>${body.trim()}</blockquote>\n\n`
40
+ return `<blockquote expandable><b>▶ ${title.trim()}</b>\n${body.trim()}</blockquote>\n\n`
63
41
  })
64
42
 
65
- // 3. Convert Headings
66
- result = result.replace(/<h1[^>]*>([\s\S]*?)<\/h1>/gi, (_, c) => `<b>${c.trim().toUpperCase()}</b>\n\n`)
43
+ // 3. Clean Headings
44
+ result = result.replace(/<h1[^>]*>([\s\S]*?)<\/h1>/gi, (_, c) => `<b>${c.trim()}</b>\n\n`)
67
45
  result = result.replace(/<h[2-6][^>]*>([\s\S]*?)<\/h[2-6]>/gi, (_, c) => `<b>${c.trim()}</b>\n\n`)
68
46
 
69
- // 4. Convert Task Lists & Unordered/Ordered Lists
47
+ // 4. Task Lists & Bullet Lists
70
48
  result = result.replace(/<ul[^>]*>([\s\S]*?)<\/ul>/gi, (_, listContent) => {
71
49
  return (
72
50
  listContent
@@ -86,34 +64,28 @@ export function sanitizeRichHtml(html: string): string {
86
64
  )
87
65
  })
88
66
 
89
- // 5. Convert Pull Quotes / Asides
67
+ // 5. Clean Blockquotes & Dividers
90
68
  result = result.replace(/<aside[^>]*>([\s\S]*?)(?:<cite[^>]*>([\s\S]*?)<\/cite>)?<\/aside>/gi, (_, quote, cite) => {
91
69
  return `<blockquote>${quote.trim()}${cite ? `\n— <i>${cite.trim()}</i>` : ''}</blockquote>\n\n`
92
70
  })
93
71
 
94
- // 6. Convert Special Bot API 10.1 tags
95
72
  result = result.replace(/<tg-thinking[^>]*>([\s\S]*?)<\/tg-thinking>/gi, (_, c) => `<blockquote>💭 <i>${c.trim()}</i></blockquote>\n\n`)
96
73
  result = result.replace(/<tg-math-block[^>]*>([\s\S]*?)<\/tg-math-block>/gi, (_, c) => `<pre><code>${c.trim()}</code></pre>\n\n`)
97
74
  result = result.replace(/<tg-reference[^>]*>([\s\S]*?)<\/tg-reference>/gi, (_, c) => `<i>${c.trim()}</i>`)
98
75
  result = result.replace(/<mark[^>]*>([\s\S]*?)<\/mark>/gi, (_, c) => `<b>[${c.trim()}]</b>`)
99
76
 
100
- // 7. Convert Figures & Captions
101
77
  result = result.replace(/<figure[^>]*>[\s\S]*?<figcaption[^>]*>([\s\S]*?)<\/figcaption><\/figure>/gi, (_, cap) => `\n<i>📷 ${cap.trim()}</i>\n`)
102
78
 
103
- // 8. Convert Paragraphs & Linebreaks
104
79
  result = result.replace(/<p[^>]*>([\s\S]*?)<\/p>/gi, (_, c) => `${c.trim()}\n\n`)
105
80
  result = result.replace(/<footer[^>]*>([\s\S]*?)<\/footer>/gi, (_, c) => `<i>${c.trim()}</i>\n`)
106
81
  result = result.replace(/<br\s*\/?>/gi, '\n')
107
- result = result.replace(/<hr\s*\/?>/gi, '──────────\n')
82
+ result = result.replace(/<hr\s*\/?>/gi, '\n')
108
83
 
109
- // 9. Strip unsupported media & sub/sup tags but keep text
84
+ // Strip unsupported tags
110
85
  result = result.replace(/<sub[^>]*>([\s\S]*?)<\/sub>/gi, '$1')
111
86
  result = result.replace(/<sup[^>]*>([\s\S]*?)<\/sup>/gi, '$1')
112
87
  result = result.replace(/<tg-(map|collage|slideshow)[^>]*>([\s\S]*?)<\/tg-\1>/gi, '$2')
113
88
  result = result.replace(/<(img|video|audio|tg-map)[^>]*\/?>/gi, '')
114
89
 
115
- // 10. Clean up extra newlines (> 2 consecutive newlines)
116
- result = result.replace(/\n{3,}/g, '\n\n')
117
-
118
- return result.trim()
90
+ return result.replace(/\n{3,}/g, '\n\n').trim()
119
91
  }
package/src/telegram.ts CHANGED
@@ -1680,26 +1680,69 @@ export class Telegram extends ApiClient {
1680
1680
  }
1681
1681
 
1682
1682
  /**
1683
- * Edit a rich message in-place while preserving 100% Native Rich UI layout (tables, headings, cards).
1684
- * @see https://core.telegram.org/bots/api#editrichmessage
1683
+ * Universal in-place message editor with Modern Rich UI formatting.
1685
1684
  */
1686
1685
  async editRichMessage(
1687
1686
  chatId: number | string,
1688
1687
  messageId: number | string,
1689
- richMessage: any,
1688
+ content: any,
1690
1689
  extra?: any
1691
1690
  ): Promise<any> {
1691
+ let htmlText = ''
1692
+ let replyMarkup = extra?.reply_markup
1693
+
1694
+ if (typeof content?.build === 'function') {
1695
+ const built = content.build()
1696
+ if (typeof built === 'object' && built !== null) {
1697
+ htmlText = built.html || built.text || built.caption || ''
1698
+ if (built.reply_markup) {
1699
+ replyMarkup = replyMarkup || built.reply_markup
1700
+ }
1701
+ } else {
1702
+ htmlText = String(built || '')
1703
+ }
1704
+ } else if (typeof content === 'object' && content !== null) {
1705
+ htmlText = content.html || content.text || content.caption || ''
1706
+ if (content.reply_markup) {
1707
+ replyMarkup = replyMarkup || content.reply_markup
1708
+ }
1709
+ } else if (typeof content === 'string') {
1710
+ htmlText = content
1711
+ }
1712
+
1713
+ // Format ke Telegram Modern HTML
1714
+ htmlText = sanitizeRichHtml(htmlText)
1715
+
1692
1716
  const payload: Record<string, any> = {
1693
1717
  chat_id: chatId,
1694
1718
  message_id: Number(messageId),
1695
- rich_message: typeof richMessage?.build === 'function' ? richMessage.build() : richMessage,
1719
+ text: htmlText,
1720
+ parse_mode: 'HTML',
1696
1721
  ...extra,
1697
1722
  }
1723
+
1724
+ if (replyMarkup) payload.reply_markup = replyMarkup
1725
+
1698
1726
  try {
1699
- return await this.callApi('editRichMessage' as never, payload as never)
1727
+ return await this.callApi('editMessageText' as never, payload as never)
1700
1728
  } catch (err: any) {
1701
1729
  const desc = String(err?.description || err?.message || '')
1702
- // Silent ignore jika konten pesan tidak mengalami perubahan
1730
+ // Fallback jika pesan berupa Media (Foto/Video)
1731
+ if (desc.includes('no text in the message') || desc.includes('message to edit not found')) {
1732
+ try {
1733
+ return await this.callApi('editMessageCaption' as never, {
1734
+ chat_id: chatId,
1735
+ message_id: Number(messageId),
1736
+ caption: htmlText,
1737
+ parse_mode: 'HTML',
1738
+ reply_markup: replyMarkup,
1739
+ ...extra,
1740
+ } as never)
1741
+ } catch (captionErr: any) {
1742
+ if (String(captionErr?.description).includes('message is not modified')) return false
1743
+ throw captionErr
1744
+ }
1745
+ }
1703
1746
  if (desc.includes('message is not modified')) {
1704
1747
  return false
1705
1748
  }
@@ -1,6 +1 @@
1
- /**
2
- * Converts Rich HTML strings (containing unsupported Telegram HTML tags like
3
- * <table>, <ul>, <ol>, <li>, <details>, <h1>-<h6>, <aside>, <p>, <hr>, etc.)
4
- * into standard Telegram HTML compatible with parse_mode: 'HTML' (editMessageText/sendMessage).
5
- */
6
1
  export declare function sanitizeRichHtml(html: string): string;
@@ -690,9 +690,8 @@ export declare class Telegram extends ApiClient {
690
690
  */
691
691
  sendRichMessageDraft(chatId: number, draftId: number, richMessage: tg.InputRichMessage, extra?: tt.ExtraSendRichMessageDraft): Promise<never>;
692
692
  /**
693
- * Edit a rich message in-place while preserving 100% Native Rich UI layout (tables, headings, cards).
694
- * @see https://core.telegram.org/bots/api#editrichmessage
693
+ * Universal in-place message editor with Modern Rich UI formatting.
695
694
  */
696
- editRichMessage(chatId: number | string, messageId: number | string, richMessage: any, extra?: any): Promise<any>;
695
+ editRichMessage(chatId: number | string, messageId: number | string, content: any, extra?: any): Promise<any>;
697
696
  }
698
697
  export default Telegram;