Last active
June 13, 2022 08:15
-
-
Save marcantoine/bedbb41189a8384b9ecf635fbd5fa67b to your computer and use it in GitHub Desktop.
showMetabaseQuestiontAsiOSWidget.js
This file contains 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
// Modified from @mutsuda's https://medium.com/@mutsuda/create-an-ios-widget-showing-google-spreadsheets-data-856767a9447e | |
// and @levelsio's https://gist.github.com/levelsio/a1ca0dd434b77ef26f6a7c403beff4d0 | |
// HOW TO | |
// 1) Make a new Metabase Question | |
// 2) Make the result an unique number and choose Visualization > Number | |
// 3) Write your metabase domain, your email and password below | |
const domain = "https://metabase.endpoint.com" | |
const username = "[email protected]" | |
const password = "p@ssw0rd" | |
// 4) copy the id of the question below. The ID can be found in the url of the question /question/42 | |
const question = '42' | |
// 5) Install Scriptable @ https://apps.apple.com/us/app/scriptable/id1405459188 | |
// 6) Copy this entire script in to Scriptable (tip: you can send it to your iPhone via Whatsapp/Messenger/Telegram etc) | |
// 7) Add a widget on your Home screen, choose scriptable and select your new script. | |
// 8) Style the widget - you can change the text font / size / color, the background, and also add image using base64 | |
// function to connect to metabase with email and password | |
async function getSessionId() { | |
let req = new Request(domain+'/api/session') | |
req.method = "POST" | |
req.headers = { 'Content-Type': 'application/json'} | |
req.body = JSON.stringify({username, password}) | |
let res = await req.loadJSON() | |
return res.id | |
} | |
// function to retrieve data from a Question based on its number | |
async function getCardData(card, id){ | |
let req = new Request(endpoint+'/api/card/'+card+'/query') | |
req.method = 'POST' | |
req.headers = { 'X-Metabase-Session': id} | |
req.body = {ignore_caches: true, parameters: []} | |
let res = await req.loadJSON() | |
return res.data.rows[0][0]; | |
} | |
const id = await getSessionId() // we get the session id | |
const data = await getCardData(question,id) // we get the result from question 42 | |
const value = data.toLocaleString() // transform the number in a nice locale string | |
let w = new ListWidget() // Create the widget | |
w.backgroundColor = new Color("#132660") | |
w.url= "https://url.com" // an url to open on click | |
t = w.addText(`${value} €`) // Add the value to the widget | |
t.textColor = new Color("#ffffff") | |
t.font = new Font("AvenirNext-DemiBold",42) | |
// add a small subtext | |
t2 = w.addText(`Invested this month`) | |
t2.textColor = new Color("#F0F3F8") | |
t2.font = new Font("AvenirNext-DemiBold",14) | |
// add a small spacer | |
s = w.addSpacer(8) | |
// load an image from base64 to Data | |
let dataImg = Data.fromBase64String("iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAIOSURBVHgBxdHLaxNRGAXwM4/m0Yl5mUdtHrZUqiDEtgsRdOEDrSDqVgS7VQqC/gOiuFHpQhA3It24UAsq7cqAgq1QF5WCVEqCaUPrNJiMmUwmM8nM5E7GGaVZqCs3fovLdw/8uAcu8I9D/R7M3b+UZol4l2aY4xTFmKDop5oVunf+2uPyX+HazJ3Aejk32mlXngXC8bhnRwxWx4TWqKAuCisWopOZvYeXE2cvN7tw4dHEsPyVzKtUuS89OAhXbwhcMAaTGDCaMlqKgM1CCW7Su8UlgwdPXZ0u0Q6sCO0LIW+qjwvHEd49asMIZEmCorTAekIIJUfg4nyI+Ib6RbF2zDE/oU65P25UixgeOwpvIAqaoWF5/CC0Cz0uN3zxNPaMHMKmyEM3e0pdKPHqghlki95wAgznR1OtY8CunEyn0CZtMB4ffLEURLb1eeLW83eOYZ1j8uGM+uD6CeND9gV2JVIwNR08z4O0CRoCj3JVglQtQ6pJPEVRVvdF5/JNVPPrX1YxOzsH2ejANDQQokNUOnibfY3c6gpqivFp+xfY7UWqt54MJSPn1vgGtvgqXk29Acux2D++DzW5hXR/1BJk8vIPGPQzYw1VhyA2sxRN4+KNMyftuLm0XFj8Lmle07SOoCNn7GypW/XXQu20Ub5aV29fuTl9urChHMgV5czi/PtxVdOn7EZ5N0sP4L/NDz4x4196PfxhAAAAAElFTkSuQmCC"); | |
let img = Image.fromData(dataImg) // Use the data to create an image | |
let image = w.addImage(img) | |
// align everyting | |
t2.centerAlignText() | |
t.centerAlignText() | |
image.centerAlignImage(); | |
image.imageSize = new Size(20,20) | |
Script.setWidget(w) | |
Script.complete() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you @0xcaff, It makes senses, I’ve updated the gist !