Idea
While I do my automation routine i was thinking about next thing: “why nobody use JSX for building messages, in most cases it’s just simple HTML or Markdown?“.
Yes, in mostly cases each chat application have possibility to send message as raw html. Also, I’m creator and maintainer [Telegraph](https://github.com/vitalics/Telegraph)
repository.
This repo was created to simplify working with Telegram by simple wrapper.
While I write [fmt](https://github.com/vitalics/Telegraph/tree/main/packages/fmt)
package i was thinking about next thing: “wait a minute, context can be replying with html by replyWithHTML
function. And also I’m familiar with React and JSX syntax, why nobody joining this ideas?”
POC
I start to think how to join JSX and formatting. For html
it was simple: wrap each function to custom component which reuse built-in HTML tags.
Q: Why wrap?
A: Since each html tag may contains class
, style
, etc attributes, but in telegram it’s not applies, so attributes should be ignored.
HTML
Each component is very simple and primitive:
As for render to HTML I found [preact-render-to-string](https://github.com/preactjs/preact-render-to-string)
package from official preact team to create raw HTML nodes.
Markdown
As for markdown I found the issue about using tags.
But I also remember about special characters, e.g. for bold text I just can write *bold*
and the text will be bolded.
But if i return just text, it will not the match to JSX.Element
type.
The answer is comes to me unexpectedly - Fragment
component - this just returns children element.
Using this knowledge I start to implement components. E.g. look at the bold component in markdown implentation:
As for render function I use node-html-parser, since i should get text content of received raw html-like text:
Default format
What should i do when user would like to use reply
function. This function applies raw text as a first parameter and text modifications as the second parameter.
Since fmt
string function is working with stringified text - so i made function which reuse default fmt
function for raw text, but i found inconsistency, and made decision do not break fmt functionality, some components are the same as for html
realization, but some of the components has a differences with html
realization
Similar with HTML:
Differences:
And Render function reuse default fmt function
That’s why If user would like to use default components - he needs to use rest/spread
operator.
Result
Code
Pros
- Using JSX for describing messages in telegram context.
- Written in typescript, autocomplete is works fine.
Cons
- many realizations, default, html, markdown. Ideally using only one render function per realization, and only one component realization.
- Pick preact instead of React. I have no idea why i choose preact. I think React is more preferable for node.js/frontend developers, but not sure about this sentence 😁
Conclusion
As for me, I do many non-trivial works, never working with preact before, but it was a great experience.
How to use this examples:
Important: use version 1.4.0 or higher since JSX was introduced in this release, You can also read release from official Telegraph repository.
P.S. Or You can read official package API and tutorial from docs page. P.P.S. This 1.4.0 release are also posted in Telegraph blog post page
Have a good day, Bye 👋