diff --git a/packages/api/methods.ts b/packages/api/methods.ts index bc69223e2672ee0dfd67437d0101ac2fa51a5c7a..63f23ae30dc31c042eef8e58ca98c5b1b742a5a1 100644 --- a/packages/api/methods.ts +++ b/packages/api/methods.ts @@ -35,6 +35,10 @@ export async function sync() { return send('api/sync'); } +export async function runBankSync(args?: { accountId: string }) { + return send('api/bank-sync', args); +} + export async function batchBudgetUpdates(func) { await send('api/batch-budget-start'); try { diff --git a/packages/loot-core/src/client/actions/account.ts b/packages/loot-core/src/client/actions/account.ts index 52b41608d1b437c27bfe9e49b5fcc815052eddee..c0d89874a3248fcbf654aeeac4f028b431340804 100644 --- a/packages/loot-core/src/client/actions/account.ts +++ b/packages/loot-core/src/client/actions/account.ts @@ -105,7 +105,7 @@ export function syncAccounts(id?: string) { // Perform sync operation const { errors, newTransactions, matchedTransactions, updatedAccounts } = - await send('gocardless-accounts-sync', { + await send('accounts-bank-sync', { id: accountId, }); diff --git a/packages/loot-core/src/server/api.ts b/packages/loot-core/src/server/api.ts index 93457027fd51cc22667bdb98067ee6fd46d190e6..b49ef58f18893ad369c33e7528e3761134ad9501 100644 --- a/packages/loot-core/src/server/api.ts +++ b/packages/loot-core/src/server/api.ts @@ -3,6 +3,7 @@ import { getClock } from '@actual-app/crdt'; import * as connection from '../platform/server/connection'; import { + getBankSyncError, getDownloadError, getSyncError, getTestKeyError, @@ -233,6 +234,17 @@ handlers['api/sync'] = async function () { } }; +handlers['api/bank-sync'] = async function (args) { + const { errors } = await handlers['accounts-bank-sync']({ + id: args?.accountId, + }); + + const [firstError] = errors; + if (firstError) { + throw new Error(getBankSyncError(firstError)); + } +}; + handlers['api/start-import'] = async function ({ budgetName }) { // Notify UI to close budget await handlers['close-budget'](); diff --git a/packages/loot-core/src/server/main.ts b/packages/loot-core/src/server/main.ts index 5b0ee4f93065155b7deb31933ebc91110af0ce90..33d30933c5741a06c1be4631db1ca67b6d8b9f39 100644 --- a/packages/loot-core/src/server/main.ts +++ b/packages/loot-core/src/server/main.ts @@ -1037,7 +1037,7 @@ handlers['gocardless-create-web-token'] = async function ({ } }; -handlers['gocardless-accounts-sync'] = async function ({ id }) { +handlers['accounts-bank-sync'] = async function ({ id }) { const [[, userId], [, userKey]] = await asyncStorage.multiGet([ 'user-id', 'user-key', @@ -1045,8 +1045,8 @@ handlers['gocardless-accounts-sync'] = async function ({ id }) { const accounts = await db.runQuery( `SELECT a.*, b.bank_id as bankId FROM accounts a LEFT JOIN banks b ON a.bank = b.id - WHERE a.tombstone = 0 AND a.closed = 0 AND a.id = ?`, - [id], + WHERE a.tombstone = 0 AND a.closed = 0 ${id ? 'AND a.id = ?' : ''}`, + id ? [id] : [], true, ); @@ -1059,7 +1059,7 @@ handlers['gocardless-accounts-sync'] = async function ({ id }) { const acct = accounts[i]; if (acct.bankId) { try { - console.group('Bank Sync operation'); + console.group('Bank Sync operation for account:', acct.name); const res = await bankSync.syncAccount( userId, userKey, diff --git a/packages/loot-core/src/shared/errors.ts b/packages/loot-core/src/shared/errors.ts index e081481ff2891e7d112286d71560a248f1364271..a6489b1e8bee2bdaf8c107c560c6485d64fd7f05 100644 --- a/packages/loot-core/src/shared/errors.ts +++ b/packages/loot-core/src/shared/errors.ts @@ -92,6 +92,10 @@ export function getSyncError(error, id) { } } +export function getBankSyncError(error: { message?: string }) { + return error.message || 'We had an unknown problem syncing the account.'; +} + export class LazyLoadFailedError extends Error { type = 'app-init-failure'; meta = {}; diff --git a/packages/loot-core/src/types/api-handlers.d.ts b/packages/loot-core/src/types/api-handlers.d.ts index d5fbd3ba5cdcbdbb7e7e180cec3a3e596a8af5e0..7be7f4119e9f90f2d4b26a92565af37deadf29d1 100644 --- a/packages/loot-core/src/types/api-handlers.d.ts +++ b/packages/loot-core/src/types/api-handlers.d.ts @@ -96,6 +96,8 @@ export interface ApiHandlers { 'api/sync': () => Promise<void>; + 'api/bank-sync': (arg?: { accountId: string }) => Promise<void>; + 'api/accounts-get': () => Promise<APIAccountEntity[]>; 'api/account-create': (arg: { account; initialBalance? }) => Promise<string>; diff --git a/packages/loot-core/src/types/server-handlers.d.ts b/packages/loot-core/src/types/server-handlers.d.ts index 88370eaf38135187fc3c0fe90bbefdacaf807d32..8a643803ba4cc5ba3883e3d15506c2a10fcaa89e 100644 --- a/packages/loot-core/src/types/server-handlers.d.ts +++ b/packages/loot-core/src/types/server-handlers.d.ts @@ -213,7 +213,7 @@ export interface ServerHandlers { | { error: 'failed' } >; - 'gocardless-accounts-sync': (arg: { id: string }) => Promise<{ + 'accounts-bank-sync': (arg: { id?: string }) => Promise<{ errors; newTransactions; matchedTransactions; diff --git a/upcoming-release-notes/2683.md b/upcoming-release-notes/2683.md new file mode 100644 index 0000000000000000000000000000000000000000..79717b7822b08139f5485e424b0aea633f3a7b5b --- /dev/null +++ b/upcoming-release-notes/2683.md @@ -0,0 +1,6 @@ +--- +category: Features +authors: [MatissJanis] +--- + +API: ability to run 3rd party bank-sync (GoCardless, SimpleFin) programmatically using `@actual-app/api`.