Giter VIP home page Giter VIP logo

actual-ai's Introduction

๐Ÿค– Actual AI

GitHub Release Docker Image Version

This is a project that allows you to categorize uncategorized transactions for Actual Budget using OpenAI or OpenAI specification compatible API, like a self-hosted Ollama server.

๐ŸŒŸ Features

๐Ÿ“Š Classify transactions using OpenAI

The app sends requests to the OpenAI API to classify transactions based on their description, amount, and notes.

๐Ÿ”„ Sync accounts before classification

๐Ÿ•’ Classify transactions on a cron schedule

โŒ When a transaction cannot be classified, it is marked in Notes as "not guessed," and it will not be classified again.

โœ… Every guessed transaction is marked as guessed in notes, so you can review the classification.

๐Ÿš€ Usage

Sample docker-compose.yml file:

services:
  actual_server:
    image: docker.io/actualbudget/actual-server:latest
    ports:
      - '5006:5006'
    volumes:
      - ./actual-data:/data
    restart: unless-stopped

  actual-ai:
    image: docker.io/sakowicz/actual-ai:latest
    restart: unless-stopped
    environment:
      - ACTUAL_SERVER_URL=http://actual_server:5006
      - ACTUAL_PASSWORD=your_actual_password
      - ACTUAL_BUDGET_ID=your_actual_budget_id # This is the ID from Settings โ†’ Show advanced settings โ†’ Sync ID
      - CLASSIFICATION_SCHEDULE_CRON=0 */4 * * * # How often to run classification.
      - CLASSIFY_ON_STARTUP=true # Whether to classify transactions on startup (don't wait for cron schedule)
      - SYNC_ACCOUNTS_BEFORE_CLASSIFY=false # Whether to sync accounts before classification
      - OPENAI_API_KEY=your_openai_api_key
#      - OPENAI_MODEL= # optional. required if you want to use a specific model, default is "gpt-3.5-turbo-instruct"
#      - OPENAI_BASE_URL= # optional. required if you don't want to use the OpenAI API but OpenAI compatible API, ex: "http://ollama:11424/v1
#      - ACTUAL_E2E_PASSWORD= # optional. required if you have E2E encryption
#      - NODE_TLS_REJECT_UNAUTHORIZED=0 # optional. required if you have trouble connecting to Actual server 

๐Ÿ“ Notes from the author

I'm not a Node developer. I have no experience with AI or GitHub actions. I've created this script to help categorise hundreds of transactions in my Actual Budget and decided to publish it.

Feel free to suggest changes or open a MR.

actual-ai's People

Contributors

sakowicz avatar dependabot[bot] avatar lejacobroy avatar

Stargazers

Nik avatar Mariusz avatar pypeaday avatar  avatar Fouad Mannou avatar Sam Whitford avatar Paul Cuciureanu avatar Paul Coates avatar  avatar Randy avatar  avatar Mark Thomas avatar  avatar Simon Tong avatar Altan S avatar Mathieu Masy avatar Vinay Sastry avatar Andrew Li avatar Fadojutimi Temitayo Olusegun avatar  avatar Akash Gurava avatar vorwd avatar  avatar Mark Pinero avatar  avatar Dean Sallinen avatar JigSaw avatar  avatar Tyler Meuse avatar  avatar Robin Tuszik avatar Jens avatar Cameron Jackson avatar  avatar Matteo Piotto avatar  avatar Avery Hill avatar  avatar Boris avatar Braxton Diggs avatar  avatar Matt Elliott avatar Piotr Sowa avatar Stian Nyblom avatar Jon avatar Jason Stelzer avatar Jani avatar Elyas Christiansen avatar Bander Alsulami avatar Prasad Bankar avatar Thiago Andrade avatar Daniel Brodie avatar Sandeep S avatar  avatar Gohan472 avatar  avatar  avatar  avatar  avatar abe avatar  avatar alex avatar  avatar Chris L avatar Nelson Cabete avatar Dhruvin Shah avatar  avatar Salvatore Gentile avatar  avatar  avatar

Watchers

Nik avatar  avatar

actual-ai's Issues

Error: Could not get remote files

When running the actual-ai Docker container, I get the following error:

> @sakowicz/[email protected] dev-docker
> ../node_modules/.bin/nodemon --exec "npm run lint && node ./app.js"

[nodemon] 2.0.22
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `npm run lint && node ./app.js`

> @sakowicz/[email protected] lint
> eslint --fix **/*.js

Application started
Starting classification process
An error occurred: Error: Could not get remote files
    at handlers.api/download-budget (/opt/node_app/node_modules/@actual-app/api/dist/app/bundle.api.js:29444:31)
node:internal/process/promises:288
            triggerUncaughtException(err, true /* fromPromise */);
            ^

Error: Could not get remote files
    at handlers.api/download-budget (/opt/node_app/node_modules/@actual-app/api/dist/app/bundle.api.js:29444:31)

Node.js v18.20.4
[nodemon] app crashed - waiting for file changes before starting...

I am self-hosting the actual-server on my Synology NAS. As a result, I am using a self-signed SSL certificate. I believe the is the cause of my issue. I received the same error with actual-helpers, and the developer of that project was able to fix it by adding a config option to permit the actual-api to allow self-signed SSL certs.

psybers/actual-helpers#2

These are the changes I see via GitHub, but I have asked the project owner for further details on the fix, and will provide updates as I get them.


Changed files for Self-Signed Certifiates

Dockerfile
Add:
# Allow self-signed SSL certs
ENV NODE_TLS_REJECT_UNAUTHORIZED=0


.env
Add:
# allow self-signed SSL certs
NODE_TLS_REJECT_UNAUTHORIZED=0

Thanks in advance for the help!

Suggestions

I just wanted to say that this is off to a great start. I love the idea.

I am unable to provide a pull request, as I completely butchered your code on my end, but I experimented with your code and made some tweaks to this to help make matching better from my personal experience.

For each request, I sent it a copy of my existing rules so that it could understand what other types of categorisations I make to help make more informed decisions.

I created a JSON file which contained a description of each category to provide better context about when to choose it. I also marked some categories here as DO-NOT-USE.

I instructed it to research the merchant if it could not categorise it to see if this would help with its matching.

I instructed it to use the last category chosen for that merchant if there is a match (in lieu of having a rule already in place via Actual!) because I found that sometimes it would choose different categories for effectively the same merchant.

Hopefully this gives you some ideas for improving this tool!

@actual-api is not the latest, causing conflict with latest actual-server

I am running the latest actual-server. version 24.8.0. The current API version is 6.9.0, per https://www.npmjs.com/package/@actual-app/api

When running the actual-ai Docker container, I receive the following error. According to the actual Discord, this appears to be a mismatch between the API version used by actual-ai and actual-server.

actual-ai-1  | Application started
actual-ai-1  | Starting classification process
actual-ai-1  | (node:1) Warning: Setting the NODE_TLS_REJECT_UNAUTHORIZED environment variable to '0' makes TLS connections and HTTPS requests insecure by disabling certificate verification.
actual-ai-1  | (Use `node --trace-warnings ...` to show where the warning was created)
actual-ai-1  | Database is out of sync with migrations: {
actual-ai-1  |   appliedIds: [
actual-ai-1  |     1548957970627, 1550601598648, 1555786194328,
actual-ai-1  |     1561751833510, 1567699552727, 1582384163573,
actual-ai-1  |     1597756566448, 1608652596043, 1608652596044,
actual-ai-1  |     1612625548236, 1614782639336, 1615745967948,
actual-ai-1  |     1616167010796, 1618975177358, 1632571489012,
actual-ai-1  |     1679728867040, 1681115033845, 1682974838138,
actual-ai-1  |     1685007876842, 1686139660866, 1688749527273,
actual-ai-1  |     1688841238000, 1691233396000, 1694438752000,
actual-ai-1  |     1697046240000, 1704572023730, 1704572023731,
actual-ai-1  |     1707267033000, 1712784523000, 1716359441000,
actual-ai-1  |     1720310586000, 1720664867241, 1720665000000
actual-ai-1  |   ],
actual-ai-1  |   available: [
actual-ai-1  |     '1548957970627_remove-db-version.sql',
actual-ai-1  |     '1550601598648_payees.sql',
actual-ai-1  |     '1555786194328_remove_category_group_unique.sql',
actual-ai-1  |     '1561751833510_indexes.sql',
actual-ai-1  |     '1567699552727_budget.sql',
actual-ai-1  |     '1582384163573_cleared.sql',
actual-ai-1  |     '1597756566448_rules.sql',
actual-ai-1  |     '1608652596043_parent_field.sql',
actual-ai-1  |     '1608652596044_trans_views.sql',
actual-ai-1  |     '1612625548236_optimize.sql',
actual-ai-1  |     '1614782639336_trans_views2.sql',
actual-ai-1  |     '1615745967948_meta.sql',
actual-ai-1  |     '1616167010796_accounts_order.sql',
actual-ai-1  |     '1618975177358_schedules.sql',
actual-ai-1  |     '1632571489012_remove_cache.js',
actual-ai-1  |     '1679728867040_rules_conditions.sql',
actual-ai-1  |     '1681115033845_add_schedule_name.sql',
actual-ai-1  |     '1682974838138_remove_payee_rules.sql',
actual-ai-1  |     '1685007876842_add_category_hidden.sql',
actual-ai-1  |     '1686139660866_remove_account_type.sql',
actual-ai-1  |     '1688749527273_transaction_filters.sql',
actual-ai-1  |     '1688841238000_add_account_type.sql',
actual-ai-1  |     '1691233396000_add_schedule_next_date_tombstone.sql',
actual-ai-1  |     '1694438752000_add_goal_targets.sql',
actual-ai-1  |     '1697046240000_add_reconciled.sql',
actual-ai-1  |     '1704572023730_add_account_sync_source.sql',
actual-ai-1  |     '1704572023731_add_missing_goCardless_sync_source.sql',
actual-ai-1  |     '1707267033000_reports.sql',
actual-ai-1  |     '1712784523000_unhide_input_group.sql'
actual-ai-1  |   ]
actual-ai-1  | }
actual-ai-1  | Error updating Error: out-of-sync-migrations
actual-ai-1  |     at checkDatabaseValidity (/opt/node_app/node_modules/@actual-app/api/dist/app/bundle.api.js:39329:31)
actual-ai-1  |     at Module.migrate (/opt/node_app/node_modules/@actual-app/api/dist/app/bundle.api.js:39337:17)
actual-ai-1  |     at async runMigrations (/opt/node_app/node_modules/@actual-app/api/dist/app/bundle.api.js:43144:17)
actual-ai-1  |     at async updateVersion (/opt/node_app/node_modules/@actual-app/api/dist/app/bundle.api.js:43163:17)
actual-ai-1  |     at async loadBudget (/opt/node_app/node_modules/@actual-app/api/dist/app/bundle.api.js:38945:21)
actual-ai-1  |     at async handlers.load-budget (/opt/node_app/node_modules/@actual-app/api/dist/app/bundle.api.js:38775:29)
actual-ai-1  |     at async handlers.download-budget (/opt/node_app/node_modules/@actual-app/api/dist/app/bundle.api.js:38745:17)
actual-ai-1  |     at async handlers.api/download-budget (/opt/node_app/node_modules/@actual-app/api/dist/app/bundle.api.js:29478:32)
actual-ai-1  | TypeError: Cannot read properties of undefined (reading 'timestamp')
actual-ai-1  |     at _fullSync (/opt/node_app/node_modules/@actual-app/api/dist/app/bundle.api.js:42483:98)
actual-ai-1  |     at /opt/node_app/node_modules/@actual-app/api/dist/app/bundle.api.js:42395:38
actual-ai-1  |     at /opt/node_app/node_modules/@actual-app/api/dist/app/bundle.api.js:43341:38
actual-ai-1  |     at initialFullSync (/opt/node_app/node_modules/@actual-app/api/dist/app/bundle.api.js:42381:38)
actual-ai-1  |     at handlers.sync-budget (/opt/node_app/node_modules/@actual-app/api/dist/app/bundle.api.js:38760:94)
actual-ai-1  |     at handlers.download-budget (/opt/node_app/node_modules/@actual-app/api/dist/app/bundle.api.js:38748:55)
actual-ai-1  |     at async handlers.api/download-budget (/opt/node_app/node_modules/@actual-app/api/dist/app/bundle.api.js:29478:32)
actual-ai-1  | [Exception] TypeError: Cannot read properties of undefined (reading 'timestamp')
actual-ai-1  |     at _fullSync (/opt/node_app/node_modules/@actual-app/api/dist/app/bundle.api.js:42483:98)
actual-ai-1  |     at /opt/node_app/node_modules/@actual-app/api/dist/app/bundle.api.js:42395:38
actual-ai-1  |     at /opt/node_app/node_modules/@actual-app/api/dist/app/bundle.api.js:43341:38
actual-ai-1  |     at initialFullSync (/opt/node_app/node_modules/@actual-app/api/dist/app/bundle.api.js:42381:38)
actual-ai-1  |     at handlers.sync-budget (/opt/node_app/node_modules/@actual-app/api/dist/app/bundle.api.js:38760:94)
actual-ai-1  |     at handlers.download-budget (/opt/node_app/node_modules/@actual-app/api/dist/app/bundle.api.js:38748:55)
actual-ai-1  |     at async handlers.api/download-budget (/opt/node_app/node_modules/@actual-app/api/dist/app/bundle.api.js:29478:32)
actual-ai-1  | Full error details {
actual-ai-1  |   message: "Cannot read properties of undefined (reading 'timestamp')",
actual-ai-1  |   reason: undefined,
actual-ai-1  |   meta: undefined
actual-ai-1  | }
actual-ai-1  | An error occurred: Error: Something went wrong trying to download that file, sorry! Visit https://actualbudget.org/contact/ for support. (reason: undefined)
actual-ai-1  |     at handlers.api/download-budget (/opt/node_app/node_modules/@actual-app/api/dist/app/bundle.api.js:29483:27)
actual-ai-1  | node:internal/process/promises:288
actual-ai-1  |             triggerUncaughtException(err, true /* fromPromise */);
actual-ai-1  |             ^
actual-ai-1  |
actual-ai-1  | Error: Something went wrong trying to download that file, sorry! Visit https://actualbudget.org/contact/ for support. (reason: undefined)
actual-ai-1  |     at handlers.api/download-budget (/opt/node_app/node_modules/@actual-app/api/dist/app/bundle.api.js:29483:27)
actual-ai-1  |
actual-ai-1  | Node.js v18.20.3
actual-ai-1 exited with code 1

Would it be possible to update to the latest version of the API, or at least provide guidance on how I could update my package.json or package-lock.json file to allow for the latest API version?

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.