Skip to content

Instantly share code, notes, and snippets.

@aaronbushnell
Created October 22, 2020 12:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aaronbushnell/9ee4e3837cc52f0ae2c4a117875b215b to your computer and use it in GitHub Desktop.
Save aaronbushnell/9ee4e3837cc52f0ae2c4a117875b215b to your computer and use it in GitHub Desktop.
Display your tracked time within Harvest in a Scriptable widget
// 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