Skip to content

Instantly share code, notes, and snippets.

@marcantoine
Last active June 13, 2022 08:15
Show Gist options
  • Save marcantoine/bedbb41189a8384b9ecf635fbd5fa67b to your computer and use it in GitHub Desktop.
Save marcantoine/bedbb41189a8384b9ecf635fbd5fa67b to your computer and use it in GitHub Desktop.
showMetabaseQuestiontAsiOSWidget.js
// 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()
@marcantoine
Copy link
Author

Thank you @0xcaff, It makes senses, I’ve updated the gist !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment