2026-09-05 · 原文发布日
Telegram拍发票,AI按规则审报销
这个n8n模板把员工报销搬上Telegram:员工给bot发收据照片,GPT-4o-mini的视觉能力提取商家、日期、金额、币种、税额、类别,随后对照Google Sheets里的报销政策表和历史记录查重,自动放行限额内的、退回无法辨认的、拒绝不合规的,存疑或超额的发给经理在Telegram里点批准或驳回。结果全部入表,月初自动汇总HTML月报邮件给财务。
原文要点
该n8n模板由Telegram触发器收收据照片并取最大尺寸图,无照片则回消息提醒。用GPT-4o-mini视觉提取商家、日期、总额、币种、税额、类别和置信度,从Google Sheets的Policy标签页读规则(Category|LimitPerReceipt|ApprovalAbove|Allowed|Notes),在Expenses标签页查重复收据键。逻辑:限额内自动批准、重复或字段缺失退回、不允许或超类别限额拒绝、超限或低置信度或超60天票龄发经理审批,Telegram按钮最长等3天。结果写入Expenses并回复员工,批准照片转发财务群;每月1日8点汇总批准记录生成HTML月报经Gmail发财务。置信度下限70%。
这次做成什么
搭一条“员工拍发票→AI读票→按自己的报销规则表自动批准/退回/拒绝/转经理→入表→月初邮件汇总”的完整链路。本页给出可直接复制的视觉提取提示词、两张表的示例数据和判定代码,先用合成数据走通再换真实凭据。
准备什么
- n8n实例且有公网URL(经理批准按钮要经webhook恢复流程)
- Telegram机器人token(@BotFather免费申请)及经理、财务群的chat ID
- OpenAI API密钥且账号可用gpt-4o-mini模型
- Google OAuth2凭据(Sheets权限)和一个含Policy、Expenses两个标签页的表格
- Gmail连接凭据和接收月报的财务邮箱
具体怎么做
建报销政策与记录两张表
在Google Sheets新建表格。Policy表首行填 Category | LimitPerReceipt | ApprovalAbove | Allowed | Notes;Expenses表首行填 SubmittedAt | Employee | TelegramUserId | ChatId | Merchant | Date | Amount | Currency | Tax | Category | Description | Status | Decision | DecisionNote | ReceiptFileId | Month。把下方artifact的CSV内容粘贴进对应表,记下spreadsheet ID。
接Telegram触发并取照片
用Telegram Trigger节点监听机器人消息,后面接Telegram的get file/download操作取附件中最大尺寸的收据照片;加一个IF判断消息里有没有photo,没有就用Telegram节点回复“请把收据以照片形式发送”。
AI视觉提取票面字段
把图片发给OpenAI节点的gpt-4o-mini模型,提示词用下方artifact中的完整版本,要求只输出JSON。随后用Code节点把金额转数字、日期统一成YYYY-MM-DD、类别映射到Policy里的类目,并生成重复检查键(如商家+日期+金额)。
按规则判定四种结果
读取Policy表,在Expenses表按重复键查重。判定顺序与模板逻辑一致:重复→拒绝;照片不可读(字段缺失或置信度极低)→退回员工重拍;Allowed为否或超过LimitPerReceipt→拒绝;金额超过ApprovalAbove、识别置信度低于0.7或票龄超过60天→转经理审批;其余自动批准。用Switch节点实现这些分支。
经理审批与结果落地
对需审批项用Telegram的Send and Wait发带批准/驳回按钮的消息给经理chat ID,等待上限3天,超时按驳回处理。所有结果append到Expenses表,Telegram回复员工结论和原因,批准的收据照片转发到财务群。
月初自动生成月报
加Schedule Trigger设为每月1日8点,读取Expenses中Status为批准且Month为上月的记录,用Code节点按员工和类别汇总金额生成HTML,再经Gmail节点发给财务邮箱。
可直接复制的材料
收据视觉提取提示词(本站独立编写)
类别清单需与Policy表Category列一致;此为提示词示例,实际节点名以原模板为准。
你是一名报销票据识别助手。请阅读这张收据照片,只输出一个JSON对象,不要输出任何其他文字。字段如下:merchant(商家名称)、date(开票日期,统一为YYYY-MM-DD,无法判断填null)、total(含总额的数字)、currency(币种代码,如CNY/USD/EUR)、tax(税额数字,没有填0)、category(从以下类别中选一个:餐饮、交通、住宿、办公用品、其他)、description(一句话概括消费内容)、confidence(你对整体识别结果的置信度,0到1之间的小数)。如果照片不是收据、严重模糊或关键信息不可读,请将confidence设为低于0.3并在description中说明原因。Policy表示例数据
合成示例,限额与阈值请按公司制度替换。
Category,LimitPerReceipt,ApprovalAbove,Allowed,Notes
餐饮,300,200,是,仅限工作日午餐
交通,500,400,是,含打车与高铁
住宿,800,600,是,需出差审批单
办公用品,200,150,是,
娱乐,0,0,否,一律不予报销判定逻辑Code节点示例(JavaScript)
本站独立编写的判定示例,60天票龄检查可按需在此补充日期比较;节点名引用需改成你流程里的实际节点名。
const e = $json; // AI提取并规范化后的票面数据
const policy = $('Read Policy').first().json; // 匹配到的政策行
const duplicate = $('Check Duplicates').first().json.found;
let status, note;
if (duplicate) { status = 'rejected'; note = '重复提交'; }
else if (e.confidence < 0.3 || !e.date || !e.total) { status = 'returned'; note = '照片不清晰或字段缺失,请重拍'; }
else if (e.confidence < 0.7) { status = 'pending_manager'; note = '识别置信度偏低,需经理确认'; }
else if (policy.Allowed !== '是') { status = 'rejected'; note = '类别不允许报销'; }
else if (e.total > Number(policy.LimitPerReceipt)) { status = 'rejected'; note = '超过单笔限额'; }
else if (e.total > Number(policy.ApprovalAbove)) { status = 'pending_manager'; note = '超过自动批准线'; }
else { status = 'approved'; note = '限额内自动批准'; }
return [{ json: { ...e, status, decisionNote: note } }];Expenses表一行测试数据
全部为合成测试数据,不要使用真实员工信息。
SubmittedAt,Employee,TelegramUserId,ChatId,Merchant,Date,Amount,Currency,Tax,Category,Description,Status,Decision,DecisionNote,ReceiptFileId,Month
2026-09-10 12:31,测试员工A,100001,200001,示例咖啡连锁(虚构),2026-09-10,86.00,CNY,4.87,餐饮,团队工作午餐,approved,auto,限额内自动批准,file_test_001,2026-09输入与输出示例
本站虚构演示,未实际运行流程;金额为合成值,不代表真实识别结果。
输入
测试员工A向机器人发送一张虚构收据照片:示例咖啡连锁(虚构),2026-09-10,合计86.00元(税额4.87元),类别餐饮;Policy中餐饮限额300、批准线200、允许报销;Expenses表无同键记录,AI置信度0.93。对应输出
判定结果 status=approved,decisionNote=限额内自动批准;机器人回复员工:“报销已自动批准:示例咖啡连锁(虚构) 86.00 CNY(餐饮)”;Expenses表追加上述artifact中的那行记录,ReceiptFileId=file_test_001;收据照片转发至财务群;该笔计入2026-09月报。做完检查这些
- Policy与Expenses两个标签页首行与本页列名完全一致,spreadsheet ID已填入所有Google Sheets节点
- 发送无照片的文字消息时,机器人回复提示用照片提交收据
- 金额86元低于批准线200时状态为approved并回复员工,金额500元(超批准线但未超限额500边界外类别)进入经理待审
- 同一商家+日期+金额再次提交时被识别为重复并拒绝
- Telegram批准按钮点击后流程能恢复执行,说明n8n公网URL和webhook配置正确
容易卡住的地方
- 经理批准/驳回按钮依赖n8n的公网webhook,本地无公网地址时审批会卡住
- Send and Wait默认等待3天,超时分支未配置会导致单据悬挂
- Policy表Allowed列的值(是/否)必须与判定代码中的比较字符串一致,否则全部误判
- 置信度下限0.7和票龄60天是模板默认值,改动后两张表口径要同步
- OpenAI、Telegram、Google、Gmail四类凭据缺一就会在对应节点报错,先用测试账号逐段验证
- GPT-4o-mini读图按次计费(原文称每张约一美分),批量测试时注意用量
本站借助AI整理来源事实,独立编写中文操作指南与示例。示例不代表实际运行结果;来源效果尚未由本站独立复现。付费模板与模型、服务费用分别计算。
- 原文标题
- Track employee expense receipts from Telegram with GPT-4o-mini and Google Sheets
- 原作者
- Vitaliy Voitik
- 原始发布日期
- 2026-09-04T23:03:13.401Z
- 来源
- https://n8n.io/workflows/19225