Here we will introduce a simple and OpenSource bot created by Devforth for managing checklists in Telegram.

How to use bot in Group with other users

You can very simply write to the bot in direct messages and it will turn them into a clickable checklist. But there might be 2 reasons why you might want to add a bot to a group or channel:

  1. Use same checklists with other Telegram users
  2. Split topics (e.g. checklists for renovation in one group and for food in other group)

To use bot in group we have to make him admin, so he will be able to read a messages. Here we will explain how.

First of all, create a group or channel which you will use for your checklists. After doing this add ToBeDo bot as a member:

Add members to Telegram group
Add members to Telegram group

Search for ToBeDoor type tobedo_bot:

Search for ToBeDo checklist bot
Search for ToBeDo checklist bot

Go to group settings and make a bot an administrator:

Promoting bot to admin
Promoting bot to admin

Done! Now you can simply write a message to channel and Bot will respond with a generated checklist:

ToBeDo bot response
ToBeDo bot response

Overcoming Telegram API limitations by persisting state 

The Telegram API provides a bot API that allows the reading of messages written to the bot in Direct messages or Group/Channel messages if the bot is promoted to the admin level. The bot can reply to messages and attach keyboards where we can add one button for each checklist item. 

Since there are no specialized UI elements for checkbox we can simply use emojis like✅ and ⬜ and type them in title of button. Since bot can handle click on button which he drawn, we can swap the state by checking current emoji char drawn on button. In other words we can use button title as state of check item.

The issue comes when user edits message and expects that check list will be also edited by bot. Thing is that bot can see that message was edited but can't find own reply to it (which has a keyboard) simply because Telegram bot API has no such methods, and even no methods to list all own messages, obviously because it cases more loads and traffic consumption to Telegram servers. Simple solution for this which applied in other bots would be sending a new reply with a new checklist, but it is defiantly bad UX for user chat.

What we can do here is apply the next trick: since the first reply is generated by us, we can also at this moment, remember this state in the local database (currently, we have a simple SQLite DB). In this way, we will remember the message id and reply message ID, and if the user edits it, we will find the reply by message ID. To prevent clashes between chats, we save the chat ID in the Database.

Also, when the user edits the message, we have to try to preserve the previous state, at least of unchanged checked items; when user clicks on a button, Telegram API sends us a callback with the current keyboard state and button titles. But we can't read keyboard attached to the message simply by message-id. To overcome this, we can also store the state of the checklist in the database.

We can also add a scheduler that deletes ancient reply states from the DB to prevent database overflow. For now, the code simply removes every state that was created earlier than 365 days ago, but if you wish, you can fork and implement a more intelligent strategy, e.g., flush checklists that have all items checked and have the last check more than a month ago.