十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Actual Budget 对接 Akahu 实现新西兰银行账户自动同步:配置实战与源码解析

Actual Budget 对接 Akahu 实现新西兰银行账户自动同步:配置实战与源码解析 Actual Budget 对接 Akahu 实现新西兰银行账户自动同步配置实战与源码解析【免费下载链接】actualA local-first personal finance app项目地址: https://gitcode.com/GitHub_Trending/ac/actual本篇技术指南以 Actual Budget本地优先的个人财务管理应用官方文档 Akahu Setup 为核心系统讲解如何通过 Akahu 服务将新西兰银行账户接入 Actual 的 Bank Sync 功能从注册 Akahu 开发者应用、获取双令牌到在 Actual 中开启实验特性、粘贴凭据、链接账户并深入同步服务器源码剖析令牌校验、账户拉取与交易导入的完整链路。读完本文你将能独立完成 Akahu 银行同步的端到端配置并理解其背后的数据流与关键实现细节。适用范围本文面向使用 Actual Budget 桌面客户端 / 自托管同步服务器、且持有新西兰银行账户的用户。Akahu 仅支持新西兰银行NZ banks其余银行请参考 GoCardless、SimpleFIN、Enable Banking 或 Pluggy.ai 文档。一、功能定位与启用前提这是一项实验特性Akahu 银行同步在 Actual 中属于实验特性Experimental Feature原文档开篇即给出提示该功能在最新稳定版中可能尚未全部可用且需使用nightly镜像才能获得最新实现。因此正式配置前必须先明确两点功能开关akahuBankSync特性标志默认关闭需要用户手动开启见 Experimental Features。版本要求建议使用 nightly 构建的镜像与客户端以保证与文档描述一致的行为。从桌面客户端源码可以看到该开关的具体定义位于 Experimental.tsxFeatureToggle flagakahuBankSync feedbackLinkhttps://github.com/actualbudget/actual/issues/8020 TransAkahu Bank Sync (NZ banks)/Trans /FeatureToggle其中flagakahuBankSync与prefs.ts中定义的实验特性键akahuBankSync见 prefs.ts一一对应issueId8020也是原文档ExperimentalFeatureWarning issueId8020 /警告组件的来源。在 Actual 界面中开启实验特性的路径为Settings → Show advanced settings → Experimental features同意免责声明后即可在特性列表中看到 Akahu Bank Sync (NZ banks) 选项并开启。二、准备工作注册 Akahu 账户并获取双令牌Akahu 是新西兰本土的银行数据聚合服务用户需要先在 Akahu 侧完成开发者应用创建拿到两个关键凭据凭据获取位置用途APP ID Tokenmy.akahu.nz 开发者页面标识你的开发者应用由 Actual 同步服务器用它实例化 AkahuClientUser Access Tokenmy.akahu.nz 开发者页面授权访问你名下已关联的银行账户数据完整准备步骤如下注册并登录 Akahu 账户my.akahu.nz先在 Akahu 中关联一个银行账户——这是后续拉取账户列表与交易的前提进入开发者页面my.akahu.nz/developers获取APP ID Token和User Access Token。原文档特别提醒如果尚未创建个人应用需要同意 Akahu 的开发者条款Developer Terms点击标记为 Continue 的按钮随后还需完成身份验证identity verification并设置多因素认证MFA。这些步骤全部完成后应用才会被创建两个 Token 才会展示给你。从 AkahuInitialiseModal.tsx 的界面文案也能印证这一点——该弹窗明确说明仅适用于新西兰银行并引导用户前往 Akahu 创建账户以生成令牌。三、在 Actual 中配置 Akahu 凭据Set up拿到双令牌后回到 Actual Budget 进行凭据配置进入More → Bank Sync更多 → 银行同步页面在Akahu卡片上点击Set up在弹出的对话框中分别粘贴App ID Token与User Access Token点击Save and continue。前端弹窗的实现位于 AkahuInitialiseModal.tsx关键行为如下表单包含两个密码类型输入框App ID Token字段 id 为appToken-field与User Access Token字段 id 为userToken-field见 AkahuInitialiseModal.tsx任一字段为空时校验失败并提示It is required to provide a User Token and an App Token.提交时依次调用secret-set方法写入名为akahu_userToken、akahu_appToken的两个密钥见 AkahuInitialiseModal.tsx保存成功后回调onSuccess()Bank Sync 页面中的 Akahu 卡片随即标记为已配置。这里有两个值得注意的工程细节令牌以密钥secret形式存储于同步服务器而非明文写进预算文件前端useAkahuStatus钩子通过akahu-status方法查询当前是否已配置见 useAkahuStatus.ts。权限控制在 useBuiltInBankSyncProviders.ts 中canConfigureProviders isAdmin即只有同步服务器的管理员才能配置凭据非管理员用户打开 Bank Sync 页面时会收到权限警告getPermissionWarning函数见 useBuiltInBankSyncProviders.ts。服务端令牌校验/status 端点同步服务器侧/akahu/status端点负责返回配置状态见 app-akahu.tsapp.post(/status, handleError(async (_req, res) { const userToken secretsService.get(SecretName.akahu_userToken); const appToken secretsService.get(SecretName.akahu_appToken); const configured userToken ! null appToken ! null; res.send({ status: ok, data: { configured } }); }));可见已配置的定义非常直接两个令牌同时存在即视为 configured。桌面端据此控制 Akahu 卡片显示Set up还是Link bank account。四、链接银行账户Link bank account凭据配置完成后在同一个 Bank Sync 页面点击 Akahu 卡片下的Link bank account按提示选择要关联的账户即可完成链接。这一流程在前端由 useBuiltInBankSyncProviders.ts 的onConnectAkahu驱动分为三步拉取外部账户列表调用akahu-accounts方法将结果规范化为统一的SyncServerAkahuAccount结构account_id、name、institution、orgDomain、orgId、balance该类型定义见 akahu.ts弹出选择弹窗通过select-linked-accounts模态框SelectLinkedAccountsModal.tsx让用户勾选要同步的账户并设置syncSource: akahu建立关联最终调用akahu-accounts-link方法。在 loot-core 服务端akahuAccounts见 app.ts负责转发账户列表请求linkAkahuAccount见 app.ts负责落库。链接时区分两种场景升级已有账户传upgradingId仅更新该账户的account_id、bank与account_sync_source: akahu字段见 app.ts新建账户插入一条带account_sync_source: akahu的新账户记录并为其创建空的转账 payee见 app.ts。链接成功后随即触发首次同步bankSync.syncAccount。三个相关 RPC 方法的注册位于 app.ts。五、同步链路从桌面端到 Akahu 再到账户理解完配置再看数据是如何拉取的。整体链路分为四段均有源码可循1. 桌面端 / loot-core 发起下载loot-core 的downloadAkahuTransactions见 sync.ts向同步服务器发起 POST 请求const res await post( getServer().AKAHU_SERVER /transactions, { accountId: acctId, startDate: since }, { X-ACTUAL-TOKEN: userToken }, 60000, );请求体只含两个字段accountId外部账户 ID与startDate起始日期并携带 60 秒超时。服务器地址由 server-config.ts 拼装AKAHU_SERVER joinURL(url, /akahu)。2. 同步服务器路由挂载同步服务器把 Akahu 处理器挂载在/akahu前缀下见 app.tsapp.use(/akahu, akahuApp.handlers)。整个实现位于 app-akahu.ts使用官方akahuSDK 的AkahuClient与 Akahu API 交互提供三个端点端点职责POST /akahu/status检查双令牌是否已配置POST /akahu/accounts列出用户已关联的银行账户POST /akahu/transactions拉取指定账户的交易与余额3. 交易拉取的核心逻辑/transactions端点是数据量最大的环节其处理逻辑值得逐段拆解见 app-akahu.ts参数校验accountId与startDate缺一不可否则返回accountId and startDate are required令牌校验任一令牌缺失时返回Missing user or app token刷新账户数据getRefreshedAccount见 app-akahu.ts先检查account.refreshed.transactions时间戳若距今超过 1 小时AKAHU_TRANSACTION_REFRESH_INTERVAL_MS 60 * 60 * 1000见 app-akahu.ts则调用akahu.accounts.refreshAll强制刷新并最多轮询 5 次每次间隔 3 秒等待刷新完成——若账户余额不可用直接返回Account balance unavailable防竞态刷新过程用createMutex()加互斥锁见 app-akahu.ts避免多个账户同时触发 refreshAll 造成 Akahu 侧冲突分页拉取endDate固定为下个月 1 日通过cursor游标循环拉取全部已入账booked交易见 app-akahu.ts待入账交易额外调用listPendingTransactions拉取 pending 交易时区处理Akahu 返回 UTC 日期代码用Intl.DateTimeFormat按Pacific/Auckland时区转换后再拼接为YYYY-MM-DD见 app-akahu.ts保证新西兰用户看到的日期与本地一致金额单位convertToCents将浮点金额转为整数分见 app-akahu.ts余额上报返回expected当前余额与可选的interimAvailable可用余额两类余额见 app-akahu.ts交易分类按booked/pending/all三组输出并按sortOrder即交易时间戳降序排列。4. 交易字段归一化原始交易经processTransaction/processPendingTransaction处理后统一成 Actual 的交易结构见 app-akahu.tspayee 名优先取merchant.name其次取meta.other_account转账对方账户兜底用description见getPayeeNameapp-akahu.ts备注使用交易的description分类若 Akahu 侧已提供分类则透传category.name标识booked 交易保留transactionId: trans._id用于去重币种默认取账户余额币种兜底为NZD。5. 回到 loot-core 落账同步服务器返回后loot-core 侧processBankSyncDownload前的分发逻辑位于 sync.ts当account_sync_source akahu时调用downloadAkahuTransactions。此外起始余额starting balance的推算也针对 Akahu 做了特化处理见 sync.ts以服务器返回的startingBalance为基准逐笔减去交易金额倒推期初余额从而保证首笔交易前的余额准确。六、解除配置与常见问题排查解除 Akahu 配置在 Bank Sync 页面 Akahu 卡片上执行 reset前端onAkahuReset会依次把akahu_userToken与akahu_appToken置为null见 useBuiltInBankSyncProviders.ts成功后卡片回到未配置状态。常见错误与含义现象可能原因处理建议Missing user or app token两个令牌未同时保存重新执行 Set up完整粘贴两个 TokenaccountId and startDate are required请求参数缺失检查外部账户是否正常关联重新执行 Link bank accountAccount not found账户 ID 失效或已被删除在 Akahu 开发者后台确认银行账户仍在关联列表中Account balance unavailable刷新后仍拿不到余额稍后重试确认 Akahu 侧银行账户状态正常Failed to fetch transactions: ...Akahu API 返回异常检查令牌是否过期必要时在 Akahu 开发者页面重新生成从源码看/accounts与/transactions端点都通过try/catch捕获异常并把错误信息随响应返回见 app-akahu.ts、app-akahu.tsloot-core 侧再依据error_code/error字段抛出对应BankSyncError见 sync.ts因此排查时应优先查看 Bank Sync 页面与日志中的错误文案。七、小结Akahu 银行同步是 Actual Budget 多银行同步体系中的新西兰专属通道。配置侧只需四步开启实验特性 → 注册 Akahu 获取双令牌 → Set up 粘贴凭据 → Link bank account 选择账户实现侧则由桌面端loot-core与自托管同步服务器协同完成令牌以密钥形式存储于服务器交易经/akahu/transactions端点分页拉取、按新西兰时区归一化日期、归一化 payee 与分类后回流落账。若你正在自托管 Actual且持有新西兰银行账户可按本文步骤直接上手遇到异常时对照错误表结合上述源码路径即可快速定位。相关源码路径速查官方文档akahu.md、experimental/index.md同步服务器实现app-akahu.ts、挂载点 app.ts桌面端界面AkahuInitialiseModal.tsx、useBuiltInBankSyncProviders.ts、useAkahuStatus.ts、特性开关 Experimental.tsx核心数据层app.tslinkAkahuAccount、sync.tsdownloadAkahuTransactions、server-config.ts、类型定义 akahu.ts【免费下载链接】actualA local-first personal finance app项目地址: https://gitcode.com/GitHub_Trending/ac/actual创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表