2026-10-13 · 原文发布日
从Gmail收据邮件中揪出重复扣款
这条n8n流程每分钟监听Gmail中含“receipt”等关键词的新邮件,解析出正文后交给Google Gemini提取商户、金额、币种、交易时间和参考号等结构化字段,校验为成功扣款后规范化格式并生成确定性交易ID,再与Google Sheets里近48小时的记录比对,商户、金额、币种一致即标记疑似重复,追加到表格并向Slack发提醒,最后给邮件打上已处理标签。时间窗可自行调整。
原文要点
该n8n模板每分钟触发一次,按关键词(如receipt)搜索Gmail新邮件,解析MIME正文取纯文本与发件人、主题、线程ID、收件时间;交给Google Gemini抽取商户、金额、币种、交易时间、参考号、类型六个字段并解析JSON;校验为成功扣款后规范化字段、生成确定性交易ID,与Google Sheets近48小时记录按商户+金额+币种比对判定疑似重复,追加到表格、向Slack发提醒,最后给邮件打已处理标签。时间窗默认48小时可在代码节点调整。
这次做成什么
搭一条自动防线:收据邮件一到Gmail就被解析、查重、记账并告警,手工只做异常确认。先用三封合成邮件(含一封重复扣款)做端到端练习,验证判定逻辑后再接真实邮箱。
准备什么
- 一个Gmail账号及n8n中已授权的Gmail OAuth2凭据
- Google AI Studio中可用的Gemini API密钥
- 一张含Transactions工作表的Google Sheets及凭据
- 一个Slack工作区、可发消息的应用凭据和目标频道
- n8n实例(自托管或Cloud均可)
具体怎么做
建表并准备测试邮件
在Google Sheets新建表格,建工作表Transactions,列依次为:transaction_id、merchant、amount、currency、transaction_timestamp、reference、email_message_id、duplicate_status。用第二个邮箱给目标Gmail发三封自拟收据:A商店29.99元一封,隔几分钟再发内容相同但参考号不同的一封(模拟重复扣款),再发一封B商店15.00元。
导入模板并接Gmail
在n8n导入该模板,打开Gmail Trigger节点绑定OAuth2凭据,搜索词先设为subject:receipt。找到末尾打标签节点,在Gmail里先手动创建一个名为processed的标签,把其标签ID填进节点,否则邮件无法标记已处理。
配置Gemini抽取节点
在Gemini(PaLM)凭据中填入AI Studio密钥,确认所选模型在你的账号可用。检查提示词是否要求只返回JSON且包含merchant、amount、currency、transaction_datetime、reference、type六个键;把金额约定为数字、币种用三位代码(CNY/USD)。
接Sheets与Slack并跑通
Sheets节点选择你的表格和Transactions工作表;Slack节点选告警频道,消息模板引用商户、金额、两笔交易参考号。手动执行一次,确认三封邮件各产生一行,重复那封duplicate_status为suspected且Slack收到提醒,三封邮件均被打上processed标签。
调窗口后上线
打开查重代码节点,把48小时按需要改为24或72小时(代码中以毫秒或小时计算,改前看清单位),保存并激活工作流。
可直接复制的材料
Gemini结构化抽取提示词(本站编写,替换模板内提示词前先用它核对输出格式)
占位符{{$json.body}}需按你工作流中正文变量实际路径替换
你是收据解析器。从下面的邮件正文中提取交易信息,只输出一个JSON对象,不要输出任何其他文字。字段:merchant(商户名,字符串)、amount(金额,纯数字不带符号)、currency(三位币种代码如CNY、USD)、transaction_datetime(ISO 8601格式)、reference(订单号或交易参考号,没有则为null)、type(charge表示成功扣款,refund表示退款,other表示其他)。若邮件不是收据或无法确定金额,输出{"type":"other"}。邮件正文:
{{$json.body}}Transactions表头与首行示例数据
本站合成示例,第二行为同商户同金额48小时内重复,应被判为suspected
transaction_id,merchant,amount,currency,transaction_timestamp,reference,email_message_id,duplicate_status
tx_20261013_a1f2,咖啡云旗舰店,29.99,CNY,2026-10-13T09:15:00+08:00,ORD-8801,msg_001,clear
tx_20261013_b3c4,咖啡云旗舰店,29.99,CNY,2026-10-13T09:41:00+08:00,ORD-8802,msg_002,suspectedSlack告警消息模板
字段路径按你查重节点实际输出调整;本模板为本站编写
⚠️ 疑似重复扣款
商户:{{$json.merchant}}
金额:{{$json.amount}} {{$json.currency}}
本次参考号:{{$json.reference}}
命中历史交易:{{$json.matched_transaction_id}}({{$json.matched_timestamp}})
请人工核对后再决定是否申诉退款。输入与输出示例
本站虚构演示,未实际运行,交易ID为示意格式
输入
两封测试邮件:第一封主题"receipt - 咖啡云旗舰店",正文"订单 ORD-8801 已支付 ¥29.99(CNY),2026-10-13 09:15";26分钟后第二封主题相同,正文"订单 ORD-8802 已支付 ¥29.99(CNY),2026-10-13 09:41"。对应输出
Sheets新增两行:tx_..._a1f2 / 咖啡云旗舰店 / 29.99 / CNY / ...09:15 / ORD-8801 / clear;tx_..._b3c4 / 咖啡云旗舰店 / 29.99 / CNY / ...09:41 / ORD-8802 / suspected。Slack收到"疑似重复扣款:咖啡云旗舰店 29.99 CNY"提醒,两封邮件均带processed标签。做完检查这些
- 两封同商户同金额邮件中,第二封duplicate_status为suspected且Slack有对应提醒
- 商户相同但金额不同(如29.99与39.99)的邮件判为clear不告警
- 每封处理过的邮件在Gmail中都带processed标签且不会被重复处理
- 非收据邮件(type为other)不会写入Transactions表
容易卡住的地方
- processed标签必须先在Gmail手动创建并填标签ID,否则打标节点报错
- Gemini返回带markdown代码块的JSON会导致解析失败,提示词中必须禁止多余文字
- 币种不一致(CNY与USD)不会判重,跨币种重复扣款需另行处理
- 每分钟轮询依赖n8n触发器正常运行,实例停机期间邮件会在恢复后补处理但时间窗仍以交易时间算
本站借助AI整理来源事实,独立编写中文操作指南与示例。示例不代表实际运行结果;来源效果尚未由本站独立复现。付费模板与模型、服务费用分别计算。
- 原文标题
- Detect duplicate payment charges from Gmail using Gemini, Google Sheets and Slack
- 原作者
- WeblineIndia
- 原始发布日期
- 2026-10-13T07:05:34.082Z
- 来源
- https://n8n.io/workflows/20859