I wanted to share a quick experiment I tried last night with the Todoist REST API and GPT action integration. I’ve created a repository to track my progress, and I’m hoping this sparks some interest and maybe somone else can fork it and push it forward. You can find the repo on github hcal/todoistgpt
What Works:
- Listing Projects
- Listing Tasks
- Listing Tasks for a Specific Project (GPT does this by listing everything and filtering it itself, I think)
- Adding a new task
- Nothing much… There’s still plenty of room for improvement and expansion.
** How to set it up **
I started by logging into Todoist and generating an API token through the settings menu. Then, I created a new GPT model and added actions using YAML schemas along with the API Key (Bearer type).
Here are my initial GPT instructions, but I haven’t put a lot of effort into refining them yet:
Role and Goal: Hannah The Task Manager acts as a direct and helpful project manager, offering clear, concise advice on tasks and projects, with a focus on efficiency and forward-thinking. Be the EXPERT or EXPERTS most qualified to provide authoritative, nuanced answers.
Constraints: Hannah prioritizes specific guidance and timelines, avoiding vague responses.
Clarification: She makes educated guesses as suggestions but leaves final decisions to the user.
Personalization: Hannah starts conversations in a friendly manner but maintains brevity in her responses. She avoids overwhelming users with unnecessary details like task IDs or creation dates unless specifically requested.
Additional Note: If the user asks what to do, or any needed information to answer their questions isn’t available, check their tasks before answering.
The YAML
{
"openapi": "3.0.0",
"info": {
"version": "1.0.0",
"title": "Todoist API",
"license": {
"name": "MIT"
}
},
"servers": [
{
"url": "https://api.todoist.com/rest/v2"
}
],
"paths": {
"/projects": {
"get": {
"summary": "Get all projects",
"operationId": "getAllProjects",
"tags": [
"projects"
],
"responses": {
"200": {
"description": "An array of projects",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Projects"
}
}
}
},
"default": {
"description": "unexpected error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/tasks": {
"get": {
"summary": "Get active tasks",
"operationId": "getActiveTasks",
"tags": [
"tasks"
],
"parameters": [
{
"name": "projectId",
"in": "query",
"description": "The id of the project to retrieve tasks for",
"required": false,
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "An array of active tasks",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Tasks"
}
}
}
},
"default": {
"description": "unexpected error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"post": {
"summary": "Create a new task",
"operationId": "createTask",
"tags": [
"tasks"
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/NewTask"
}
}
}
},
"responses": {
"200": {
"description": "Task successfully created",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Task"
}
}
}
},
"default": {
"description": "unexpected error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"Project": {
"type": "object",
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
}
},
"Projects": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Project"
}
},
"Task": {
"type": "object",
"required": [
"id",
"content"
],
"properties": {
"id": {
"type": "integer"
},
"content": {
"type": "string"
}
}
},
"Tasks": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Task"
}
},
"NewTask": {
"type": "object",
"required": [
"content"
],
"properties": {
"content": {
"type": "string"
},
"projectId": {
"type": "integer",
"description": "The id of the project to which the task belongs"
}
}
},
"Error": {
"type": "object",
"required": [
"code",
"message"
],
"properties": {
"code": {
"type": "integer",
"format": "int32"
},
"message": {
"type": "string"
}
}
}
}
}
}