Time-Tracking via the Telegram Bot API and Webhooks

How my search for the ideal time tracking tool ended with a surprising result

Marten Gartner
Better Programming
Published in
5 min readAug 19, 2022

--

Image from Unsplash by Bred Neathery

In this article, I want to present a way to track your time using Telegram’s Bot API and Webhooks. I will guide you through the setup, configuration, and deployment. But first, let’s look at how this idea came to my mind. If you’re only interested in the technical part, skip to the next section.

Intro

In one of our evening talks, my wife said she needed to write the hourly report for her job for the last three months and tried to find out the exact hours she worked. She didn’t have any tooling to help her track her time, so it was quite a pain to find all these things in old notes and chats. Then she told me she agreed with her boss to make a WhatsApp group where she writes a message when she starts working and when she stops, and based on these messages, it’s easy to fill the respective reports.

I thought: Quite a nice idea. You have your phone mostly always with you, and it’s not a big deal just to write “start” or “end” or whatever. I was quite impressed and thought about this approach. I spent a lot of hours the last few months to find good tooling to track my time and always had the issue: it needs to be easy to enter that I now work on a task or finish a task, and it must be doable from all devices that I have.

So I tried some apps for time tracking, which can run on my Mac, Linux machine, and phone, but nothing really knocked my socks off. Back to the idea of how my wife does her time tracking now, I thought that writing down when I start what task and when I finish it in a messenger is a great idea. After a bit of research about Bots and Webhooks, I built some tooling based on telegram.

My idea was to create a telegram bot and to implement Webhooks for specifically formatted messages, which save timestamps and task descriptions in CSV format. Let’s have a look at how it works.

Setting Up the Project

At first, I started searching for existing libraries or examples that use Telegram Webhooks and found this one on GitHub: node-telegram-bot-api. It looked easy to use, and I am a fan of Node, so I decided to try it. Since it provided a library, I needed to set up a node application. I prefer TypeScript over JavaScript, so I set up my project accordingly.

There is a cool tool called typescript-starter that you can run as npm executable via npx typescript-starter . It asks you some questions, for example, if you want to build a library or an application, which was the latter for me. After setting up the project by keeping the default values in the setup dialog of typescript-starter, I created a launch configuration for debugging in VS Code. After some experimenting, my final launch configuration looked like the following:

The main part of the code goes into src/main/index.ts. To configure Webhooks for messages sent to a telegram Bot, the node-telegram-bot-api provides a great template, which I adapted slightly. At first, I installed the required packages:
- npm i --save node-telegram-bot-api
- npm i --save @types/node-telegram-bot-api

Telegram bot code

Then I changed the imports from the example code from require to import (to get type safety for the imported code) and added my token. The code looked like this and was ready to be tested:

Using the on and onText hooks, functions for each incoming message (on) or for messages that match a particular (onText) regex are called. In these functions, the example code answers by sending messages back to the respective chat. The level of abstraction this library provides is great, in my opinion. So I was ready to test the example.

At first, I created a bot by going to telegram (or web telegram), opening a chat to Botfather (follow the t.me link in the doc), writing /newbot, and giving it a name and a username following the requirements. The BotFather printed the token, which needed to be set in the token constant at the beginning of the code. Afterward, I ran the telegram API bot via the launch command in VS Code I added before.

After opening a new chat to the bot by clicking the link I received from the Botfather and clicking start at the top right, I was able to test the Webhooks by sending /echo Hello to the bot. It should reply with hello (through the onText function) and send another text, “Received your message.”

Great! Now let’s add some more functionality to the example code.

Adding Handlers and Code for Time-Tracking

As mentioned before, my goal was to store my time-tracking in the CSV format to allow editing later in Excel. Working with CSV files in Node is quite easy. Despite many libraries doing this task, I decided to write it from scratch, just for fun. For my prototype, I wanted to have the following commands for my bot:
- /work $message -> Starts the work on the task $message
- /done -> Finishes the last started task
- /state -> Shows the state of the last task (started or finished)
- /print-> Writes the whole CSV into the chat

To read and write CSV entries, I implemented the following two functions:

The function getEntries returns the CSV content as JS objects, and the writeFile function stores the JS objects into the CSV file. So, there is no real need to use a library. With these two functions, I implemented the four handlers mentioned above:

The work command adds an entry with a startDate and the respective text added to /work . The /done command checks if there is at least one entry in the file and sets the endDate and the duration. The /state and /print handlers work similarly, doing what I presented above. That’s it!

Not much code, but a pretty cool feeling to use this tool. I ran it in debug mode to test if everything worked as expected. Great. Now let’s head to the final task: deployment.

Deployment of the Telegram Time-Tracker

I added a Dockerfile with a multi-stage build to run it on any host. You could also pass the token as an env variable or similar for deployment. The easiest way to run it on a server (with docker setup) is to push your repo to the server and just build and run the container (after changing the token to your bot token):

  • docker build -t telegram-timetracker:latest
  • docker run -ti --rm telegram-timetracker:latest

One may set the token via an env variable to avoid editing the code, but that’s just a minor optimization. The whole repo can be found here. I really like this way of tracking my tasks.

Please feel free to share any feedback. I’d be glad to add it to this article.

--

--

Marten Gartner
Marten Gartner

Written by Marten Gartner

I’m a dad, software developer and researcher on network performance. Writing about high-speed frontend-dev, neworking, productivity and homeoffice with kids.

No responses yet