Skip to content

Instantly share code, notes, and snippets.

@dangarbri
Last active December 24, 2022 16:54
Show Gist options
  • Select an option

  • Save dangarbri/9e993373aba85e7107b7a224426fb158 to your computer and use it in GitHub Desktop.

Select an option

Save dangarbri/9e993373aba85e7107b7a224426fb158 to your computer and use it in GitHub Desktop.

Revisions

  1. dangarbri revised this gist Dec 24, 2022. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions setup.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,2 @@
    git clone git@github.com:Appsolutely-Wonderful/amex-selenium-api.git
    git clone git@github.com:Appsolutely-Wonderful/everydollar-selenium-api.git
  2. dangarbri revised this gist Dec 24, 2022. 1 changed file with 29 additions and 48 deletions.
    77 changes: 29 additions & 48 deletions amex_everydollar_integration.py
    Original file line number Diff line number Diff line change
    @@ -9,70 +9,51 @@
    from everydollar_api import EveryDollarAPI
    from time import sleep
    from datetime import datetime, timedelta
    import pickle
    import os

    # Create your own creds.py with these variables
    from creds import amex_username, amex_password, everydollar_username, everydollar_password

    UPDATE_FREQUENCY_SECONDS = 86400 # every 24 hours
    pending_transactions = [] # Watch for when pending transactions clear
    first_run = True # First run ignores any pending transactions and adds all cleared ones
    iteration = 1
    DATE_THRESHOLD = datetime.fromisoformat("2022-12-20 00:00:00")
    TRANSACTIONS_FILE = "transactions.pickle"
    captured_transactions = [] # Watch for when pending transactions clear
    merchant_prefix = "Amex "

    def matching(a, b):
    """
    Check if transactions match
    """
    if a.date == b.date and a.merchant == b.merchant and a.amount == b.amount:
    return True
    return False
    def save_transactions():
    with open(TRANSACTIONS_FILE, "wb") as fp:
    pickle.dump(captured_transactions, fp)

    def load_transactions():
    if os.path.exists(TRANSACTIONS_FILE):
    with open(TRANSACTIONS_FILE, "rb") as fp:
    global captured_transactions
    captured_transactions = pickle.load(fp)

    def apply_prefix(merchant):
    return "Amex " + merchant

    while True:

    print(f"Running iteration {iteration}")
    iteration = iteration + 1
    # Get webdrivers
    amex = AmexAPI()
    if __name__ == "__main__":
    load_transactions()
    # Get webdrivers
    everydollar = EveryDollarAPI()
    amex = AmexAPI()

    # Log in to each site
    amex.login(amex_username, amex_password)
    # Log in to each site
    everydollar.login(everydollar_username, everydollar_password)
    amex.login(amex_username, amex_password)

    # Get transactions from amex
    # Get transactions from amex
    transactions = amex.get_recent_transactions()

    for new_transaction in transactions:
    # Ignore pending transactions.
    # Only add them when they clear
    if not new_transaction.pending:
    if first_run:
    print(f"Adding transaction {new_transaction}")
    everydollar.add_transaction(new_transaction.date, apply_prefix(new_transaction.merchant), new_transaction.amount)
    sleep(1) # wait for webdriver to be done... TODO: Move this into everydollar api
    else:
    # if it's not the first run, check if the transaction was pending
    # If it wasn't pending, then it's already been added to everydollar
    for transaction in pending_transactions:
    if matching(transaction, new_transaction):
    # Transaction has gone from pending to cleared, add it to everydollar
    print(f"Adding transaction {new_transaction}")
    everydollar.add_transaction(new_transaction.date, apply_prefix(new_transaction.merchant), new_transaction.amount)
    sleep(1)
    # Remove the pending transaction from the list
    pending_transactions.remove(transaction)

    else:
    # Watch pending transactions so we can add them when they're cleared
    pending_transactions.append(new_transaction)

    # Close browsers/logout TODO: Add proper logout button
    if (new_transaction.date > DATE_THRESHOLD) and (new_transaction not in captured_transactions):
    print(f"Adding transaction {new_transaction}")
    everydollar.add_transaction(new_transaction.date, apply_prefix(new_transaction.merchant), new_transaction.amount)
    captured_transactions.append(new_transaction)
    save_transactions()
    sleep(1)

    # Close browsers/logout TODO: Add proper logout button
    amex.close()
    everydollar.close()
    first_run = False

    # Wait until it's time to run again
    sleep(UPDATE_FREQUENCY_SECONDS)
  3. dangarbri created this gist Jan 10, 2021.
    78 changes: 78 additions & 0 deletions amex_everydollar_integration.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,78 @@
    """
    Uses selenium based APIs for American Express and Everydollar
    continuously import transactions into everydollar.
    Since everydollar doesn't natively support linking an American Express account
    """

    from amex_selenium import AmexAPI
    from everydollar_api import EveryDollarAPI
    from time import sleep
    from datetime import datetime, timedelta

    # Create your own creds.py with these variables
    from creds import amex_username, amex_password, everydollar_username, everydollar_password

    UPDATE_FREQUENCY_SECONDS = 86400 # every 24 hours
    pending_transactions = [] # Watch for when pending transactions clear
    first_run = True # First run ignores any pending transactions and adds all cleared ones
    iteration = 1
    merchant_prefix = "Amex "

    def matching(a, b):
    """
    Check if transactions match
    """
    if a.date == b.date and a.merchant == b.merchant and a.amount == b.amount:
    return True
    return False

    def apply_prefix(merchant):
    return "Amex " + merchant

    while True:

    print(f"Running iteration {iteration}")
    iteration = iteration + 1
    # Get webdrivers
    amex = AmexAPI()
    everydollar = EveryDollarAPI()

    # Log in to each site
    amex.login(amex_username, amex_password)
    everydollar.login(everydollar_username, everydollar_password)

    # Get transactions from amex
    transactions = amex.get_recent_transactions()

    for new_transaction in transactions:
    # Ignore pending transactions.
    # Only add them when they clear
    if not new_transaction.pending:
    if first_run:
    print(f"Adding transaction {new_transaction}")
    everydollar.add_transaction(new_transaction.date, apply_prefix(new_transaction.merchant), new_transaction.amount)
    sleep(1) # wait for webdriver to be done... TODO: Move this into everydollar api
    else:
    # if it's not the first run, check if the transaction was pending
    # If it wasn't pending, then it's already been added to everydollar
    for transaction in pending_transactions:
    if matching(transaction, new_transaction):
    # Transaction has gone from pending to cleared, add it to everydollar
    print(f"Adding transaction {new_transaction}")
    everydollar.add_transaction(new_transaction.date, apply_prefix(new_transaction.merchant), new_transaction.amount)
    sleep(1)
    # Remove the pending transaction from the list
    pending_transactions.remove(transaction)

    else:
    # Watch pending transactions so we can add them when they're cleared
    pending_transactions.append(new_transaction)

    # Close browsers/logout TODO: Add proper logout button
    amex.close()
    everydollar.close()
    first_run = False

    # Wait until it's time to run again
    sleep(UPDATE_FREQUENCY_SECONDS)