David Schlachter

Creating recurring tasks in Todoist with cron

My system for task management is simple: a single list of tasks, sorted by 'Date Added' descending. Previously, this lived in a text file on my grad school laptop; now, I'm using Todoist. I keep my list of tasks (the 'Inbox' in Todoist) as a big widget on my phone home screen, so that it's the first thing I see when I unlock my phone. I appreciate the multi-device sync when I'm using a computer.

My one complaint with Todoist is how it handles recurring tasks. When a task has recurrence, it stays in my list according to the creation date of the first instance of the task. Checking it off just changes the due date. Since I don't use due dates, and rely on the order of my list as an indicator of freshness and short-term pertinence, this doesn't work for me.

Previously, I was using the Reminders app on my phone to surface recurring tasks, which I would then add to Todoist or check off in the Reminders app. This wasn't ideal because it created two places with tasks. If you count my calendar (which I used for some tasks with long recurrence intervals), that was three places. Ideally, I would only have one place where I can look and see what I've planned to do.

To centralize my tasks in Todoist, I had the idea to write a small program that would use their API to create tasks. This way, I could have recurring tasks that would work how I want them to: when checked off, they disappear; and when they recurr, the re-appear at the top of the list.

I spent a few hours writing a simple app to do this. The recurring tasks are read from an input file that specifies recurrence using the same format as cron. The format is simple: recurrence, then task name. e.g.

0 18 * * Mon    Take out garbage, recycling, compost
0 9 * * *       Study choreography
0 10 * 4-10 *   Water outdoor plants
30 8 * * Sun    Water indoor plants
0 7 9 5,11 *    Wash and condition sofa

The program checks the file for changes every minute, so that it can add any new tasks and remove any that are deleted. Whenever the time comes to create a task, it uses the Todoist API to do so, and retries if an error is encountered. This could be more resilient (e.g. what happens if the program was not running when a task should have been created?), but it's good enough for me right now.

If this would be useful to you, you can find the source code here, or get it with git clone https://git.schlachter.ca/todoist-repeater