If you want to be able to create To-Do items in Markdown syntax in your note files (e.g. Notes created with Obsidian), but have those materialize in Todoist then this package is for you.
In other words: Type away, making your notes fast and furiously. When a To-do item pops into your mind, no need to switch apps, just make your To-do item in your markdown file and stay in the zone.
After trying it out, if you feel the urge, you can Buy Me a Coffee ☕️ ☕️ ☕️
If you're a visual person, you can see this tool in action, here on YouTube
- Because notes kept in Markdown are very portable. Since they're plain text, they're compatible with a wide variety of tools.
- This author's favorite tool is Obsidian, but you're not limited to any one tool
- Because while To-Do items in Markdown are nice, there's no denying the power of Todoist. (Scheduling, Reminders, Tagging, Delegation, etc, etc)
This tool is not a copy of obsidian-todoist-plugin
I've tried out the popular obsidian-todoist-plugin, by jamiebrynes7 which I think is really great. Markdown Todoist is slightly different however, in that it's more of a Batch Load of parsed tasks rather than a view into todoist Views. I think these tools probably complement each other for different use cases.
This tool is Not an Obsidian Plugin. The Primary reason for this is that the original author is better with Python than Javascript. The original intention was to get things working with Python, as described throughout the rest of this document, then translate all of that into a "Version 2" in the form of an Obsidian plugin.
At this point, that may or may not happen. Reason being that it could be argued that this tool is better off as a standalone code package and that the lack of tight integration with Obsidian is a feature , not a bug because it allows the tool to work with arbitrary Markdown files anywhere on the file system and also makes automation easy to implement (See Automation section below), which might be harder to do (or impossible? ... I haven't looked closely enough) as an Obsidian Plugin
For now, there are no bells and whistles when it comes to Migrating tasks into Todoist. There is no (intentional) handling for Projects, Labels, Priorities. Todoist itself might gracefully handle some of these things based on how the task is worded, but there are no guarantees.
Today, this tool will simply shunt To-Do tasks into your Default Project (.e.g Inbox), with "Today" as the Due Date so that you might go on to augment these tasks with Labels and Comments, change the due date, assign to a project, etc.
The notion comes from the GTD Method.
At a high level, here's what happens:
- When invoked, the tool traverses a directory (e.g. Obsidian Vault Directory) looking for Markdown files with a
.md
file extension. - These files are inspected for Incomplete To-Do items using regular expression pattern matching, looking for To-Do's that look like:
- [ ] Buy Milk
- Any To-Do items are "migrated" to Todoist
- There is a basic check on file timestamp to try to ensure that To-Do items that are still being typed out aren't migrated into Todoist prematurely.
- There is a basic check to try to avoid edge cases where a to-do with the same wording in different places would be created in Todoist more than once
- Migrated To-Do items from
.md
files are 'crossed out' in the markdown file with a link to the corresponding task in Todoist to denote they've been migrated - Migrated To-Do items created in Todoist will contain the Task description as well as an Obsidian URI that points back to the file the To-Do was parsed out of
- This linkage may be imperfect, especially if the file is moved or renamed.
- However, in testing, basic file moves within Obsidian did not break the functionality
This tool was created on a Mac using Python3 (version 3.11). It was tested on that Mac and worked fine there. I would expect that this code work on Windows, but there may be some minor bugs as I didn't test for Windows. If you care to do so and encounter an issue, please get in touch with Adam Reese and/or fix it yourself and create a pull request.
- Python3 (This tool was originally developed and tested with Python 3.11)
- A Todoist Account with Access to the API
- I believe the API is available to all Pricing Tiers of Todoist as of this writing (2022-12-20)
- The package uses todoist-api-python under the hood so that needs to be installed and available to whichever Python3 installation or virtual environment you use
- You may find make_env.sh useful for setting up a Python Virtual Environment, but YMMV
Clone or Download and Extract the code from the repository to your preferred destination. ~/scripts
is a good spot if you're not sure where else to put it.
The make_pyenv_venv.sh
script does its best to bootstrap a Python Virtual Environment using pyenv virtualenv
(more on that here) with the requirements from requirements.txt
installed. You can run this script if you'd like to use that sort of setup.
If you'd like to avoid pyenv some reason, all that is really needed at the end of the day is a Python installation with todoist-api-python and whatever else is in requirements.txt
installed, so this command might be all you need:
pip install -U -r requirements.txt
There are 2 config files you'll need to create under the config
folder:
config.json
which contains config for the program itselftodoist_api_config.json
which contains your API token (Sensitive. Treat it as such)
- As of this writing (2022-12-20), the only thing to configure in this file is the base directory (for example:
~/Obsidian
) where markdown files and subdirectories with more markdown files can be found. - See config_TEMPLATE.json to understand how the file should be formatted
- Make a copy of the file and remove the comments to make it valid JSON
- You'll have to create a configuration file with your Todoist API token in it.
- See todoist_api_config_TEMPLATE.json to understand how that should be formatted.
- Take heed to the notes at the top of that file regarding your API token
- Make a copy of the file and remove the comments to make it valid JSON.
- Enter your Todoist API Token
- To find this in Todoist:
Settings > Integrations > Developer > API Token
- To find this in Todoist:
If you just want to print a list of your To-Do's but not "Migrate" them, as described above you can use find_tasks.py
like this:
python find_tasks.py
Alternatively, you can use the wrapper script that's intended to place nicely with pyenv
./find.sh
To migrate To-Do items as described in the How does this tool work? section above, use migrate_tasks.py
like this:
python migrate_tasks.py
Alternatively, you can use the wrapper script that's intended to place nicely with pyenv
./migrate.sh
If you want to exempt a specific file from having its to-do items migrated to Todoist, simply specify todoist: false
in the YAML front matter at the top of the file.
For Example, a Packing list template for trips might look like the below. It's a checklist, but you might not want to actually make To-do items for everything in that template:
---
tags:
- Template
- Travel
todoist: false
---
# Daily Clothing
- [ ] Shoes
- [ ] Socks
- [ ] Pants
- [ ] Shorts
You can automate migrate_tasks.py
on macOS (Or anything *nix) using a cron
entry. This set up is out of scope to describe here, but for the unfamiliar here is a good place to start. As an example, you might make a crontab
entry like this:
# Parse to-do items out of Markdown files and create corresponding to-do's in Todoist
0 */1 * * 1-5 cd ~/path/to/wherever/you/have/this/script && python migrate_tasks.py > /tmp/migrate_tasks.log 2>&1
You can use this website to help generate and validate your crontab schedules
As mentioned above, this script hasn't been tested on Windows, but should work without requiring too much (or any) fixing. On Windows, instead of cron, you'd want to use the Windows Task Scheduler, the set-up for which is out of scope to describe here.
If you've set up any kind of Synchronization for your Markdown notes (Obsidian Sync, Dropbox, Syncthing, etc), this tool should, in-theory, work without any issue, but please let Adam Reese know and/or fix it yourself and create a pull request if you encounter any issues.
This was tested with Obsidian Sync, and it worked fine.
When a task is "migrated", this tool modifies the markdown file that that task was parsed from on-the-fly.
So a task that looks like this, pre-migration:
Will end up looking like this, post-migration:
Visually, in Obsidian the syntax from the screen prints above renders like this, before and after Before:
After:
Here's what the generated task in Todoist Looks like:
If so, you can Buy Me a Coffee
☕️ ☕️ ☕️