Last active
February 20, 2021 22:15
-
-
Save tristankenney/5cfd024b8eac0b3f79a10b7295e5c17d to your computer and use it in GitHub Desktop.
Up Bank + Google Sheets = ❤️
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
const UP_ACCOUNTS = "https://api.up.com.au/api/v1/accounts"; | |
const UP_TRANSACTIONS = (accountId, params) => | |
`https://api.up.com.au/api/v1/accounts/${accountId}/transactions?${params}`; | |
/** | |
* Retrieves a list of accounts from Up bank account | |
* | |
* @param {string} token Up API token | |
* @param {bool} [includeSavers=true] Include savers accounts | |
* @return list of accounts | |
* @customfunction | |
*/ | |
function UpAccounts(token, includeSavers = true) { | |
const accounts = fetch(UP_ACCOUNTS, token); | |
const accountFilter = (account) => | |
includeSavers || account.attributes.accountType !== "SAVER"; | |
const accountMap = (account) => { | |
return [ | |
account.id, | |
account.attributes.displayName, | |
account.attributes.accountType, | |
parseFloat(account.attributes.balance.value), | |
]; | |
}; | |
return [["Account ID", "Name", "Type", "Balance"]].concat( | |
accounts.data.filter(accountFilter).map(accountMap) | |
); | |
} | |
/** | |
* Retrieves a list of transactions from Up bank account | |
* | |
* @param {string} token Up API token | |
* @param {string} accountId account to retrieve transactions from | |
* @param {Date} since | |
* @param {Date} until | |
* @param {string|Array<string>|Array<Array<string>>} transactionTypes=['Transaction', 'Quick save', 'Cover', 'Transfer', 'Funding', 'Forward'] included transactions | |
* @param {boolean} includeRaw=false include raw JSON | |
* @return list of transactions' | |
* @customfunction | |
*/ | |
function UpTransactions( | |
token, | |
accountId, | |
since = null, | |
until = null, | |
transactionTypes = [ | |
"Transaction", | |
"Quick save", | |
"Cover", | |
"Transfer", | |
"Funding", | |
"Forward", | |
], | |
includeRaw = false | |
) { | |
transactionTypes = | |
typeof transactionTypes === "string" | |
? transactionTypes.split(",") | |
: transactionTypes; | |
transactionTypes = Array.isArray(transactionTypes) | |
? transactionTypes.flat() | |
: [transactionTypes]; | |
const params = { | |
"page[size]": () => 100, | |
"filter[since]": () => (since instanceof Date ? since.toISOString() : null), | |
"filter[until]": () => (until instanceof Date ? until.toISOString() : null), | |
}; | |
const encodedParams = Object.entries(params) | |
.filter(([key, value]) => value()) | |
.map(([key, value]) => { | |
return `${encodeURIComponent(key)}=${encodeURIComponent(value())}`; | |
}) | |
.join("&"); | |
const getTransactionType = (transaction) => { | |
const description = transaction.attributes.description; | |
const rawText = transaction.attributes.rawText; | |
const amount = transaction.attributes.amount; | |
const relationships = transaction.relationships; | |
const types = { | |
Cover: () => description.startsWith("Cover from"), | |
Transfer: () => | |
description.startsWith("Transfer from") || | |
description.startsWith("Transfer to"), | |
Forward: () => description.startsWith("Forward to"), | |
"Quick save": () => description.startsWith("Quick save"), | |
Funding: () => | |
amount.valueInBaseUnits > 0 && | |
relationships.category.data === null && | |
description != rawText, | |
Transaction: () => true, | |
}; | |
return Object.entries(types) | |
.find(([type, test]) => test()) | |
.shift(); | |
}; | |
const transactionFilter = (transaction) => | |
transactionTypes.includes(getTransactionType(transaction)); | |
const transactionMap = (transaction) => { | |
const attributes = transaction.attributes; | |
const roundUpValue = attributes.roundUp | |
? attributes.roundUp.amount.value | |
: 0; | |
const mappedTransaction = [ | |
attributes.createdAt, | |
attributes.description, | |
getTransactionType(transaction), | |
parseFloat(attributes.amount.value), | |
parseFloat(roundUpValue), | |
parseFloat(attributes.amount.value) + parseFloat(roundUpValue), | |
transaction.relationships.tags.data | |
.map((tag) => { | |
return tag.id; | |
}) | |
.join(","), | |
]; | |
if (includeRaw) { | |
mappedTransaction.push(JSON.stringify(transaction)); | |
} | |
return mappedTransaction; | |
}; | |
let data = fetch(UP_TRANSACTIONS(accountId, encodedParams), token); | |
let transactions = data.data; | |
while (data.links.next) { | |
data = fetch(data.links.next, token); | |
transactions = transactions.concat(data.data); | |
} | |
const headers = [ | |
"Created At", | |
"Description", | |
"Type", | |
"Amount", | |
"Round Up", | |
"Total", | |
"Tags", | |
]; | |
if (includeRaw) { | |
headers.push("JSON"); | |
} | |
return [headers].concat( | |
transactions.filter(transactionFilter).map(transactionMap) | |
); | |
} | |
function fetch(url, token) { | |
const options = { | |
method: "GET", | |
headers: { | |
Authorization: `Bearer ${token}`, | |
}, | |
}; | |
const response = UrlFetchApp.fetch(url, options); | |
return JSON.parse(response.getContentText()); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Installation
Code.gs
file with the aboveUsage
Once you have installed the script using the installation instructions, you will have two new Google spreadsheet functions,
UpAccounts
andUpTransactions
available to you!UpAccounts
Basic Usage
=UpAccounts('up:yeah:xxxxx')
Parameters
token
: your Up API token (begins withup:yeah
)includeSavers
: Allows you to include or exclude Savers accounts (optional) [default=true]UpTransactions
Basic Usage
=UpTransactions('up:yeah:xxxxx', 'c62336a0-abf7-4715-ba1e-ba6fac453827')
Parameters
token
: your Up API token (begins withup:yeah
)accountId
: account id to retrieve transactions from (a list of these can be found usingUpAccounts
)since
: date since in RFC-3339 format (optional)until
: date since in RFC-3339 format (optional)transactionTypes
: transaction types to include (optional) [default="Transaction,Quick save,Cover,Transfer,Funding,Forward"]