Skip to content

Instantly share code, notes, and snippets.

@frodosamoa
Last active June 2, 2023 23:26
Show Gist options
  • Save frodosamoa/17d75c0272f8c49c6f76f10b4457f9d8 to your computer and use it in GitHub Desktop.
Save frodosamoa/17d75c0272f8c49c6f76f10b4457f9d8 to your computer and use it in GitHub Desktop.
reminders to todoist

inspiration taken from: https://github.com/FirePanther/Apple-Reminders-to-Todoist

what gets transferred

  1. your lists in Reminders will become projects in Todoist
  2. the reminders within those lists will become items within those newly created projects
    1. priority of these items will be transferred
    2. any notes will be transferred (Todoist premium)

what won't get transferred

  1. reminders by location
  2. an item's repetition

caveats

  1. the due date and remind me date are the same in Apple Reminders (when fetched through AppleScript)

dependencies

  1. your Todoist API token (found in Todoist Settings > Account > API token)

how to run:

  1. open the file in Script Editor.
  2. run dat file (CMD + R).
// todoist api config
var todoistToken = '...';
// get the current application and set it up for scripting
var app = Application.currentApplication();
app.includeStandardAdditions = true;
// get the application object for Reminders and its lists
var reminders = Application('Reminders');
var lists = reminders.lists;
// collect commands in this array
var commands = [];
for (var list in lists) {
var project = lists[list];
var projectId = guid();
// create a Todoist project with the name of the list
commands.push(todoistItemInfo('project_add', {
name: project.name(),
color: list % 11
}, projectId));
for (var x in project.reminders) {
var reminder = project.reminders[x];
// just transfer uncompleted items
if (!reminder.completed()) {
var reminderId = guid();
var args = {
content: reminder.name(),
priority: convertPriority(reminder.priority()),
project_id: projectId // associate the reminder with the new project
};
// create a Todoist item with the reminder info
if (reminder.dueDate()) args.date_string = dateStr(reminder.dueDate());
commands.push(todoistItemInfo('item_add', args, reminderId));
// transfer over reminder note
if (reminder.body()) {
commands.push(todoistItemInfo('note_add', {
item_id: reminderId,
content: reminder.body()
}));
}
// mark as completed
// list.reminders[x].completed.set(true);
}
}
// execute commands (create todoist project + items) with one request, then clean up
if (commands.length) todoistCmd(commands);
commands = [];
}
/**
* converts Reminders priority (9, 5, 1, 0) to Todoist priority (4, 3, 2, 1)
*/
function convertPriority(priority) {
return priority == 1 ? 4 : (priority == 5 ? 3 : (priority == 9 ? 2 : 1));
}
/**
* generate an object to be sent up to the todoist sync API
*/
function todoistItemInfo(type, args, tempId) {
return {
type: type,
uuid: guid(),
temp_id: tempId ? tempId : guid(),
args: args
};
}
/**
* execute todoist commands (todoist api)
*/
function todoistCmd(commands) {
app.doShellScript("curl https://todoist.com/API/v7/sync -d token=" + todoistToken +
" --data-urlencode commands='" + JSON.stringify(commands) + "'");
}
/**
* generate unique random string: http://stackoverflow.com/a/105074/2284993
*/
function guid() {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
return `${s4()}${s4()}-${s4()}-${s4()}-${s4()}-${s4()}${s4()}${s4()}`;
}
/**
* format date object to string (yyyy-mm-ddThh:ii)
*/
function dateStr(date) {
var year = date.getFullYear();
var month = (date.getMonth() < 9 ? '0' : '')+(date.getMonth()+1);
var day = date.getDate();
var hour = (date.getHours() < 10 ? '0' : '')+date.getHours();
var min = (date.getMinutes() < 10 ? '0' : '')+date.getMinutes();
return year+'-'+month+'-'+day+'T'+hour+':'+min;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment