beanni / beanni

Your friendly Australian bean-counter. Beanni helps gather financial data from all of your various providers, institutions, and banks.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Beanni

Your friendly Australian bean-counter, Beanni.

GitHub contributors Build Status

By @mjhilton and @tathamoddie.

Beanni helps gather financial data from all of your various institutions. Having all of this cached in a local database allows you to do deeper analysis than typical online banking tools would allow, such as portfolio-wide net-wealth trends.

Beanni is just a local helper, on your own machine. You're not sharing your passwords with us, or anybody else. You're not reverse engineering your bank. Beanni is just a robot that's really fast at clicking the same export buttons that you would otherwise have to click manually.

Usage

πŸ†• First Run

Get started:

Step Run Why
1. https://nodejs.org/en/download/ Beanni is built on Node.js
2. node --version Make sure you're on Node β‰₯18
3. npm --version Make sure you're on NPM β‰₯8
4. git clone https://github.com/beanni/beanni.git
cd beanni
Pull down the latest version of Beanni
5. npm install Install Beanni's dependencies
6. npm run build Build Beanni
6. npm run init Create an example config.yaml
7. Edit config.yaml Add your own banking relationships
8. npm run fetch Grab your data
9. npm run explore Launch the analysis UI

βš’ Ongoing Usage (Manual)

Fetch and explore your data:

Step Run Why
1. npm run fetch Grab your data
2. npm run explore Launch the analysis UI

βš™ Ongoing Usage (Automated, Linux)

Beanni works best when you're building up long-term data trends.

Setup a cronjob to fetch your data on a regular basis. Twice a day gives the best resilience (you'll get daily data points, with a long recovery window for any provider outages / maintenance windows).

~ $ crontab -e

0 5 * * * (cd ~/beanni; npm run fetch >> cron.log 2>&1;)
0 17 * * * (cd ~/beanni; npm run fetch >> cron.log 2>&1;)

Keep the web interface running as a service, so that it's always available:

~ $ sudo nano /etc/systemd/system/beanni.service

[Unit]
Description=Beanni explore server
After=network.target

[Service]
Type=simple
User=myuser
WorkingDirectory=/home/myuser/beanni
ExecStart=npm run explore
Restart=on-failure

[Install]
WantedBy=multi-user.target

~ $ sudo systemctl enable beanni

πŸ†• Updating Beanni

Get the latest updates:

Step Run Why
1. git pull --ff-only Update Beanni to the latest version
2. npm install Install any new dependencies
3. npm run build Build Beanni

If you've configured Beanni to run as a service, restart that too. (Probably via $ sudo systemctl restart beanni).

πŸ—‘ Uninstall

  1. Remove secrets from your operating system's credential store
    • Windows:
      1. WinKey > credential manager
      2. Windows Credentials
      3. Generic Credentials
      4. Look for anything that starts with Beanni:
    • MacOS: Keychain
    • Headless environment: ~/.beanni/secrets.yaml
  2. Remove your data from the local working folder, specifically:
    • beanni.db (the database contains bank account numbers and financial data)
    • config.yaml (your provider listing)
    • statements/ (folder cache of downloaded statements)
  3. Remove the local working folder

πŸ‘©β€πŸ’» API

There are two REST endpoints exposed while npm run explore is running:

/api/netWealth returns a JSON object like {"netWealth":12345.67}

/api/dataIssues returns a JSON object like {"count":1}

These can be integrated into a platform like Home Assistant, via a REST sensor:

sensor:
  - platform: rest
    resource: http://host:3000/api/netWealth
    name: Net Wealth
    value_template: "{{ value_json.netWealth }}"
    device_class: monetary
    unit_of_measurement: $
  - platform: rest
    resource: http://host:3000/api/dataIssues
    name: Beanni Data Issues
    value_template: "{{ value_json.count }}"

And then you can use Home Assistant to deliver a push notification to you whenever there's a noteworthy balance movement, or if you have stale balances (because a provider is persistently failing):

automation:
  - id: net_wealth_event
    alias: "[Beanni] Net Wealth Event"
    trigger:
      - platform: state
        entity_id: sensor.net_wealth
    condition:
      condition: and
      conditions:
        - alias: "Old state was a number"
          condition: template
          value_template: "{{ trigger.from_state.state|float > 0 }}"
        - alias: "New state is a number"
          condition: template
          value_template: "{{ trigger.to_state.state|float > 0 }}"
        - alias: "Only events >$1k"
          condition: template
          value_template: "{{ (((trigger.from_state.state|float) - (trigger.to_state.state|float)) | abs) > 1000 }}"
    action:
      - service: notify.everyone
        data_template:
          title: πŸ€‘ Financial Event
          message: "{{ 'Positive' if (trigger.to_state.state|float) > (trigger.from_state.state|float) else 'Negative' }} net wealth movement"
          data:
            channel: Beanni
            clickAction: http://host:3000/

  - id: beanni_data_issues
    alias: "[Beanni] Data Issues"
    trigger:
      - platform: state
        entity_id: sensor.beanni_data_issues
    condition: "{{ trigger.to_state.state|int > 0 }}"
    action:
      - service: notify.everyone
        data_template:
          title: ⚠️ Beanni Data Issues
          message: Requires investigation
          data:
            channel: Beanni
            clickAction: http://host:3000/

Security, by design

πŸ’» Execution Environment

Beanni all runs locally on your own machine, or your own hosting. There are no shared web services in play.

🀫 Secret Storage

Secrets are kept out of configuration files entirely, by design.

Secrets are stored in your operating system's credential store (Credential Manager on Windows, or Keychain on MacOS). We use keytar to do this, which is built and maintained by the Atom project.

Beanni will seek credentials during your first fetch. If you're running on an interactive command line, it'll prompt you, then store these values in your operating system's credential store. If you're running in a context where this doesn't work, such as headless execution, or without a compatible store, Beanni will give guidance about configuring a secrets file.

πŸ“¦ Dependency Supply Chain

Our dependency supply chain is the biggest risk. We've been careful to keep our package.json dependencies list short, and highly trustworthy:

Package Weekly Package Downloads (Jan 2021) Known/Trusted Maintainer
commander >40M
express >10M
inquirer >20M
js-yaml >20M
keytar >100k Atom
lodash >30M
pug >750k
puppeteer >1.5M Google Chrome
request >20M
sqlite >60k
ts-node >6M

It would be very visible if any of these packages, or their dependencies, were to be compromised.

You can compare this table with https://github.com/beanni/beanni/network/dependencies (GitHub's view of Beanni's dependencies, based on what's in source control).

We use Dependabot to ensure we adopt updates to these dependencies as fast as possible. It's a busy little bot.

Development

πŸ‘©β€πŸ’» Local Execution

  1. git clone https://github.com/beanni/beanni.git
  2. npm install
  3. VS Code > Ctrl+F5

🌲 Dependencies

For a smooth npm install:

  • On Ubuntu, LibSecret needs to be installed for Keytar to npm install properly

  • sqlite3 requires a native binary. npm install will attempt to resolve a pre-compiled binary for the right combination of your OS, architecture, and node version via node-pre-gyp. If this fails, it'll then attempt to compile from source which will then throw up new dependencies for Python and a C++ compiler. You're probably better off getting the pre-compiled binary option to work instead of trying to install the required compiler toolchain. If you want to pursue the build tools on Windows, try npm install --vs2015 --global --production --add-python-to-path windows-build-tools from an elevated prompt.

πŸ€– Puppeteer Debugging

Running npm run fetch -- --debug will keep the browser visible during execution, and write out more logs.

In VS Code, you can F5 > explore > --debug to both apply this flag and attach a debugger to the process.

About

Your friendly Australian bean-counter. Beanni helps gather financial data from all of your various providers, institutions, and banks.

License:MIT License


Languages

Language:TypeScript 84.0%Language:Pug 11.9%Language:CSS 2.2%Language:JavaScript 1.9%Language:Shell 0.1%