Last active
December 23, 2023 15:39
-
-
Save alex-streza/dac4218bc2dc8962bbd5932abd69851c to your computer and use it in GitHub Desktop.
Script.kit compatible JS script to fetch Toggl time entries via the official API, organizing data into a monthly CSV timesheet.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Name: Export Toggl Entries to CSV | |
import "@johnlindquist/kit"; | |
const jsonexport = await npm("jsonexport"); | |
const API_URL = await env("API_URL"); | |
const EMAIL = await env("EMAIL"); | |
const PASSWORD = await env("PASSWORD"); | |
const OUTPUT_PATH = await env("OUTPUT_PATH"); | |
const NAME = await env("NAME"); | |
const config = { | |
auth: { | |
username: EMAIL, | |
password: PASSWORD, | |
}, | |
headers: { | |
"Content-Type": "application/json", | |
}, | |
}; | |
const months = [ | |
"january", | |
"february", | |
"march", | |
"april", | |
"may", | |
"june", | |
"july", | |
"august", | |
"september", | |
"october", | |
"november", | |
"december", | |
]; | |
const getStartEndMonthDates = () => { | |
const today = new Date(); | |
const firstDay = new Date(today.getFullYear(), today.getMonth(), 1); | |
const lastDay = new Date(today.getFullYear(), today.getMonth() + 1, 0); | |
return [firstDay, lastDay]; | |
}; | |
const getHoursBetweenDates = (start, end) => { | |
const diff = end.getTime() - start.getTime(); | |
return diff / (1000 * 60 * 60); | |
}; | |
try { | |
const [start] = getStartEndMonthDates(); | |
const currentMonth = months[start.getMonth()]; | |
const projectsResponse = await get(API_URL + "/projects", config); | |
const projects = projectsResponse.data; | |
const entriesResponse = await get(API_URL + `/time_entries?since=${Math.floor(start.getTime() / 1000)}`, config); | |
const entries = []; | |
for (const entry of entriesResponse.data.reverse()) { | |
const { start, stop, description, pid } = entry; | |
const project = projects.filter((project) => project.id === pid); | |
entries.push({ | |
date: start.split("T")[0].split("-").reverse().join("/"), | |
project: project.length > 0 ? project[0].name : "Unknown", | |
person: NAME, | |
task: description, | |
hours: getHoursBetweenDates(new Date(start), new Date(stop)), | |
}); | |
} | |
jsonexport(entries, async (err, csv) => { | |
if (err) return console.error(err); | |
let filePath = await path(OUTPUT_PATH + "\\" + currentMonth + ".csv"); | |
await writeFile(filePath, csv); | |
}); | |
} catch (e) { | |
console.log(e); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment