soumyadeepdas/TbhRichBotPublic · Community Store Listing

Rich Message Demo [TBH]

ProfileTelegram
17 commands0 envUpdated 5d agoCreated Jul 16, 2026
Back to folder

commands/_inline_query.js

javascript · 282 lines · click line # to share

1/**#command2name: /inline_query3answer: 4keyboard: 5parse_mode: 6aliases: 7allow_only_group: false8need_reply: false9is_web: 010#command**/11 12/* Command: /inlineQuery */13 14if (!update.inline_query) return;15 16let query = (update.inline_query.query || "").trim();17let inlineId = update.inline_query.id;18 19// =======================20// REMOVE BOT USERNAME FROM TEXT21// =======================22let botUsername = ""23 24if (typeof bot !== 'undefined' && bot.username) {25  botUsername = bot.username26} else if (update.bot && update.bot.username) {27  botUsername = update.bot.username28} else {29  botUsername = "pyralbot"30}31 32let botMention = "@" + botUsername33 34if (query.startsWith(botMention)) {35  query = query.substring(botMention.length).trim()36} else {37  let regex = new RegExp('^@' + botUsername + '\\s*', 'i')38  query = query.replace(regex, '').trim()39}40 41// =======================42// MARKDOWN TO HTML CONVERTER43// =======================44function markdownToHtml(text) {45  let html = text46 47  // HEADINGS48  html = html.replace(/^###### (.*$)/gm, '<h6>$1</h6>')49  html = html.replace(/^##### (.*$)/gm, '<h5>$1</h5>')50  html = html.replace(/^#### (.*$)/gm, '<h4>$1</h4>')51  html = html.replace(/^### (.*$)/gm, '<h3>$1</h3>')52  html = html.replace(/^## (.*$)/gm, '<h2>$1</h2>')53  html = html.replace(/^# (.*$)/gm, '<h1>$1</h1>')54 55  // TEXT FORMATTING56  html = html.replace(/\*\*(.*?)\*\*/g, '<b>$1</b>')57  html = html.replace(/__(.*?)__/g, '<b>$1</b>')58  html = html.replace(/\*(.*?)\*/g, '<i>$1</i>')59  html = html.replace(/_(.*?)_/g, '<i>$1</i>')60  html = html.replace(/~~(.*?)~~/g, '<s>$1</s>')61  html = html.replace(/==(.*?)==/g, '<mark>$1</mark>')62  html = html.replace(/\|\|(.*?)\|\|/g, '<tg-spoiler>$1</tg-spoiler>')63  html = html.replace(/`(.*?)`/g, '<code>$1</code>')64 65  // CODE BLOCKS66  html = html.replace(/```(\w+)?\n([\s\S]*?)```/g, function(match, lang, code) {67    if (lang) {68      return `<pre><code class="language-${lang}">${code.trim()}</code></pre>`69    }70    return `<pre><code>${code.trim()}</code></pre>`71  })72 73  // LINKS & IMAGES74  html = html.replace(/!\[(.*?)\]\((.*?)\)/g, '<img src="$2" alt="$1"/>')75  html = html.replace(/\[(.*?)\]\((.*?)\)/g, '<a href="$2">$1</a>')76 77  // BLOCKQUOTES78  html = html.replace(/^> (.*$)/gm, '<blockquote>$1</blockquote>')79  html = html.replace(/<\/blockquote>\n<blockquote>/g, '<br>')80  81  let blockquoteRegex = /(<blockquote>.*?<\/blockquote>)/gs82  let matches = html.match(blockquoteRegex)83  if (matches) {84    for (let match of matches) {85      let content = match.replace(/<blockquote>/g, '').replace(/<\/blockquote>/g, '')86      html = html.replace(match, `<blockquote>${content}</blockquote>`)87    }88  }89 90  // LISTS91  html = html.replace(/^- (.*$)/gm, '<li>$1</li>')92  html = html.replace(/^\* (.*$)/gm, '<li>$1</li>')93  html = html.replace(/^\+ (.*$)/gm, '<li>$1</li>')94  html = html.replace(/(<li>.*<\/li>\n?)+/g, function(match) {95    return `<ul>${match.trim()}</ul>`96  })97 98  html = html.replace(/^\d+\. (.*$)/gm, '<li>$1</li>')99  html = html.replace(/(<li>.*<\/li>\n?)+/g, function(match) {100    return `<ol>${match.trim()}</ol>`101  })102 103  html = html.replace(/- \[x\] (.*$)/g, '<li><input type="checkbox" checked disabled> $1</li>')104  html = html.replace(/- \[ \] (.*$)/g, '<li><input type="checkbox" disabled> $1</li>')105 106  // DIVIDERS107  html = html.replace(/^---$/gm, '<hr/>')108  html = html.replace(/^\*\*\*$/gm, '<hr/>')109 110  // MATH111  html = html.replace(/\$(.*?)\$/g, '<tg-math>$1</tg-math>')112  html = html.replace(/\$\$([\s\S]*?)\$\$/g, '<tg-math-block>$1</tg-math-block>')113 114  // TABLES115  let tableRows = html.match(/\|.*\|/g)116  if (tableRows && tableRows.length > 1) {117    let tableHtml = '<table>'118    let isHeader = true119    120    for (let row of tableRows) {121      let cells = row.split('|').filter(cell => cell.trim())122      let isSeparator = cells.every(cell => /^[\s\-:]+$/.test(cell))123      if (isSeparator) continue124      125      tableHtml += '<tr>'126      for (let cell of cells) {127        let align = ''128        let cleanCell = cell.trim()129        if (cleanCell.startsWith(':') && cleanCell.endsWith(':')) {130          align = ' align="center"'131        } else if (cleanCell.startsWith(':')) {132          align = ' align="left"'133        } else if (cleanCell.endsWith(':')) {134          align = ' align="right"'135        }136        let tag = isHeader ? 'th' : 'td'137        let content = cleanCell.replace(/^:|:$/g, '').trim()138        tableHtml += `<${tag}${align}>${content}</${tag}>`139      }140      tableHtml += '</tr>'141      isHeader = false142    }143    tableHtml += '</table>'144    html = html.replace(/\|.*\|\n?/g, '')145    html = html.replace(/\|---\|/g, '')146    html = html + tableHtml147  }148 149  // COLLAPSIBLE DETAILS150  html = html.replace(/<details>/g, '<details>')151  html = html.replace(/<\/details>/g, '</details>')152  html = html.replace(/<summary>(.*?)<\/summary>/g, '<summary>$1</summary>')153 154  // CLEANUP155  html = html.replace(/\n\n/g, '</p><p>')156  html = '<p>' + html + '</p>'157  html = html.replace(/<p><\/p>/g, '')158  html = html.replace(/<p>\s*<h/g, '<h')159  html = html.replace(/<\/h\d>\s*<\/p>/g, '</h>')160  html = html.replace(/<p>\s*<ul/g, '<ul')161  html = html.replace(/<\/ul>\s*<\/p>/g, '</ul>')162  html = html.replace(/<p>\s*<ol/g, '<ol')163  html = html.replace(/<\/ol>\s*<\/p>/g, '</ol>')164  html = html.replace(/<p>\s*<blockquote/g, '<blockquote')165  html = html.replace(/<\/blockquote>\s*<\/p>/g, '</blockquote>')166  html = html.replace(/<p>\s*<table/g, '<table')167  html = html.replace(/<\/table>\s*<\/p>/g, '</table>')168  html = html.replace(/<p>\s*<pre/g, '<pre')169  html = html.replace(/<\/pre>\s*<\/p>/g, '</pre>')170  html = html.replace(/<p>\s*<hr/g, '<hr')171  html = html.replace(/<hr\/>\s*<\/p>/g, '<hr/>')172  html = html.replace(/<p>\s*<tg-math/g, '<tg-math')173  html = html.replace(/<\/tg-math>\s*<\/p>/g, '</tg-math>')174  html = html.replace(/<p>\s*<tg-math-block/g, '<tg-math-block')175  html = html.replace(/<\/tg-math-block>\s*<\/p>/g, '</tg-math-block>')176 177  return html178}179 180// =======================181// VALIDATE AND FIX HTML182// =======================183function validateAndFixHtml(html) {184  html = html.replace(/<tg-math>\s*<\/tg-math>/g, '')185  html = html.replace(/<tg-math-block>\s*<\/tg-math-block>/g, '')186  html = html.replace(/<tg-emoji>\s*<\/tg-emoji>/g, '')187  html = html.replace(/<tg-time>\s*<\/tg-time>/g, '')188  html = html.replace(/<tg-reference>\s*<\/tg-reference>/g, '')189  190  html = html.replace(/<tg-time[^>]*>/g, function(match) {191    if (match.includes('unix=') && match.includes('format=')) {192      return match193    }194    return ''195  })196  197  html = html.replace(/<tg-emoji[^>]*>/g, function(match) {198    if (match.includes('emoji-id=')) {199      return match200    }201    return ''202  })203  204  html = html.replace(/<tg-reference[^>]*>/g, function(match) {205    if (match.includes('name=')) {206      return match207    }208    return ''209  })210  211  return html212}213 214// =======================215// HELP ARTICLE216// =======================217let helpHtml = `218<details>219<summary><b>📝 Rich Formatting Help</b></summary>220<p><b>Markdown examples:</b></p>221<pre><code># Heading222**bold** *italic* ~~strike~~223==highlight== ||spoiler|| \`code\`224- List item2251. Numbered226| Table |</code></pre>227<p><b>HTML also supported!</b></p>228<p><b>Try:</b> <code>&lt;h1&gt;Hello&lt;/h1&gt;&lt;b&gt;bold&lt;/b&gt;</code></p>229</details>230`;231 232// =======================233// PROCESS USER INPUT234// =======================235let userText = query.trim();236 237if (!userText) {238  return Api.answerInlineQuery({239    inline_query_id: inlineId,240    cache_time: 5,241    is_personal: true,242    results: [{243      type: "article",244      id: "help",245      title: "📝 Rich Formatting Help",246      description: "Use Markdown or HTML",247      input_message_content: {248        rich_message: { html: helpHtml }249      }250    }]251  });252}253 254// Check if it's pure HTML255let isHTML = userText.includes("<") && userText.includes(">") && 256             (userText.includes("</") || userText.includes("<br>") || 257              userText.includes("<b>") || userText.includes("<i>") ||258              userText.includes("<u>") || userText.includes("<code>") ||259              userText.includes("<h1>") || userText.includes("<p>"))260 261let finalHtml = isHTML ? userText : markdownToHtml(userText)262finalHtml = validateAndFixHtml(finalHtml)263 264let shortTitle = userText.length > 40 ? userText.substring(0, 40) + "..." : userText265 266// =======================267// RETURN RICH MESSAGE268// =======================269Api.answerInlineQuery({270  inline_query_id: inlineId,271  cache_time: 0,272  is_personal: true,273  results: [{274    type: "article",275    id: "rich_" + Date.now(),276    title: "📝 " + shortTitle,277    description: "Tap to send formatted message",278    input_message_content: {279      rich_message: { html: finalHtml }280    }281  }]282});