Back

Step by Step Guide to Building a Todoist API Integration in JS

Aug 11, 20246 minute read

Introduction

Hey there, fellow developer! Ready to supercharge your productivity game? Let's dive into building a Todoist API integration using JavaScript. Todoist's API is a powerhouse for task management, and we're about to harness that power. Buckle up!

Prerequisites

Before we jump in, make sure you've got:

  • Node.js and npm installed (you're a pro, so I'm sure you do)
  • A Todoist account and API token (grab it from your Todoist settings)

Setting up the project

Let's get our hands dirty:

mkdir todoist-integration && cd todoist-integration npm init -y npm install axios dotenv

Authentication

First things first, let's keep that API token safe:

// .env TODOIST_API_TOKEN=your_api_token_here // index.js require('dotenv').config(); const axios = require('axios'); const api = axios.create({ baseURL: 'https://api.todoist.com/rest/v2', headers: { Authorization: `Bearer ${process.env.TODOIST_API_TOKEN}` } });

Making API requests

Time to flex those API muscles:

// GET tasks const getTasks = async () => { const response = await api.get('/tasks'); return response.data; }; // POST a new task const createTask = async (content) => { const response = await api.post('/tasks', { content }); return response.data; }; // PUT (update) a task const updateTask = async (id, updates) => { const response = await api.post(`/tasks/${id}`, updates); return response.data; }; // DELETE a task const deleteTask = async (id) => { await api.delete(`/tasks/${id}`); };

Handling responses

Let's keep it clean and handle those responses like a pro:

const handleApiCall = async (apiCall) => { try { const result = await apiCall(); return result; } catch (error) { console.error('API Error:', error.response?.data || error.message); throw error; } }; // Usage const tasks = await handleApiCall(getTasks);

Implementing key features

Now for the fun part - let's build some cool features:

// Fetch projects const getProjects = async () => { return handleApiCall(() => api.get('/projects')); }; // Create task with due date and priority const createDetailedTask = async (content, dueString, priority) => { return handleApiCall(() => api.post('/tasks', { content, due_string: dueString, priority })); }; // Complete a task const completeTask = async (id) => { return handleApiCall(() => api.post(`/tasks/${id}/close`)); }; // Move task to another project const moveTask = async (taskId, projectId) => { return handleApiCall(() => api.post(`/tasks/${taskId}`, { project_id: projectId })); };

Optimizing the integration

Keep an eye on those rate limits, champ! Todoist allows 450 requests per minute, so let's play nice:

const rateLimit = require('axios-rate-limit'); const api = rateLimit(axios.create({ baseURL: 'https://api.todoist.com/rest/v2', headers: { Authorization: `Bearer ${process.env.TODOIST_API_TOKEN}` } }), { maxRequests: 450, perMilliseconds: 60000 });

Testing the integration

Don't forget to test! Here's a quick Jest test to get you started:

// __tests__/api.test.js jest.mock('axios'); test('getTasks fetches tasks successfully', async () => { const mockTasks = [{ id: 1, content: 'Test task' }]; axios.get.mockResolvedValue({ data: mockTasks }); const tasks = await getTasks(); expect(tasks).toEqual(mockTasks); });

Conclusion

And there you have it! You've just built a solid Todoist API integration. You're now equipped to create, manage, and optimize tasks like a true productivity ninja. Remember, this is just the beginning - there's so much more you can do with the Todoist API. Keep exploring and building awesome things!

Resources

Now go forth and conquer those tasks! Happy coding! 🚀