Automatisch You Need A Budget 集成实战四大触发器的原理、配置与源码解析【免费下载链接】automatischThe open source Zapier alternative. Build workflow automation without spending time and money.项目地址: https://gitcode.com/GitHub_Trending/au/automatisch本篇文章围绕开源自动化平台 Automatisch 内置的 You Need A BudgetYNAB应用集成展开重点讲解其在 docs 触发事件文档 中定义的四个触发器Category overspent、Goal completed、Low account balance 与 New transactions。读完本文你将掌握每个触发器的触发条件、轮询机制、可配置参数以及它们背后直接调用 YNAB API 的源码实现原理能够据此在 Automatisch 中搭建属于自己的预算自动化流程。一、YNAB 集成在 Automatisch 中的定位You Need A Budget 是一款基于零基预算理念的个人理财应用。在 Automatisch 中它作为一个标准应用集成存在应用定义位于 packages/backend/src/apps/you-need-a-budget/index.jsexport default defineApp({ name: You Need A Budget, key: you-need-a-budget, baseUrl: https://app.ynab.com, apiBaseUrl: https://api.ynab.com/v1, ... supportsConnections: true, beforeRequest: [addAuthHeader], auth, triggers, });关键信息一目了然API 基地址为https://api.ynab.com/v1所有触发器发出的 HTTP 请求都会以该地址为前缀该应用支持连接supportsConnections: true即必须先通过 OAuth 建立账户连接后才能使用触发器每个请求在发出前都会经过beforeRequest中注册的 add-auth-header.js自动为请求附加访问令牌全部四个触发器集中在 triggers/index.js 中统一注册导出。从apiBaseUrl: https://api.ynab.com/v1可以推断四个触发器都使用default 预算这一固定标识即GET /budgets/default/...也就是说它们监控的是用户在 YNAB 中当前选定的默认预算。二、四个触发器的总览根据 triggers.md 的 frontmatter 定义该应用共提供四个轮询型触发器触发器名称Key触发条件Category overspentcategoryOverspent某个类别超出其预算余额变为负数Goal completedgoalCompleted某个预算类别的储蓄目标达成Low account balancelowAccountBalance检查账户Checking/Savings余额低于指定金额New transactionsnewTransactions创建了新的交易记录四个触发器均未声明type: webhook因此全部走**轮询polling**模式。它们在定义中都通过defineTrigger注册而 define-trigger.js 会强制校验触发器必须设置pollInterval或声明为 webhook否则直接抛出Trigger must have a poll interval or be a webhook错误。轮询间隔与去重机制四个触发器的pollInterval统一为15分钟意味着 Automatisch 的调度器每 15 分钟执行一次对应的run($)函数。每次运行产出的数据通过$.pushTriggerItem({ raw, meta })推入流程raw交给下游步骤使用的原始数据这里是 YNAB 返回的 category / account / transaction 对象meta.internalId作为该条目的内部唯一标识。例如Category overspent使用${category.id}-${monthYear}作为 ID其中monthYear是DateTime.now().toFormat(MM-yyyy)luxon 库格式化出的MM-yyyy。这样做的好处是同一个月内同一个超支类别只触发一次避免每次轮询重复产生执行。三、Category overspent类别超支触发器该触发器的源码位于 triggers/category-overspent/index.jsexport default defineTrigger({ name: Category overspent, key: categoryOverspent, pollInterval: 15, description: Triggers when a category exceeds its budget, resulting in a negative balance., async run($) { const monthYear DateTime.now().toFormat(MM-yyyy); const categoryWithNegativeBalance []; const response await $.http.get(/budgets/default/categories); const categoryGroups response.data.data.category_groups; categoryGroups.forEach((group) { group.categories.forEach((category) { if (category.balance 0) { categoryWithNegativeBalance.push(category); } }); }); for (const category of categoryWithNegativeBalance) { $.pushTriggerItem({ raw: category, meta: { internalId: ${category.id}-${monthYear} }, }); } }, });工作原理拆解调用 YNAB APIGET /budgets/default/categories拉取默认预算的全部类别遍历响应中的category_groups类别分组及其下的每个categories筛选出category.balance 0的类别——这正对应文档描述的超出预算导致负余额将每个超支类别以internalId 类别ID 当前月份推入流程。典型使用场景当某个类别如餐饮超支时自动向 Slack / Telegram 发送提醒或把超支类别汇总写入 Google Sheets 用于月末复盘。四、Goal completed目标完成触发器源码位于 triggers/goal-completed/index.jsasync run($) { const monthYear DateTime.now().toFormat(MM-yyyy); const goalCompletedCategories []; const response await $.http.get(/budgets/default/categories); const categoryGroups response.data.data.category_groups; categoryGroups.forEach((group) { group.categories.forEach((category) { if (category.goal_percentage_complete 100) { goalCompletedCategories.push(category); } }); }); for (const category of goalCompletedCategories) { $.pushTriggerItem({ raw: category, meta: { internalId: ${category.id}-${monthYear} }, }); } }工作原理拆解同样读取GET /budgets/default/categories筛选出goal_percentage_complete 100的类别——YNAB 中为类别设置的储蓄目标完成度达到 100%即代表目标已完成按类别ID-月份去重后推送。与 Category overspent 的对比两者使用同一数据端点只是筛选条件不同一个看balance 0一个看goal_percentage_complete 100这体现了 Automatisch 中触发器同一数据源、不同判定逻辑的常见设计模式。可组合使用目标完成时向邮箱发送祝贺邮件或自动把已完成的储蓄目标记录到 Notion 看板。五、Low account balance账户余额过低触发器这是四个触发器中唯一带用户配置参数的触发器源码位于 triggers/low-account-balance/index.jsexport default defineTrigger({ name: Low account balance, key: lowAccountBalance, pollInterval: 15, description: Triggers when the balance of a Checking or Savings account falls below a specified amount within a given month., arguments: [ { label: Balance Below Amount, key: balanceBelowAmount, type: string, required: true, description: Account balance falls below this amount (e.g. 250.00), variables: true, }, ], async run($) { const monthYear DateTime.now().toFormat(MM-yyyy); const balanceBelowAmount $.step.parameters.balanceBelowAmount; const formattedBalance balanceBelowAmount * 1000; const response await $.http.get(/budgets/default/accounts); if (response.data?.data?.accounts?.length) { for (const account of response.data.data.accounts) { if (account.balance formattedBalance) { $.pushTriggerItem({ raw: account, meta: { internalId: ${account.id}-${monthYear} }, }); } } } }, });配置参数说明Balance Below Amount参数 key 为balanceBelowAmount必填类型为字符串表示余额低于该金额即触发。文档示例值为250.00。required: true意味着不填该参数流程无法保存/运行variables: true表示该参数支持引用上游步骤的变量例如可以把阈值做成动态值。关键的金额换算细节容易踩坑const formattedBalance balanceBelowAmount * 1000;YNAB API 返回的账户balance采用milliunits千分之一货币单位表示即250.00美元在 API 中实际返回为250000。因此源码将用户输入的250.00乘以 1000 得到250000再与account.balance比较从而保证比较基准一致。如果忽略这一换算触发结果将完全错误——这一点直接体现在源码中也是该触发器在实测中最常见的误区。触发范围遍历GET /budgets/default/accounts返回的全部账户涵盖 Checking、Savings 等只要余额低于阈值即触发因此单次运行可能推送多条数据。典型使用场景当活期账户余额低于某个警戒线时通过 ntfy / Pushover 推送通知或自动向自己邮箱发送提醒避免透支。六、New transactions新交易触发器源码位于 triggers/new-transactions/index.jsexport default defineTrigger({ name: New transactions, key: newTransactions, pollInterval: 15, description: Triggers when a new transaction is created., async run($) { const response await $.http.get(/budgets/default/transactions); const transactions response.data.data?.transactions; if (transactions?.length) { for (const transaction of transactions) { $.pushTriggerItem({ raw: transaction, meta: { internalId: transaction.id }, }); } } }, });工作原理拆解调用GET /budgets/default/transactions拉取默认预算下的交易列表使用可选链response.data.data?.transactions做空值保护没有交易时直接跳过对每条交易调用$.pushTriggerItem其internalId直接使用transaction.id。与前三者不同这里不拼接月份作为 internalId因为交易记录本身具有天然唯一 ID不存在同月重复问题。Automautisch 依赖该 internalId 做幂等去重——只有internalId变化的数据才会作为新条目触发下游流程这也是New transactions能准确识别新增的机制基础。典型使用场景每笔新消费自动记账到 Google Sheets、按交易金额触发不同的后续分支或把大额消费实时推送到 Discord。七、前置条件如何为触发器建立连接触发器必须依赖有效的 YNAB 账户连接才能运行。连接建立流程由 auth/index.js 定义需要的字段包括OAuth Redirect URL只读自动生成{WEB_APP_URL}/app/you-need-a-budget/connections/add需要在 YNAB 开发者后台配置的回调地址Screen Name该连接在界面中显示的名称Client ID / Client Secret在 YNAB Developer 后台创建应用后获得的凭证。授权流程的核心逻辑见 generate-auth-url.js它拼接https://app.ynab.com/oauth/authorize携带client_id、redirect_uri、response_typecode以及用于 CSRF 防护的随机state并将生成的 URL 存入$.auth。拿到授权码换取令牌后令牌过期时由 refresh-token.js 携带client_id、client_secret、refresh_token调用https://app.ynab.com/oauth/token刷新accessToken。注意连接建立需要 YNAB 开发者应用Client ID/Secret不属于当前开源仓库代码本身可自动完成的部分上述实现仅展示了 Automatisch 侧的 OAuth 处理方式。八、小结触发器对照速查表触发器数据端点apiBaseUrl 前缀下判定条件用户参数internalId 策略Category overspentGET /budgets/default/categoriescategory.balance 0无id-MM-yyyyGoal completedGET /budgets/default/categoriesgoal_percentage_complete 100无id-MM-yyyyLow account balanceGET /budgets/default/accountsaccount.balance 阈值×1000balanceBelowAmount必填id-MM-yyyyNew transactionsGET /budgets/default/transactions交易列表非空无transaction.id四个触发器统一采用 15 分钟轮询、统一的$.pushTriggerItem推送约定并在 triggers/index.js 中集中注册。理解它们的判定条件与金额换算细节后你就可以在 Automatisch 中组合这些触发器与任意下游应用把 YNAB 的预算数据变成自动化的输入源。如需查看更完整的连接配置说明可参考 You Need A Budget 连接文档。【免费下载链接】automatischThe open source Zapier alternative. Build workflow automation without spending time and money.项目地址: https://gitcode.com/GitHub_Trending/au/automatisch创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
