Who doesn’t love checking their sales numbers a million times per day
I thought it would be nicer as a widget in my local currency…
Here’s how to set it up:
- Use at your own risk! (obviously)
- Install this free app: https://scriptable.app
- In the marketplace dashboard create a new user with
view sales reports
permissions. - Create an API key for that user; ensuring it is the correct user.
- Open the Scriptable app, paste this code and edit to suit.
- Add the Scriptable widget to your iPhone homescreen and connect the script.
const EMAIL = "";
const API_KEY = "";
const VENDOR_ID = "";
const CURRENCY = "AUD";
const BACKGROUND = "#202123";
// get exchange rate
const rate = await get({
url: `https://api.exchangerate.host/latest?symbols=${CURRENCY}&base=USD`,
});
// get sales data
let sales = {},
totalMonth = 0,
totalAll = 0;
sales = await fetchSalesMonth();
sales.total.series.forEach((hosting) =>
hosting.elements.forEach((sale) => (totalMonth += sale.revenue))
);
totalMonth = totalMonth * rate.rates[CURRENCY];
sales = await fetchSalesAll();
sales.total.series.forEach((hosting) =>
hosting.elements.forEach((sale) => (totalAll += sale.revenue))
);
totalAll = totalAll * rate.rates[CURRENCY];
// create widget
const widget = new ListWidget();
widget.backgroundColor = new Color(BACKGROUND);
const stack = widget.addStack();
stack.layoutVertically();
stack.centerAlignContent();
const titleMonth = stack.addText("SALES");
titleMonth.textColor = Color.gray();
titleMonth.font = new Font("Helvetica", 12);
const textMonth = stack.addText(
"$" + totalMonth.toLocaleString(undefined, { maximumFractionDigits: 0 })
);
textMonth.textColor = Color.white();
textMonth.font = new Font("Helvetica", 28);
stack.addSpacer(10);
const titleAll = stack.addText("ALL TIME");
titleAll.textColor = Color.gray();
titleAll.font = new Font("Helvetica", 12);
const textAll = stack.addText(
"$" + totalAll.toLocaleString(undefined, { maximumFractionDigits: 0 })
);
textAll.textColor = Color.white();
textAll.font = new Font("Helvetica", 28);
Script.setWidget(widget);
Script.complete();
widget.presentSmall();
// functions
async function fetchSalesMonth() {
const now = new Date();
const start = formatDate(new Date(now.getFullYear(), now.getMonth(), 1));
const end = formatDate(now);
return await get({
url: `https://marketplace.atlassian.com/rest/2/vendors/${VENDOR_ID}/reporting/sales/transactions/hosting?startDate=${start}&endDate=${end}`,
headers: { Authorization: `Basic ${btoa(`${EMAIL}:${API_KEY}`)}` },
});
}
async function fetchSalesAll() {
return await get({
url: `https://marketplace.atlassian.com/rest/2/vendors/${VENDOR_ID}/reporting/sales/transactions/hosting?aggregation=month`,
headers: { Authorization: `Basic ${btoa(`${EMAIL}:${API_KEY}`)}` },
});
}
async function get(opts) {
const request = new Request(opts.url);
request.headers = {
...opts.headers,
...this.defaultHeaders,
};
var result = await request.loadJSON();
return result;
}
function formatDate(date) {
var 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("-");
}