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.
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 :)
Top comments (0)