Skip to content

Instantly share code, notes, and snippets.

@craigeley
Last active January 5, 2023 19:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save craigeley/230a75d8e59e70f0cc3e8caf79c7f546 to your computer and use it in GitHub Desktop.
Save craigeley/230a75d8e59e70f0cc3e8caf79c7f546 to your computer and use it in GitHub Desktop.
This script allows you to use Todoist as your primary todo list manager but still see tasks in Todoist formatted in a way to work with the [Obsidian Tasks](https://github.com/obsidian-tasks-group/obsidian-tasks/blob/main/README.md) plugin for sorting and querying. If you set this script to run periodically, it can close tasks that have been clos…
#!/usr/local/opt/ruby/bin/ruby
# encoding: utf-8
require 'json'
require "unicode/emoji"
# Variables: path and API key
path = "/Users/USER/Library/Mobile\ Documents/iCloud\~md\~obsidian/Documents/VAULTNAME/"
key = "YOUR TODOIST API KEY"
# First close all completed tasks in Obsidian
stayput = ""
File.readlines(path+"Tasks.md", :encoding => 'utf-8').each do |line|
if line.include? "✅"
output += line
/(?<close_id>\d+)/ =~ line
close = %x{curl -sS -X POST "https://api.todoist.com/rest/v2/tasks/#{close_id}/close" \
-H "Authorization: Bearer #{key}"}
puts close
else
stayput += line
end
end
f = File.open(path+"Tasks.md", "w+") { |f|
f.puts "#{stayput}" }
# Don't tax the API
sleep 1
# Get active tasks and format them like Obsidian Tasks
call = %x{curl -sS https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer #{key}" \
-d sync_token="*" \
-d resource_types='["items","projects"]'
}
data = JSON.parse(call)
sync_token = data["sync_token"]
projects = data["projects"]
items = data["items"]
output = ""
taskarray = []
items.each do |item|
name = item["content"]
id = item["project_id"]
uuid = item["id"]
name = "#{name} [🔗](todoist://task?id=#{uuid})"
proj = ""
projects.each do |project|
if id == project["id"]
proj = project["name"]
proj = proj.downcase.gsub(/\s/, "_")
end
end
if item["priority"] == 4
priority = "⏫"
end
if item["due"] != nil
due_date = item["due"]["date"]
due_date = "📅 #{due_date}"
end
inject = { :name => name, :due => due_date, :category => proj.strip, :priority => priority}
taskarray.push(inject)
end
# Organize and sort tasks
tasktext = ""
taskarray = taskarray.sort_by {|h| [h[:category]]}
uniq_proj = taskarray.map { |e| e[:category] }.uniq
uniq_proj.each do |project|
tasktext += "\n### #{project}\n"
taskarray.each do |unit|
if unit.has_value?(project) && unit[:due] != nil && unit[:priority] != nil
tasktext += "- [ ] " + unit[:name] + " ##{project} " + unit[:priority] + " " + unit[:due] + "\n"
elsif unit.has_value?(project) && unit[:due] != nil
tasktext += "- [ ] " + unit[:name] + " ##{project} " + unit[:due] + "\n"
elsif unit.has_value?(project)
tasktext += "- [ ] " + unit[:name] + " ##{project}\n"
end
end
end
# If you want to take a look at your output, uncomment the next line
# puts tasktext
File.open(path+"Tasks.md", 'w+') { |file| file.write("#{tasktext}") }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment