Last active
April 28, 2025 15:20
-
-
Save shotasenga/aa5e83b9406f7fcc2910cc7c43a30d4b to your computer and use it in GitHub Desktop.
Export Wealthsimple transactions as CSV
This file contains hidden or 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
/* | |
* DISCLAIMER: | |
* This script extracts sensitive financial information (transaction data) from Wealthsimple. | |
* Ensure that you use this script in a secure environment and handle the extracted data responsibly. | |
* The developer of this script is not responsible for any issues or troubles that arise from its use. | |
*/ | |
(async function () { | |
"use strict"; | |
const transactions = []; | |
for (const button of x(`//button[contains(., 'Chequing')][contains(., 'CAD')]`)) { | |
const payee = button.querySelector("p").innerText; | |
const amount = x(`.//p[contains(., 'CAD')]`, button).next().value.innerText; | |
button.click(); | |
await nextTick(); | |
const [date, _] = Array.from( | |
x( | |
`.//p[contains(., 'Date')]/following-sibling::*//p`, | |
button.parentElement.parentElement | |
) | |
).map((el) => el.innerText); | |
transactions.push({ | |
payee, | |
amount, | |
date: formatDateForYNAB(date), | |
}); | |
} | |
const csv = []; | |
csv.push("Date, Payee, Amount"); | |
for (const transaction of transactions) { | |
csv.push( | |
[transaction.date, transaction.payee, transaction.amount] | |
.map(escapeCsvField) | |
.join(",") | |
); | |
} | |
// save as a file | |
const blob = new Blob([csv.join("\n")], { type: "text/csv" }); | |
const url = URL.createObjectURL(blob); | |
const a = document.createElement("a"); | |
a.href = url; | |
a.download = "transactions.csv"; | |
a.click(); | |
function* x(xpath, root = document) { | |
const xpathResult = document.evaluate( | |
xpath, | |
root, | |
null, | |
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, | |
null | |
); | |
for (let i = 0; i < xpathResult.snapshotLength; i++) { | |
yield xpathResult.snapshotItem(i); | |
} | |
} | |
function nextTick() { | |
return new Promise((resolve) => setTimeout(resolve, 0)); | |
} | |
function waitUntilElementExists(xpath, callback) { | |
const observer = new MutationObserver(() => { | |
const element = x(xpath).next().value; | |
if (element) { | |
observer.disconnect(); | |
callback(element); | |
} | |
}); | |
observer.observe(document.documentElement, { | |
childList: true, | |
subtree: true, | |
}); | |
} | |
function escapeCsvField(field) { | |
return `"${field}"`; | |
} | |
function formatDateForYNAB(str) { | |
// "August 19, 2024" to "2024-08-19" using RegExp | |
const [, month_s, day_s, year] = str.match(/(\w+) (\d+), (\d+)/); | |
const month = (new Date(Date.parse(`${month_s} 1, 2020`)).getMonth() + 1) | |
.toString() | |
.padStart(2, "0"); | |
const day = day_s.padStart(2, "0"); | |
return `${year}-${month}-${day}`; | |
} | |
})(); |
Updated the script to reflect the wording changes on Wealthsimple (from "Cache" to "Chequing")
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is a bookmarklet version of the CSV export user script for Wealthsimple.
Instruction
DISCLAIMER