Skip to content

Instantly share code, notes, and snippets.

@carlosefonseca
Last active November 8, 2021 12:26
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save carlosefonseca/39509a675b8af6bbd2bc0c13cdee515d to your computer and use it in GitHub Desktop.
Save carlosefonseca/39509a675b8af6bbd2bc0c13cdee515d to your computer and use it in GitHub Desktop.
iOS Home Screen Widget for Scriptable (https://scriptable.app) displaying the amount on a Prize Card and a Dá Card.
// Variables used by Scriptable.
// These must be at the very top of the file. Do not edit.
// icon-color: cyan; icon-glyph: wallet;
// Card Number
const prizeCardAmount = (await prizeCard("1234567890123456")).amount
// Username, Password, Date
const daCardAmount = (await daCard("username", "password", "31081980"))
async function prizeCard(cardNumber) {
// login with username & password
const request1 = new Request("https://hbprepagos.unicre.pt")
request1.method = "POST"
request1.addParameterToMultipart("User", cardNumber)
request1.addParameterToMultipart("Password", cardNumber.slice(-7))
await request1.loadString()
// request the page with the balance using the login cookies
const request2 = new Request('https://hbprepagos.unicre.pt/area-cliente')
request2.headers = { cookie: request1.response.cookies }
// returns the page with the balance
const html = await request2.loadString()
// find and return the balance amount
const match = html.match(/[\d\.]+€/g)
const value = match[0]
return {
card: cardNumber,
amount: parseFloat(value)
}
}
function dict2Array(dict, transform) {
const result = []
for (k in dict) { result.push(transform(k, dict[k])) }
return result
}
async function daCard(username, password, date) {
// login with username & password
const request1 = new Request("https://sites.prepaytec.com/chopinweb/scareMyLogin.do?loc=pt")
request1.method = "POST"
const bodyData1 = {
'page': '1',
'customerCode': '19151415',
'agentCode': '',
'username': username,
'password': password,
'submit.x': '81',
'submit.y': '8'
}
request1.body = dict2Array(bodyData1, (k, v) => `${k}=${v}`).join("&")
request1.headers = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Content-Type': 'application/x-www-form-urlencoded',
'Origin': 'https://sites.prepaytec.com',
'Accept-Language': 'en-us',
'Host': 'sites.prepaytec.com',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.1 Safari/605.1.15',
'Referer': 'https://sites.prepaytec.com/chopinweb/scareMyLogin.do?customerCode=19151415&loc=pt&brandingCode=myscare_pt&org.apache.catalina.filters.CSRF_NONCE=614F4605624AECCF95FD612B646B472A',
}
// login returns html asking for 3 digits in arbitrary positions
const html = await request1.loadString()
// find the requested numbers
const results = html.matchAll(/    ([DMA])    |input type="password" .*? name="(.*?)"/g)
const capturedGroups = Array.from(results).map(([_, a, b]) => a || b)
const requestedIndexes = capturedGroups.map((v, i) => v.startsWith("security") ? i : null).filter(x => x !== null)
const secrets = requestedIndexes.map(x => date.charAt(x))
// send the requested digits and the login cookies
const request2 = new Request('https://sites.prepaytec.com/chopinweb/scareMyLogin.do?loc=pt')
request2.method = "POST"
const bodyData2 = {
'page': '2',
'customerCode': '19151415',
'agentCode': '',
'securityDigit1': secrets[0],
'securityDigit2': secrets[1],
'securityDigit3': secrets[2],
'submit.x': '74',
'submit.y': '11'
}
request2.body = dict2Array(bodyData2, (k, v) => `${k}=${v}`).join("&")
request2.headers = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Content-Type': 'application/x-www-form-urlencoded',
'Origin': 'https://sites.prepaytec.com',
'Accept-Language': 'en-us',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.1 Safari/605.1.15',
'Referer': 'https://sites.prepaytec.com/chopinweb/scareMyLogin.do?loc=pt',
'Accept-Encoding': 'gzip, deflate, br',
'Connection': 'keep-alive',
'cookies': request1.cookies
}
// the request will cause a couple redirects
request2.onRedirect = (req) => { return req }
// returns the page with the balance
const response2 = await request2.loadString()
// find and return the balance amount
const results2 = response2.match(/€ ([\d,]+)/)
return parseFloat(results2[1].replace(",", "."))
}
// CREATE WIDGET
const widget = new ListWidget()
// PRIZE title
const t1 = widget.addText("Prize")
t1.font = Font.boldRoundedSystemFont(20)
t1.textColor = new Color("FFF")
t1.textOpacity = 0.8
// PRIZE amount
const t2 = widget.addText(`${prizeCardAmount.toFixed(2)}€`)
t2.font = Font.boldRoundedSystemFont(20)
t2.textOpacity = 0.6
t2.rightAlignText()
widget.addSpacer(20)
// DÁ title
const t3 = widget.addText("Dá")
t3.font = Font.boldRoundedSystemFont(20)
t3.textColor = new Color("FFF")
t3.textOpacity = 0.8
// DÁ amount
const t4 = widget.addText(`${daCardAmount.toFixed(2)}€`)
t4.font = Font.boldRoundedSystemFont(20)
t4.textOpacity = 0.6
t4.rightAlignText()
// Background
const gradient = new LinearGradient()
gradient.colors = [new Color("6dd5ed"), new Color("2193b0")]
gradient.locations = [0, 1]
widget.backgroundGradient = gradient
if (config.runsInWidget) {
Script.setWidget(widget)
} else {
widget.presentSmall()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment