79 lines
2.6 KiB
JavaScript
Executable File

#!/usr/bin/env node
// Note: mostly generated by ChatGPT, I am not a Javascript developer
const actual = require('@actual-app/api');
const yargs = require('yargs/yargs');
const { hideBin } = require('yargs/helpers');
(async () => {
const argv = yargs(hideBin(process.argv))
.option('account', {
alias: 'a',
type: 'string',
demandOption: true,
describe: 'The UUID of the account',
})
.option('payee', {
alias: 'p',
type: 'string',
demandOption: false,
describe: 'The name of the payee',
})
.option('amount', {
alias: 'm',
type: 'number',
demandOption: true,
describe: 'The amount in dollars (positive or negative)',
})
.option('date', { alias: 'd', type: 'string', demandOption: true, describe: 'The date in ISO format' })
.option('notes', { alias: 'n', type: 'string', demandOption: false, describe: 'Notes' })
.option('server', {
alias: 's',
type: 'string',
describe: 'Actual server URL (fallback if ACTUAL_SERVER is not set)',
})
.option('password', {
alias: 'w',
type: 'string',
describe: 'Password (fallback if ACTUAL_PASSWORD is not set)',
})
.option('sync-id', { alias: 'b', type: 'string', describe: 'UUID of the budget to connect to' })
.help()
.argv;
const serverURL = process.env.ACTUAL_SERVER || argv.server;
const password = process.env.ACTUAL_PASSWORD || argv.password;
const syncId = process.env.ACTUAL_SYNC_ID || argv.sync_id;
if (!serverURL || !password || !syncId) {
console.error('❌ Error: server URL, budget ID, and password must be provided (via CLI or environment)');
process.exit(1);
}
try {
await actual.init({
dataDir: './cache',
serverURL: serverURL,
password: password,
});
await actual.downloadBudget(syncId)
const amount = Math.round(argv.amount * 100); // Convert to milli-units
await actual.importTransactions(argv.account, [{
imported_payee: argv.payee,
payee_name: argv.payee ?? '',
amount,
date: argv.date, // today's date
notes: argv.notes ?? ''
}]);
console.log('✅ Transaction added successfully.');
await actual.shutdown();
} catch (err) {
console.error('❌ Error:', err.message || err);
process.exit(1);
}
})();