DEV Community

loading...
Cover image for Send message as a Telegram bot. What may go wrong?

Send message as a Telegram bot. What may go wrong?

mbelsky profile image Max Belsky ・2 min read

Last month I've worked on @hltvFeatured – it's a Telegram bot to get notifications about upcoming Counter-Strike: Global Offensive matches featured by HLTV.org.

Example of @hltvFeatured message

After a few weeks in production I've got an alert that the bot fails on sending notifications to subscribers. I had no access to my PC, so it was so nervous. I didn't know what may go wrong.

When I back to home first of all I opened IDE and started debugging. There were no issues with database, the app's code or network. But the Telegram API returns error 400: Bad Request: can't parse entities. I've started analyze what wrong with the messages and why it didn't fail before.

Telegram API allows to format messages in two styles: Markdown and HTML. I've selected Markdown as less verbose and wrote a small function to convert match data entity to a Markdown string:

function convertToMessage({ event, href, stars, title, unixTimestamp }) {
  const when = new Date(unixTimestamp).toUTCString()
  const date = formatUTCString(when).replace(/\s/g, NBSP)

  return `
[${title.replace(/\s/g, NBSP)}](${href})
Rating: ${''.repeat(stars) || ''}
_${date} @ ${event}_
`.trim()
}

That day matches had an interesting event name: cs_summit 5 and I immediately noticed it. As you can see the convert function makes date and event italic: _${date} @ ${event}_. So the message contained three underscores. I didn't expect that Telegram API can't parse a message like that, so I've started search for a dependency to escape symbols like _, * and [ in matches data before inject it in message template.

You have no idea how I was surprised when Telegram API answered with the same error for a message with escaped symbols. This time I went to google it. The solution was a suggestion to use HTML markup and escape symbols. I've updated my function and... it works!

function convertToMessage({ event, href, stars, title, unixTimestamp }) {
  const when = new Date(unixTimestamp).toUTCString()
  const date = formatUTCString(when).replace(/\s/g, NBSP)

  return `
<a href="${href}">${escapeHtml(title).replace(/\s/g, NBSP)}</a>
Rating: ${''.repeat(stars) || ''}
<i>${date} @ ${escapeHtml(event)}</i>
`.trim()
}

I can't imagine a case when Markdown is a good choice to markup messages delivered by a bot. And if you can, please, share in comments :)

Discussion (0)

pic
Editor guide