Skip to content

Instantly share code, notes, and snippets.

@ericbolikowski
Created October 23, 2023 17:01
Show Gist options
  • Save ericbolikowski/e6a946845053071be6f80447b9c96d4c to your computer and use it in GitHub Desktop.
Save ericbolikowski/e6a946845053071be6f80447b9c96d4c to your computer and use it in GitHub Desktop.
Query Todoist tasks, then update due-date and not-before-date in bulk
const axios = require('axios');
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
const question = (prompt) => new Promise((resolve) => rl.question(prompt, resolve));
const TODOIST_API_TOKEN = 'YOUR_TOKEN'; // Replace this with your token
const API_ENDPOINT = 'https://api.todoist.com/rest/v2/tasks';
async function fetchTasks(query) {
const response = await axios.get(API_ENDPOINT, {
headers: {
Authorization: `Bearer ${TODOIST_API_TOKEN}`
},
params: {
filter: query
}
});
return response.data;
}
async function updateTask(task, days, notBeforeDays) {
if (task.due) {
const dueDate = new Date(task.due.date);
dueDate.setDate(dueDate.getDate() + days);
task.due.date = dueDate.toISOString().split('T')[0];
}
const notBeforeRegex = /(notbefore:\s*\d+\s*\w+(\s*\d{4})?)/i;
const match = task.content.match(notBeforeRegex);
if (match) {
let [_, dateStr] = match;
dateStr = dateStr.replace('notbefore:', '').trim();
const parts = dateStr.split(' ');
const day = parseInt(parts[0]);
const month = parts[1];
const year = parts[2] || new Date().getFullYear();
const notBeforeDate = new Date(`${month} ${day}, ${year}`);
notBeforeDate.setDate(notBeforeDate.getDate() + notBeforeDays);
task.content = task.content.replace(notBeforeRegex, `notbefore: ${notBeforeDate.getDate()} ${notBeforeDate.toLocaleString('default', { month: 'long' })} ${notBeforeDate.getFullYear()}`);
}
await axios.post(`${API_ENDPOINT}/${task.id}`, {
due_date: task.due.date,
content: task.content,
}, {
headers: {
Authorization: `Bearer ${TODOIST_API_TOKEN}`
}
});
console.log(`Updated Task: ${task.content}`);
}
async function main() {
const query = await question("Query?\n")
const tasks = await fetchTasks(query);
tasks.forEach(task => console.log(task.content));
console.log(`\nTotal of ${tasks.length}\n`)
const proceedAnswer = await question('Proceed with the above tasks? (yes/no) ');
if (proceedAnswer.toLowerCase() !== 'yes') {
console.log('Aborted!');
rl.close();
return;
}
const days = parseInt(await question('By how many days do you want to extend the deadline? '));
const notBeforeDays = parseInt(await question('By how many days do you want to move the "not before" date? '));
for (const task of tasks) {
await updateTask(task, days, notBeforeDays);
}
console.log('Tasks updated successfully.');
rl.close();
}
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment