Select a task from Todoist
(configured from tasks assigned to today
) and start a Toggl
-timer for it.
If both, Todoist
and Toggl
have a Project with the same name, that project is automatically linked in the Tracking-Entry.
Even though this script is very opinionated to those two tools, it might inspire you to do something similar with the tools of your choice. 😉
import "@johnlindquist/kit"
import { getTodosOfToday, getProjectById } from '../lib/Todoist';
import { startTimeTrackerFor } from '../lib/Toggl';
const todosToday = await getTodosOfToday();
const selectedTodo = await arg(
'Select Todo to start',
todosToday.map((todo) => ({
name: todo.content,
value: todo
})
));
let projectName;
if(selectedTodo.project_id) {
const project = await getProjectById(selectedTodo.project_id);
projectName = project.name;
}
const result = await startTimeTrackerFor({
description: selectedTodo.content,
projectName
});
await notify({
title: 'Tracking Started.',
message: `Started Tracking for ${result.description}.`
});
As I am planing to write some more actions for Todoist as well as Toggl, I externalized accessing them into two modules (might put them into own npm modules when I have the time):
../lib/Todoist.ts
:
import "@johnlindquist/kit"
const axios = await npm('axios');
const todoistApiToken = await env('TODOIST_API_TOKEN');
type TodoistTask = {
id: number,
project_id: number,
content: string,
};
type TodoistProject = {
id: number,
name: string,
};
const getTodosOfToday = async (): Promise<TodoistTask[]> => {
const response = await axios({
method: 'GET',
url: 'https://api.todoist.com/rest/v1/tasks?filter=today',
headers: {
'Authorization': `Bearer ${todoistApiToken}`
}
});
return response.data;
};
const getProjectById = async (id: number): Promise<TodoistProject> => {
const response = await axios({
method: 'GET',
url: `https://api.todoist.com/rest/v1/projects/${id}`,
headers: {
'Authorization': `Bearer ${todoistApiToken}`
}
});
return response.data;
};
export {
getTodosOfToday,
getProjectById
};
../lib/Toggl.ts
import "@johnlindquist/kit"
const axios = await npm('axios');
const togglApiToken = await env('TOGGL_API_TOKEN');
const togglWorkspaceId = await env('TOGGL_WORKSPACE_ID');
const auth = {
username: togglApiToken,
password: 'api_token'
};
type TimeEntry = {
id: number,
description: string,
};
type TogglProject = {
id: number,
name: string,
}
const getProjectByName = async(name: string): Promise<TogglProject | undefined> => {
const response = await axios({
method: 'GET',
url: `https://api.track.toggl.com/api/v8/workspaces/${togglWorkspaceId}/projects`,
auth
});
return response.data.find((project: TogglProject): boolean => project.name === name)
}
const startTimeTrackerFor = async (
{description, projectName}: { description: string, projectName?: string}
): Promise<TimeEntry> => {
let projectId;
if(projectName) {
const project = await getProjectByName(projectName);
projectId = project.id;
}
const response = await axios({
method: 'POST',
url: 'https://api.track.toggl.com/api/v8/time_entries/start',
data: {
time_entry: {
description,
pid: projectId,
created_with: 'script-kit'
}
},
auth
});
return response.data.data;
}
export {
startTimeTrackerFor
};
export {
startTimeTrackerFor
};