Using the Todoist REST API with Drafts

I’ve had some success connecting the Todoist REST API to Drafts 5. I’ve now got a script up and running that populates a prompt with a list of Todoist projects which allows me, for instance, to pick which project I add a new task to, rather than everything going in the inbox.

This is the http.request statement (where token is my Todoist token, which I get using the credential module):
var http = HTTP.create(); //create HTML object
var response = http.request({“url”:“https://beta.todoist.com/API/v8/projects","method”: “GET”, “headers”:{“Authorization”: "Bearer "+token}})

One of the best features of the REST API is that you can filter your list of tasks by adding parameters to the statement. I’ve got this working in Pythonista, but can’t work out how to do this in JavaScript in Drafts.

An example of the statement using requests in Python is given below - I just need to know how to pass the “params” element of the request in http.request:
tasks = requests.get(“https://beta.todoist.com/API/v8/tasks",params=parameters,headers={"Authorization”: “Bearer %s” % token}).json()

Where e.g. parameters = {‘project_id’:12345}

I’ve tried the params element within both the data and the headers part of the http.request statement in Drafts, but I’m getting a 403 error. Is there a way to pass something that is neither “data” nor “headers”.

Thanks in advance.

1 Like

The data value would typically be used to pass data with a POST type HTTP request. If it’s looking for parameters on a GET request, those would typically be encoded into the URL arguments. There is not a separate object to pass for those, they should be part of the URL used for the request. So your URL passed the request would be:

https://beta.todoist.com/API/v8/tasks?project_id=12345

This is untested, but that would be my guess as to what they are looking for.

Thanks. Brilliant - that works for the project ID.

var response = http.request({“url”:“https://beta.todoist.com/API/v8/tasks?project_id=132171147","method”: “GET”,“headers”:{“Authorization”: "Bearer "+token}})

Would you like to share your Todoist script with us?

Thanks.

This is what I’ve got so far for the projects selector - gets a projects list from Todoist, populates a prompt and then will allow me to take action on the selected project. At the moment the actions are done through Pythonista, but I’m in the process of converting that.

The aim is to get to a point where I can do most things I want to do with Todoist from Drafts so I don’t have to lose my focus.

Once I’ve finished I’ll add to the action directory.

// Sort out credentials
var credential = Credential.create("Todoist token", "Todoist API");
credential.addTextField("username", "Username");
credential.addPasswordField("password", "Password");
credential.authorize();

//Get token
var token = credential.getValue("password")

// grab text
const currentContent = draft.content.trim();

//Choose Action
action_list =["New project", "Open Project", "Copy Project ID","Add project note","Update meetings list","Change status", "Add default notes"]

var p2 = Prompt.create();
p2.title = "Select action";
for (var action of action_list) {
p2.addButton(action);
}

var ActionSelect = p2.show();
var actionSelected = p2.buttonPressed;

//Get Todoist Data
var http = HTTP.create(); //create HTML object
var response = http.request({"url":"https://beta.todoist.com/API/v8/projects","method": "GET", "headers":{"Authorization": "Bearer "+token}})

if (response.success) {
	var text = response.responseText;
	console.log(text)
	projects = JSON.parse(text)
}
else {
	console.log(response.statusCode);
	console.log(response.error);
}
var prompt_text = [];
for (var i = 0; i < projects.length; i++) {
	prompt_text.push(projects[i].name);
}

var p = Prompt.create();
p.title = "Select project";
for (var project of prompt_text) {
p.addButton(project);
}

var pSelect = p.show();

var projectSelected = p.buttonPressed;

for (var i = 0; i < projects.length; i++) {
	console.log(projects[i].name)
	if (projects[i].name == projectSelected) {
		var project_id = projects[i].id;
	}
}

actionSelected = encodeURIComponent(actionSelected)
textToAdd = encodeURIComponent(currentContent)

var url= "pythonista://Todoist/td_project_actions?action=run&argv=" + project_id + "&argv="+actionSelected+"&argv="+textToAdd
console.log(url)
var result = app.openURL(url);
3 Likes

Moggy, thanks very much. Looking forward to you adding this to the action directory.

Can you please explain how obtaining the token using Credential works?

I’m rather new to this, but to me it looks like this code is using the user’s password as a token?

(I’m asking because I want to properly obtain a token for Remember The Milk and might learn from your code how to do that)

I don’t really understand how it works, it just does. I just copied the example from the website.

Basically first time it runs it will ask you for the relevant password/token etc, after this, it will find the password so you don’t have to enter it again.

It should work for other similar applications.

@moggy1972 Thanks!

I believe Remember The Milk authorisation works differently (the user has to perform a manual action at a specific URL), so I guess I just need to start experimenting.