Lessons I've learned from building a COVID-19 Bot with 10K users on Telegram
Tags: node, telegram, javascript, covid
Published: 2020-08-28 00:47:48

In the beginning of 2020, we came to know about COVID-19. It was only a matter of time until the virus arrived in Brazil, and in the midst of some confusion and fear, I decided to spend my time indoors writing some code targeted at our latest global problem. **[CoronavirusBrBot](https://t.me/coronavirusbrbot)**, *a bot for tracking the situation of the pandemic in Brazil*, was created on Telegram, became popular and at one point had ~18k users (including group users).

This article talks about the decisions I've made and challenges I've faced while creating and maintaining CoronavirusBrBot. It also talks about some technical choices suitable for **side-projects with limited resources.**

{% vimeo 452371721 %}

# Make an MVP (Minimum Viable Product)

*Focus on the minimum number of features required to ship your product as early as possible. This will give you quicker feedback from your users.*

Back when cases were rare in Brazil, I wanted to **receive mobile notifications from Ministry of Health's website data** to track the current pace of the disease. So I focused on getting that done as my first feature.

Since I'm a web developer, my first thought was *"I will create an App for this"*. But I eventually came to the conclusion that a **Telegram Bot** was much more appropriate for building my **MVP**, along with a very very simple database called [Lowdb](https://github.com/typicode/lowdb). 

*The "right tool" for the job can be simpler than you expect.*

Using [node-telegram-bot-api](https://github.com/yagop/node-telegram-bot-api), all I had to do was create a bot using [BotFather](https://telegram.me/BotFather), and use Lowdb for a schemaless database structure and straightforward data manipulation.

|![Initial bot version with cases count](https://dev-to-uploads.s3.amazonaws.com/i/44p9prt46szi6fhiq4uc.png)|
|:--:| 
| *Initial version of the bot.* |

# Surround yourself with people with common goals

*Don't be afraid to reach out for help. Once you find people with the same goals as you, you'll realize how much more you can create together.*

{% github wcota/covid19br no-readme %}

In order to improve the bot, I spent some time looking for COVID-19 resources until I found [covid19br](https://github.com/wcota/covid19br) by [W. Cota](https://twitter.com/wlcota), who introduced me to a group of people working with COVID-19 data, including [coronavirusbra1](https://twitter.com/coronavirusbra1) who has done an outstanding job covering COVID-19 news. **We were able to benefit from each other's work and referrals.** For the bot, it meant **earning new users and a new data source**, as well as the support from the team during hard times.

|![Cases and Deaths in Brazil](https://dev-to-uploads.s3.amazonaws.com/i/hniseu6gyvt734y7vvxh.png)|
|:--:| 
| *Nowadays the bot provides multiple data sources.* |

# Listen to what users have to say

One of the first features I implemented in CoronavirusBrBot was a command for the user to give us feedback. I was pleased to receive many ideas related to my initial plans, as well as new ones (e.g.: filter data by city) that were implemented afterwards and became popular. As long as you **take opinions with a grain of salt and prioritize goals**, listening to users will improve your development cycle.

|![Command contact allows for feedback](https://dev-to-uploads.s3.amazonaws.com/i/g5cgmsjygejt7savhg5r.jpg)|
|:--:| 
| *Feedback channels are a great way to validate that you're on the "right track".* |

# Avoid Premature Optimization
Don't be afraid to evolve your app as required, instead of designing the architecture for extreme scenarios in the first iteration. **Often, you will be able to fix the issues quicker than your app scales.** Examples: 
* The bot used to enqueue all messages and send them consecutively, one-by-one. This became slow by the time we got to ~500 users, as it took ~8 minutes to send updates to everyone. The solution was to **parallelize messages** at a rate of 20 messages/second (Telegram's limit is 30).
* The log of actions used to be saved in the same database storing user information. That quickly became a bottleneck for performance, since LowDB has to stringify and parse all of the database content. Solution: moved the log to a **separate append-only file**.
* Syncing the whole DB from RAM to disk also had an impact once we increased the sent messages frequency. Instead of saving the DB every time, I optimized the code to **save once every 3 seconds** for bulk sends, and before shutting down the server. Problem solved without needing to change databases :)



# It doesn't have to be perfect
*When using limited time and resources, don't bother about making it too perfect.* **Sacrifices in quality have to be made.** Specifically for the bot:

* **Production and Development used to be the same environment**. I was coding it late at night (2-4am) when almost nobody was using it, applying changes immediately with restart, and keeping an eye on the logs during the day to make sure nothing would break. 

* **Code quality is not ideal**. **I did not use Typescript for this project.** The project has huge `.js` files, and the folder structure is weird. But it runs, and that's good enough :)

* **Incidents happened:** Most of the time, these were minor, e.g. sending messages twice. However in one time **the database got corrupted due to the hard drive being full.** Luckily I was able to revert to a backup created not so long before the incident. 

*Backups are essential, take them frequently and the consequences of loss of data will be greatly diminished.*

# Seize the Opportunity

If I were to launch the bot today, it probably wouldn't have been as popular as it is. **Part of its success was due to the trust users have put into our work** for delivering accurate information on a daily basis.

*The sooner you start working on making your idea come true, the higher the probability it will be successful.*

|![User Count](https://dev-to-uploads.s3.amazonaws.com/i/3pu0ej9m6v367rmskkw1.jpg)|
|:--:| 
| *8,612 people + 5,138 indirect people (channel/group users) =* **13,750 total users**| 


# Got an Idea?

**Before you Start:**
* **Trust your idea even if no one else does!** Don't ask for people's approval as this can actually work against you. **Be persistent.**
* **Prepare yourself with a  "no regrets" attitude**. In the worst-case scenario you will have failed, wasted some time and acquired important knowledge. Meaning you will be ready for the next challenge in your life.   
* If you have to gather information about your audience, do some market research, which uses a  more objective, unbiased  approach than asking informal questions to people around you.

**During the Process:**

* Use **metrics** and **feedback from users** to measure your app success.

* Some people may not understand the value of your creation and the effort you've put into making it come true. **There's nothing you can do about this!** Don't waste time trying to  convince anyone and...

* **Find people who NEED your app.**  Don't be discouraged in case your initial users (friends, colleagues, close ones, etc.) are indifferent to your creation, they might not overlap with your target audience. **The internet is a gigantic place and your target audience is certainly there, you just have to keep looking.**

*If you build something good enough that reaches the intended target audience, users will come. If they build trust on your app, they will stay.*

# The Bot is Open Source
Feel free to check the code for the bot at:
{% github stackomate/coronavirus-bot no-readme %}


# Final Acknowledgments

*Cover photo by [CDC - Unsplash](https://unsplash.com/@cdc)*

I would like to give special thanks to 
[coronavirusbra1](https://twitter.com/coronavirusbra1), [Wesley Cota](https://twitter.com/wlcota), [Fabio Rehm](https://twitter.com/fgrehm), [PokeCorona](https://twitter.com/PokeCorona), [leonardomed](https://twitter.com/leonardomed), [hexry13](https://twitter.com/hexry13), and [aletoorres](https://twitter.com/aletoorres) for providing me the **data sources, graphs and support when I needed the most.**
Check Coronavirusbra1's panel at [coronavirusbra1.github.io](https://coronavirusbra1.github.io).
Also, thanks to [inlocotech](https://twitter.com/inlocotech) and [turicas](https://twitter.com/turicas) for graphs and regional data. 
**CoronavirusBrBot would not have been possible without your help.** ❤️