From WhatsApp to Todoist: an n8n + Whatsmeow automation

I make a lot of promises on WhatsApp.
“Yeah, I’ll send that later.”
“Sure, I’ll ask him.”
“Remind me to book it tomorrow.”
But more often than not, I never do.
It’s not that I don’t want to do these things. It’s just that unless I stop everything I’m doing right there, open Todoist, and add the task manually, there’s a solid 50/50 chance I’ll forget about it entirely.
After this had happened one time too many, I figured that it's time to do something about it. After all, this is 2025 - the age of AI! It's simply unacceptable that so many of the tasks I commit depend on a me remembering to file them. There has to be a better way.
The plan: Monitoring messages with AI
Once I accepted that I clearly can’t be trusted to remember my own commitments, I figured I might as well outsource the job.
The goal was simple: I wanted something that could read my WhatsApp messages, figure out when I promised to do something, and make sure it ended up in Todoist - without me lifting a finger.
At first, I thought this would be easy. Just plug into WhatsApp somehow, run the messages through an LLM, connect Todoist’s API, done. Right?
Not quite.
Turns out, there’s no “nice” way to monitor your own WhatsApp messages. The official APIs are meant for businesses, so if I wanted to make this work, I’d need to start with step one: getting access to my own WhatsApp data.
What about the WhatsApp MCP Server?
If you recall, in a previous post I used a WhatsApp MCP server to do something similar. So you might ask - why not use it again?

Well, unlike in the previous post, this project was meant to run in a cloud hosted VPS. Now, while I trust in my ability to secure servers, this means that the risk is higher - and I wouldn't want my entire WhatsApp history sitting in a VPS.
I also didn’t need all the bells and whistles that come with MCPs. I wasn’t trying to build a chatty AI that replies to people. I just needed a way to read messages.
Building A WhatsApp Listener
So, what did I do?
I read through the MCP Server documentation, and found out that it is using a Go package called whatsmeow that implements a WhatsApp client using their Web MultiDevice APIs.

So, I took the example code for this package and hacked together a small Dockerized application called whatsapp-aggregator
.
This app uses the API to listen in on new messages and store them in a local Sqlite3 database:
client.AddEventHandler(func(evt interface{}) {
switch v := evt.(type) {
case *events.Message:
senderType := "from"
if v.Info.IsFromMe {
senderType = "sent by me to"
}
log.Printf("Received message %s %s in chat %s: %s",
senderType, v.Info.Sender, v.Info.Chat, v.Message.GetConversation())
// Store message in database
if err := messageDB.InsertMessage(v, client); err != nil {
log.Printf("Failed to store message: %v", err)
} else {
log.Printf("Message stored successfully")
}
}
})
In addition, to make sure that we store as little data on the server as possible, a Python script is also running alongside the Go package.
This script runs every few minutes and deletes old messages - ensuring that the server only keeps the last 24-hours worth of messages.
Gathering Context for the Agent
With the messages now available on my server, I needed to deal with the automation part.
Like in previous cases, I decided that I would use n8n
for the workflow, but quickly ran into an issue - n8n
did not have a native Sqlite integration!
Luckily, the n8n
community nodes came to the rescue - and I found a simple node that allowed me the query the DB called n8n-node-sqlite3
.

Next order of business was getting existing TODOs out from Todoist. I didn't want to get duplicates - so if there's already a task for something I mentioned on WhatsApp, I didn't want the agent to create another one.
To get the existing tasks, I initially used the n8n Todoist node - but I quickly ran into an issue. When using this node to query existing tasks, it would not return completed tasks - which meant that once I marked a task as done it would be re-added by the agent.
To go around this issue, I used a custom HTTP node that directly called the API to get the completed tasks.

Once I had both the completed tasks, the open tasks, and the messages history, I had all the context I needed to fire up the agent itself.

Creating a Gemini Agent...using Claude???
Now, I knew I wanted to use Gemini as the LLM for this agent because I had good experience with how it handles tasks. However, I knew that writing the prompt for this on my own would be a hard task.
Instead, I decided to use another LLM! I fired up Claude Sonnet, and fed it instructions on how I want this agent to work.

In addition to my instructions, I gave it this screenshot, from the Anthropic talk Prompting 101
- which I recommend watching for everyone working on agents.

Basically, this is the structure recommended by Anthropic researchers for how to construct a prompt - including things like context engineering, giving the model concrete examples, and more.
After some back and forth with Claude, I had a 500-lines long prompt that started like this:You are an intelligent task management assistant that analyzes WhatsApp conversations and Todoist tasks to identify missing action items. Your goal is to help users capture commitments and action items that haven't been added to their task list yet.
You should maintain a precise, analytical tone. Be conservative in your analysis - it is better to miss an action item than to create duplicate or unnecessary tasks.
The full prompt is available here.
Creating the task and notifying about it
Once the agent had came up with a list of tasks, all that's left to be done is to add them to Todoist.
For this I am once again using the Todoist node - and I make sure to add the n8n-generated
label to ensure that I know that these tasks were auto-generated.

Once the task had been created, I added one final node that uses Pushover to sends out a notification about the new task with a link to the task in Todoist.

This is useful to allow me to get feedback that the system is running properly and that new tasks are being added.

Conclusion
And that’s it. My "personal assistant" now quietly listens to my WhatsApp chats, figures out what I’ve committed to, and keeps Todoist up to date. This is what the final n8n
workflow looks like:

It’s a small thing, but it echos my favorite type of hacks - ones that blend seamlessly into the background of your life, and help make them better - one message at a time.