Created
October 22, 2020 12:28
-
-
Save aaronbushnell/9ee4e3837cc52f0ae2c4a117875b215b to your computer and use it in GitHub Desktop.
Display your tracked time within Harvest in a Scriptable widget
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
// Variables used by Scriptable. | |
// These must be at the very top of the file. Do not edit. | |
// icon-color: red; icon-glyph: stopwatch; | |
// Variables used by Scriptable. | |
// These must be at the very top of the file. Do not edit. | |
// icon-color: orange; icon-glyph: magic; | |
const HARVEST_ACCOUNT_ID = ""; | |
const HARVEST_API_KEY = ""; | |
const HARVEST_USER_ID = ""; | |
// Get times and insert into widget | |
let {todayTime, weekTime} = await getEntries(); | |
let widget = await createWidget(todayTime, weekTime); | |
// Check if the script is running in | |
// a widget. If not, show a preview of | |
// the widget to easier debug it. | |
if (!config.runsInWidget) { | |
await widget.presentMedium(); | |
} | |
// Tell the system to show the widget. | |
Script.setWidget(widget); | |
Script.complete(); | |
/** | |
* Construct a widget using the fetched times from Harvest | |
*/ | |
async function createWidget(todayTime, weekTime) { | |
let w = new ListWidget(); | |
w.setPadding(4, 20, 0, 20) | |
let logoReq = new Request("https://www.getharvest.com/assets/press/harvest-logo-icon-aea5eea5a1905ec4fe999116981098fb63ef9bfd95bccc3cba442d531864819f.png") | |
let logoFile = await logoReq.loadImage() | |
let logo = w.addImage(logoFile) | |
logo.imageSize = new Size(20, 20) | |
logo.rightAlignImage() | |
w.backgroundColor = new Color("#1c1c1e"); | |
// Add heading to top of today's hours | |
let heading = w.addText("Today"); | |
heading.font = Font.systemFont(12); | |
heading.textColor = new Color("#999"); | |
// Insert time for today hours | |
let today = w.addText(todayTime); | |
today.font = Font.boldSystemFont(30); | |
today.textColor = new Color("#fff") | |
w.addSpacer(8); | |
// Add heading to top of week's hours | |
let totals = w.addText("This Week"); | |
totals.font = Font.systemFont(12); | |
totals.textColor = new Color("#999"); | |
// Insert time for week's hours | |
let week = w.addText(weekTime); | |
week.font = Font.boldSystemFont(30); | |
week.textColor = new Color("#fff") | |
return w; | |
} | |
/** | |
* Formats a date in YYYY-MM-DD format | |
*/ | |
function formatDate(date) { | |
const d = new Date(date), | |
month = '' + (d.getMonth() + 1), | |
day = '' + d.getDate(), | |
year = d.getFullYear(); | |
if (month.length < 2) { | |
month = '0' + month; | |
} | |
if (day.length < 2) { | |
day = '0' + day; | |
} | |
return [year, month, day].join('-'); | |
} | |
/** | |
* Get logged time from Harvest API | |
*/ | |
async function getEntries() { | |
const headers = { | |
"Harvest-Account-ID": `${HARVEST_ACCOUNT_ID}`, | |
"Authorization": `Bearer ${HARVEST_API_KEY}`, | |
}; | |
// Get dates required for our API request | |
const current = new Date; | |
const first = current.getDate() - current.getDay(); | |
const last = first + 6; | |
const firstDate = new Date(current.setDate(first)); | |
const lastDate = new Date(current.setDate(last)); | |
const dates = { | |
"weekStart": formatDate(firstDate), | |
"weekEnd": formatDate(lastDate), | |
"today": formatDate(new Date()), | |
}; | |
let req = new Request(`https://api.harvestapp.com/api/v2/time_entries?from=${dates.weekStart}&to=${dates.weekEnd}&user_id=${HARVEST_USER_ID}`); | |
req.headers = headers; | |
const data = await req.loadJSON(); | |
const times = data.time_entries; | |
const hours = { | |
todayTime: 0, | |
weekTime: 0, | |
}; | |
for (let i = 0; i < times.length; i++) { | |
if (times[i].spent_date === dates.today) { | |
hours.todayTime += times[i].hours; | |
} | |
hours.weekTime += times[i].hours; | |
} | |
hours.todayTime = hours.todayTime.toFixed(2); | |
hours.weekTime = hours.weekTime.toFixed(2); | |
return hours; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment