feat(webscrape-bank): webscrapes the bank file on a hour loop, init. api

This commit is contained in:
devaine 2026-01-26 16:03:50 -06:00
commit 2ec98dc81d
Signed by: devaine
GPG key ID: 954B1DCAC6FF84EE
8 changed files with 4252 additions and 0 deletions

7
.gitignore vendored Normal file
View file

@ -0,0 +1,7 @@
# PERSONAL INFO
.env
My-Finances*
notes
# Others
node_modules/

31
actual-api/src/index.js Normal file
View file

@ -0,0 +1,31 @@
require("dotenv").config();
let api = require("@actual-app/api");
// Constants
const ACTUAL_URL = process.env.ACTUAL_URL
const ACTUAL_PASSWORD = process.env.ACTUAL_PASSWORD
const ACTUAL_CHECKING_ID = process.env.ACTUAL_CHECKING_ID
(async () => {
await api.init({
dataDir: "./",
serverURL: ACTUAL_URL,
password: ACTUAL_PASSWORD,
});
console.log("Downloading the Budget Data")
await api.downloadBudget("1d6b0769-5ed4-4601-b6f2-b63df21f1f46");
console.log("Getting Account Info")
let accountInfo = await api.getAccounts()
console.log(accountInfo)
function inspectBankFile() {
}
//await api.shutdown();
})();

3817
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

18
package.json Normal file
View file

@ -0,0 +1,18 @@
{
"name": "transaction-sync",
"license": "ISC",
"main": "index.js",
"scripts": {
"actual": "node actual-api/src/index.js"
},
"dependencies": {
"@actual-app/api": "^26.1.0",
"concurrently": "^9.2.1",
"dotenv": "^17.2.3"
},
"devDependencies": {
"@eslint/js": "^9.39.2",
"eslint": "^9.39.2",
"eslint-plugin-import": "^2.32.0"
}
}

View file

@ -0,0 +1,99 @@
from playwright.sync_api import Playwright, sync_playwright, Page
from dotenv import load_dotenv
import os
from time import sleep
load_dotenv()
BANK_USER = os.getenv("BANK_USER")
BANK_PASS = os.getenv("BANK_PASS")
LOGIN_LINK = os.getenv("LOGIN_LINK")
ACCOUNT_LINK = os.getenv("ACCOUNT_LINK")
def main(playwright: Playwright) -> None:
browser = playwright.chromium.launch(headless=False)
context = browser.new_context()
page = context.new_page()
page.goto(LOGIN_LINK)
page.locator("#username").click()
page.locator("#username").fill(BANK_USER)
page.locator("#password").click()
page.locator("#password").fill(BANK_PASS)
page.get_by_role("button", name="Login", exact=True).click()
# Wait a little bit
page.wait_for_load_state()
page.get_by_role("button", name="Text").click()
page.get_by_test_id("text-field").click()
# Bank prompts 2FA (hopefully only once)
two_fac = input("2FA Code: ")
page.get_by_test_id("text-field").fill(two_fac)
page.get_by_test_id("private-button").click()
# Wait for everything to load...
page.wait_for_timeout(5000)
# We should be at the home page here
download_file(page)
def switchingForever(page: Page):
print("Switching to not get timed out!")
page.goto(ACCOUNT_LINK)
count = 0
while (count < 12):
page.wait_for_timeout(5000)
page.get_by_role("link", name="Cards").hover()
page.get_by_role("link", name="Activate Card").click(timeout=0)
sleep(300)
page.get_by_role("link", name="My Accounts").click(timeout=0)
count = count + 1
print("Count updated: " + str(count))
download_file(page)
def download_file(page: Page):
print("Going to download a new QFX File")
page.goto(ACCOUNT_LINK)
page.locator('iframe[title="Next Gen Home Page"]').content_frame.get_by_test_id(
"com.ncr.dbk.olb.widgets.my-accounts"
).get_by_test_id("feature-link").click()
page.wait_for_timeout(5000)
page.locator("#ncr-la-chat-win-notif-close path").click()
page.locator(
'iframe[title="NextGen account history page"]'
).content_frame.get_by_role("button", name="Download Transactions Button").click()
with page.expect_download(timeout=0) as download_info:
page.mouse.wheel(0, 70)
page.locator(
'iframe[title="NextGen account history page"]'
).content_frame.get_by_role("menuitem", name="Export QFX").dblclick()
download = download_info.value
download.save_as("./test.qfx")
print("Downloaded!")
switchingForever(page)
# context.close()
# browser.close()
if __name__ == "__main__":
with sync_playwright() as playwright:
main(playwright)

View file

View file

@ -0,0 +1 @@
{"modernCSSenabled":"true","adJourneyId":"085fb73e-5231-44fd-a593-60f720931593","hasAnomalyDetectionSDKLoaded":"true","adSessionId":"121f0996-2733-4b30-a907-7ba92678a72d","locale":"en_US","OLB_SESSIONID":"1769388232617","modernBrandingJSON":"{\"palette\":{\"info\":{\"main\":\"rgba(0, 55, 114, 1)\",\"subtle\":\"rgba(209, 231, 255, 1)\",\"subtleHover\":\"rgba(168, 210, 255, 1)\",\"subtleContrast\":\"rgba(0, 42, 87, 1)\",\"contrastText\":\"rgba(255, 255, 255, 1)\",\"light\":\"rgba(56, 152, 255, 1)\",\"dark\":\"rgba(0, 4, 8, 1)\"},\"logo\":{\"primary\":\"#003366\",\"secondary\":\"#808080\",\"subdued\":\"#6E6E6E\"},\"error\":{\"main\":\"rgba(221,23,8,1)\",\"subtle\":\"rgba(250,215,214,1)\",\"subtleHover\":\"rgba(248,197,196,1)\",\"subtleContrast\":\"rgba(113,11,1,1)\",\"contrastText\":\"rgba(255,255,255,1)\",\"light\":\"rgba(255,103,96,1)\",\"dark\":\"rgba(137,8,2,1)\"},\"other\":{\"muted\":\"#A9A9A9\",\"highlight\":\"#FFD700\",\"divider\":\"#E0E0E0\",\"border\":\"#919191\"},\"secondary\":{\"main\":\"rgba(196, 13, 59, 1)\",\"subtle\":\"rgba(253, 222, 229, 1)\",\"subtleHover\":\"rgba(251, 190, 206, 1)\",\"subtleContrast\":\"rgba(91, 6, 27, 1)\",\"contrastText\":\"rgba(255, 255, 255, 1)\",\"light\":\"rgba(245, 100, 136, 1)\",\"dark\":\"rgba(127, 8, 38, 1)\"},\"action\":{\"active\":\"rgba(0, 0, 0, 0.54)\",\"hover\":\"rgba(0, 0, 0, 0.04)\",\"selected\":\"rgba(0, 0, 0, 0.08)\",\"disabled\":\"rgba(0, 0, 0, 0.26)\",\"disabledBackground\":\"rgba(0, 0, 0, 0.12)\",\"focus\":\"rgba(0, 0, 0, 0.12)\"},\"primary\":{\"main\":\"rgba(0,55,114,1)\",\"subtle\":\"rgba(201,227,249,1)\",\"subtleHover\":\"rgba(177,215,246,1)\",\"subtleContrast\":\"rgba(5,53,112,1)\",\"contrastText\":\"rgba(255,255,255,1)\",\"light\":\"rgba(56,157,250,1)\",\"dark\":\"rgba(19,64,133,1)\"},\"success\":{\"main\":\"rgba(36,128,45,1)\",\"subtle\":\"rgba(209,229,207,1)\",\"subtleHover\":\"rgba(188,217,186,1)\",\"subtleContrast\":\"rgba(8,64,14,1)\",\"contrastText\":\"rgba(255,255,255,1)\",\"light\":\"rgba(57,175,62,1)\",\"dark\":\"rgba(6,78,5,1)\"},\"warning\":{\"main\":\"rgba(171,90,5,1)\",\"subtle\":\"rgba(248,218,187,1)\",\"subtleHover\":\"rgba(245,202,158,1)\",\"subtleContrast\":\"rgba(85,44,7,1)\",\"contrastText\":\"rgba(255,255,255,1)\",\"light\":\"rgba(221,131,47,1)\",\"dark\":\"rgba(101,55,0,1)\"},\"text\":{\"primary\":\"#212121\",\"disabled\":\"#9E9E9E\",\"secondary\":\"#656565\"},\"background\":{\"default\":\"#FAFAFA\",\"paper\":\"#FFFFFF\"}},\"typography\":{\"h1\":{\"fontSize\":28,\"fontFamily\":\"Calibri, Candara, Segoe, \\\"Segoe UI\\\", Optima, Arial, sans-serif\",\"fontWeight\":650},\"h2\":{\"fontSize\":25,\"fontFamily\":\"Calibri, Candara, Segoe, \\\"Segoe UI\\\", Optima, Arial, sans-serif\",\"fontWeight\":650},\"h3\":{\"fontSize\":22,\"fontFamily\":\"Calibri, Candara, Segoe, \\\"Segoe UI\\\", Optima, Arial, sans-serif\",\"fontWeight\":650},\"h4\":{\"fontSize\":20,\"fontFamily\":\"Calibri, Candara, Segoe, \\\"Segoe UI\\\", Optima, Arial, sans-serif\",\"fontWeight\":650},\"h5\":{\"fontSize\":18,\"fontFamily\":\"Calibri, Candara, Segoe, \\\"Segoe UI\\\", Optima, Arial, sans-serif\",\"fontWeight\":650},\"h6\":{\"fontSize\":16,\"fontFamily\":\"Calibri, Candara, Segoe, \\\"Segoe UI\\\", Optima, Arial, sans-serif\",\"fontWeight\":650},\"body1\":{\"fontSize\":16},\"body2\":{\"fontSize\":14},\"caption\":{\"fontSize\":12,\"fontFamily\":\"Calibri, Candara, Segoe, \\\"Segoe UI\\\", Optima, Arial, sans-serif\"},\"fontSize\":16,\"fontFamily\":\"Calibri, Candara, Segoe, \\\"Segoe UI\\\", Optima, Arial, sans-serif\"},\"components\":{\"MuiButton\":{\"defaultProps\":{\"color\":\"primary\"},\"styleOverrides\":{\"root\":{\"borderRadius\":15,\"textTransform\":\"none\"},\"sizeLarge\":{\"padding\":\"9px 18px\",\"lineHeight\":\"26px\"},\"sizeSmall\":{\"padding\":\"5px 10px\",\"lineHeight\":\"22px\"},\"sizeMedium\":{\"padding\":\"8px 16px\",\"lineHeight\":\"24px\"}}},\"MuiCard\":{\"styleOverrides\":{\"root\":{\"&.MuiWidgetCard\":{\"boxShadow\":\"0px 4px 20px rgba(27, 53, 93, 0.05)\",\"borderRadius\":15,\"opacity\":1}}}},\"MuiAccordion\":{\"styleOverrides\":{\"root\":{\"&.MuiWidgetStack:not(:last-child)\":{\"borderBottom\":0,\"borderRadius\":15},\"&.MuiWidgetStack:before\":{\"display\":\"none\"},\"&.MuiWidgetStack:last-child\":{\"borderRadius\":15},\"&.MuiWidgetStack\":{\"boxShadow\":\"0px 4px 20px rgba(27, 53, 93, 0.05)\",\"opacity\":1},\"&.MuiWidgetStack.MuiWidgetStackFavorite\":{\"borderRadius\":15}}}}}}"}

279
webscrape-bank/test.qfx Normal file
View file

@ -0,0 +1,279 @@
OFXHEADER:100
DATA:OFXSGML
VERSION:102
SECURITY:NONE
ENCODING:USASCII
CHARSET:1252
COMPRESSION:NONE
OLDFILEUID:NONE
NEWFILEUID:NONE
<OFX>
<SIGNONMSGSRSV1>
<SONRS>
<STATUS>
<CODE>0
<SEVERITY>INFO
</STATUS>
<DTSERVER>20260126032052[-8:PST]
<LANGUAGE>ENG
<FI>
<ORG> DI
<FID> 111906271
</FI>
<INTU.BID>9933
<INTU.USER>rafroj7821
</SONRS>
</SIGNONMSGSRSV1>
<BANKMSGSRSV1>
<STMTTRNRS>
<TRNUID>0
<STATUS>
<CODE>0
<SEVERITY>INFO
</STATUS>
<STMTRS>
<CURDEF>USD
<BANKACCTFROM>
<BANKID>111906271
<ACCTID>523638278
<ACCTTYPE>CHECKING
</BANKACCTFROM>
<BANKTRANLIST>
<DTSTART>20251226000000[-8:PST]
<DTEND>20260124000000[-8:PST]
<STMTTRN>
<TRNTYPE>POS
<DTPOSTED>20260124000000[-8:PST]
<TRNAMT>-73.13
<FITID>20260124000000[-6:CST]*-73.13*13**POS PUR- 00000001 *****7133
<NAME>POS PUR- 00000001 *****7133
<MEMO>01/23 03:30 CENTERPOINT ENERGY ENT HOUSTON TX
</STMTTRN>
<STMTTRN>
<TRNTYPE>SRVCHG
<DTPOSTED>20260123000000[-8:PST]
<TRNAMT>-1.00
<FITID>20260123000000[-6:CST]*-1.00*21**Zelle Debit Fee
<NAME>Zelle Debit Fee
</STMTTRN>
<STMTTRN>
<TRNTYPE>DEBIT
<DTPOSTED>20260123000000[-8:PST]
<TRNAMT>-10.00
<FITID>20260123000000[-6:CST]*-10.00*12**Xfer Debit- ZELLE ZARINA
<NAME>Xfer Debit- ZELLE ZARINA
<MEMO>01/23 16:44 800.677.9801
</STMTTRN>
<STMTTRN>
<TRNTYPE>CREDIT
<DTPOSTED>20260123000000[-8:PST]
<TRNAMT>30.00
<FITID>20260123000000[-6:CST]*30.00*512**INTERNET TRANSFER FROM:
<NAME>INTERNET TRANSFER FROM:
<MEMO>DDXXXX2655
</STMTTRN>
<STMTTRN>
<TRNTYPE>POS
<DTPOSTED>20260122000000[-8:PST]
<TRNAMT>-13.86
<FITID>20260122000000[-6:CST]*-13.86*13**POS PUR- *****7133 01/21 09:09
<NAME>POS PUR- *****7133 01/21 09:09
<MEMO>CHIPOTLE 2800 HOUSTON TX 9096
</STMTTRN>
<STMTTRN>
<TRNTYPE>CREDIT
<DTPOSTED>20260118000000[-8:PST]
<TRNAMT>435.25
<FITID>20260118000000[-6:CST]*435.25*512**Xfer Credit- ZELLE EMBER
<NAME>Xfer Credit- ZELLE EMBER
<MEMO>WINTERMERE GROU 01/18 16:37 800.677.9801
</STMTTRN>
<STMTTRN>
<TRNTYPE>POS
<DTPOSTED>20260117000000[-8:PST]
<TRNAMT>-3.39
<FITID>20260117000000[-6:CST]*-3.39*13**POS PUR- 122 *****7133 01/16
<NAME>POS PUR- 122 *****7133 01/16
<MEMO>22:30 TARGET 00009936 HOUSTON TX
</STMTTRN>
<STMTTRN>
<TRNTYPE>POS
<DTPOSTED>20260114000000[-8:PST]
<TRNAMT>-16.98
<FITID>20260114000000[-6:CST]*-16.98*13**POS PUR- *****7133 01/13 08:50
<NAME>POS PUR- *****7133 01/13 08:50
<MEMO>H-E-B #492 HOUSTON TX 00022088
</STMTTRN>
<STMTTRN>
<TRNTYPE>CREDIT
<DTPOSTED>20260114000000[-8:PST]
<TRNAMT>8.50
<FITID>20260114000000[-6:CST]*8.50*512**Xfer Credit- ZELLE GABRIELLA
<NAME>Xfer Credit- ZELLE GABRIELLA
<MEMO>AURELYA 01/13 17:09 800.677.9801
</STMTTRN>
<STMTTRN>
<TRNTYPE>POS
<DTPOSTED>20260108000000[-8:PST]
<TRNAMT>-3.24
<FITID>20260108000000[-6:CST]*-3.24*13**POS PUR- *****7133 01/07 17:44
<NAME>POS PUR- *****7133 01/07 17:44
<MEMO>CHECKPOINT #111 HOUSTON TX 04916202
</STMTTRN>
<STMTTRN>
<TRNTYPE>POS
<DTPOSTED>20260105000000[-8:PST]
<TRNAMT>-4.75
<FITID>20260105000000[-6:CST]*-4.75*13**POS PUR- 00000001 *****7133
<NAME>POS PUR- 00000001 *****7133
<MEMO>01/03 22:03 SHELL OIL12980332014 RICHMOND TX
</STMTTRN>
<STMTTRN>
<TRNTYPE>POS
<DTPOSTED>20260103000000[-8:PST]
<TRNAMT>-15.00
<FITID>20260103000000[-6:CST]*-15.00*13**POS PUR- *****7133 01/01 22:04
<NAME>POS PUR- *****7133 01/01 22:04
<MEMO>lonestar LINCOLN NE 73262040
</STMTTRN>
<STMTTRN>
<TRNTYPE>POS
<DTPOSTED>20260102000000[-8:PST]
<TRNAMT>-331.20
<FITID>20260102000000[-6:CST]*-331.20*13**POS PUR- 0000 *****7133 01/02
<NAME>POS PUR- 0000 *****7133 01/02
<MEMO>09:50 LONE STAR COLLEGE/EPAY THE WOODLANDS TX
</STMTTRN>
<STMTTRN>
<TRNTYPE>CREDIT
<DTPOSTED>20260102000000[-8:PST]
<TRNAMT>100.00
<FITID>20260102000000[-6:CST]*100.00*512**INTERNET TRANSFER FROM:
<NAME>INTERNET TRANSFER FROM:
<MEMO>DDXXXX2655
</STMTTRN>
<STMTTRN>
<TRNTYPE>POS
<DTPOSTED>20260101000000[-8:PST]
<TRNAMT>-2.00
<FITID>20260101000000[-6:CST]*-2.00*13**POS PUR- *****7133 12/31 08:13
<NAME>POS PUR- *****7133 12/31 08:13
<MEMO>H-E-B #492 HOUSTON TX 00022080
</STMTTRN>
<STMTTRN>
<TRNTYPE>POS
<DTPOSTED>20251231000000[-8:PST]
<TRNAMT>-2.97
<FITID>20251231000000[-6:CST]*-2.97*13**POS PUR- *****7133 12/30 18:33
<NAME>POS PUR- *****7133 12/30 18:33
<MEMO>H-E-B #492 HOUSTON TX 87969902
</STMTTRN>
<STMTTRN>
<TRNTYPE>POS
<DTPOSTED>20251231000000[-8:PST]
<TRNAMT>-29.45
<FITID>20251231000000[-6:CST]*-29.45*13**POS PUR- 47640095 *****7133
<NAME>POS PUR- 47640095 *****7133
<MEMO>12/30 17:47 WAL SAMSCLUB #4764 0008 KATY TX
</STMTTRN>
<STMTTRN>
<TRNTYPE>CREDIT
<DTPOSTED>20251231000000[-8:PST]
<TRNAMT>30.00
<FITID>20251231000000[-6:CST]*30.00*512**INTERNET TRANSFER FROM:
<NAME>INTERNET TRANSFER FROM:
<MEMO>DDXXXX2655
</STMTTRN>
<STMTTRN>
<TRNTYPE>POS
<DTPOSTED>20251230000000[-8:PST]
<TRNAMT>-7.74
<FITID>20251230000000[-6:CST]*-7.74*13**POS PUR- 99999999 *****7133
<NAME>POS PUR- 99999999 *****7133
<MEMO>12/30 11:03 TST* FENG CHA - CYPRES CYPRESS TX
</STMTTRN>
<STMTTRN>
<TRNTYPE>POS
<DTPOSTED>20251230000000[-8:PST]
<TRNAMT>-18.58
<FITID>20251230000000[-6:CST]*-18.58*13**POS PUR- *****7133 12/29 05:37
<NAME>POS PUR- *****7133 12/29 05:37
<MEMO>UEP*AJI IZAKAYA CYPRESS TX 99999999
</STMTTRN>
<STMTTRN>
<TRNTYPE>POS
<DTPOSTED>20251228000000[-8:PST]
<TRNAMT>-62.50
<FITID>20251228000000[-6:CST]*-62.50*13**POS PUR- 1GDVKT18 *****7133
<NAME>POS PUR- 1GDVKT18 *****7133
<MEMO>12/27 00:19 SQ *GRAYSCALE BARBERSH Katy TX
</STMTTRN>
<STMTTRN>
<TRNTYPE>POS
<DTPOSTED>20251226000000[-8:PST]
<TRNAMT>-7.39
<FITID>20251226000000[-6:CST]*-7.39*13**POS PUR- *****7133 12/24 08:16
<NAME>POS PUR- *****7133 12/24 08:16
<MEMO>H-E-B #492 HOUSTON TX 00022072
</STMTTRN>
<STMTTRN>
<TRNTYPE>POS
<DTPOSTED>20251226000000[-8:PST]
<TRNAMT>-68.34
<FITID>20251226000000[-6:CST]*-68.34*13**POS PUR- 00000001 *****7133
<NAME>POS PUR- 00000001 *****7133
<MEMO>12/24 02:07 CENTERPOINT ENERGY ENT HOUSTON TX
</STMTTRN>
<STMTTRN>
<TRNTYPE>CASH
<DTPOSTED>20251226000000[-8:PST]
<TRNAMT>-80.00
<FITID>20251226000000[-6:CST]*-80.00*0*423013504*In Branch Transaction Debit
<CHECKNUM>423013504
<NAME>In Branch Transaction Debit
</STMTTRN>
</BANKTRANLIST>
<LEDGERBAL>
<BALAMT>591.16
<DTASOF>20260126032052[-8:PST]
</LEDGERBAL>
<AVAILBAL>
<BALAMT>591.16
<DTASOF>20260126032052[-8:PST]
</AVAILBAL>
</STMTRS>
</STMTTRNRS>
</BANKMSGSRSV1>
</OFX>