This is a partial replacement for the wonderful Autodoist app by Hoffelhas. Changes to the Todoist API temporarily broke Autodoist. I wrote this to keep "next_action" alive while Autodoist was down and as an example for an article on building and hosting a "bot".
Hoffelhas has since restored Autodoist to its former glory. This project works, and I will continue to use and maintain it, but in your shoes I'd probably defer to the Lindy Rule and go with Autodoist, the more established project.
This project reproduces (and tweaks) the functionality of Autodoist that I rely on. It finds (sub)projects, sections, or (sub)tasks with special markers (that you select) and applies or removes tags with one of three schemes: serial, parallel (more below), or all.
Don't miss the ("or removes") part of that. This is a dynamic system. If you remove a marker, the labels will be removed a few seconds later. So, feel empowered to @park or @activate or @whatever-you-like any project, section, or task for half an hour if that's useful to you. But know that any labels you use with this program belong to the program. The program will freely add and remove these labels per the logic you select when running the script. If you're not sure, see the --dry-run
argument.
-h, --help show this help message and exit
-a API_KEY, --api_key API_KEY
REQUIRED: your Todoist API Key.
-s [SERIAL ...], --serial [SERIAL ...]
format "label suffix". Add [label] to the next (sub)task beneath or at any item with a name ending in [suffix]. Example:
"next_action -n" will add the label `@next_action` to the next task beneath or at any project, section, or task with a name
ending in -n.
-p [PARALLEL ...], --parallel [PARALLEL ...]
format "label suffix". Add [label] to all childless (sub)tasks beneath or at any item with a name ending in [suffix]. Example:
"actionable -a" will add the label `@actionable` to all childless (sub)tasks beneath or at any project, section, or task with a
name ending in -a.
-l [ALL ...], --all [ALL ...]
format "label suffix". Add [label] to all (sub)tasks beneath or at any item with a name ending in [suffix]. Example: "parked -p"
will add the label `@parked` to all (sub)tasks beneath or at any project, section, or task with a name ending in -p.
-d DELAY, --delay DELAY
Specify the delay in seconds between syncs (default 5).
-n, --dry-run Do not update Todoist. Describe changes and exit.
-o, --once Update Todoist once then stop watching for changes.
Apply a label to the next (sub)task (leftmost leaf).
Image generously provided by Hoffelhas under the MIT license.Apply a label to all (sub)tasks with no descendent tasks (all leaves).
Image generously provided by Hoffelhas under the MIT license.Apply a label to all tasks under a Project, Section, or Task.
The meaning of "next task" is not objective. Todoist doesn't represent tasks in a strict hierarchy of
Project -> Section -> Task
Two tasks under the same project might be
Project -> Subproject -> Section -> Task1
# and
Project -> Task2
So, even though Todoist objects have an order attribute, there is no canonical ordering of child nodes of different types. When comparing different node types, I give higher priority to shorter branches. So, in this case, Task2 would be selected as "next task" over Task1. For a typical use case (one project with multiple sections, all tasks in a section), the "next task" will be the task in the upper-left corner of the board view.
The full hierarchy is:
Highest priority first:
* Project -> Task
* Project -> Section -> Task
* Project -> Subproject -> Task
* Project -> Subproject -> Section -> Task
* Project -> Subproject ... Subproject -> Task
* Project -> Subproject ... Subproject -> Section -> Task
Further, Todoist will nest any number of subprojects and subtasks, so there is no one true answer to leftmost leaf.
This can be run as a script with Python with the two dependencies in requirements.txt. If that's new to you or you've never created a virtual environment, this will get you there:
python -m venv venv
./venv/Scripts/activate
pip install todoist_api_python paragraphs
python main.py
That will print the instructions for putting together an actual command. The command I use is
python main.py -a <my api key> --serial "next_action -n" "blocking -b" --parallel "actionable -a" -all "parked -p"
This command will:
- For any Project, Section, or Task with an
-n
suffix (e.g.,Clean Office -n
), tag the next task with@next_action
. - For any Project, Section, or Task with an
-a
suffix (e.g.,Purchase Supplies -a
), tag all top-level (no subtasks) tasks with@actionable
. - For and Project, Section, or Task with a
-p
suffix (e.g.,Post Review Actions -p
), tag all tasks and subtasks with@parked
.
I suggest following the "dash letter" suffix style. You can also use "-word" or just "word". Double symbols (e.g., the "--" you may be accustomed to from Autodoist) have a potential to cause problems. Autodoist makes provisions for some of these problems. Todoist-bot does not.
If you're not sure where to find your API key or you'd like to go further and run this program as a bot on a remote server (that's what it was built for), see this article: Deploy Your First Baby Bot on Heroku on my personal website.