AI PLAY玩法更新持续收录
← 回到更新流

2026-09-04 · 原文发布日

拍照转发单据自动建档并邮件提醒运营

给运营团队用的单据入口流程:把业务单据照片POST到webhook,OpenAI视觉模型按指令返回结构化JSON(单据类型、金额、币种、日期、置信度等),可识别的记录写入Postgres并把摘要邮件发给运营;无法识别的也发一封“无法读取”通知而不是静默失败。每天早上还会查超过24小时未关闭的单据,邮件催办清单。

原文要点

原文描述一条单据入口工作流:webhook接收POST来的image_url或image_base64及可选doc_type、note、submitter;校验有图后调用OpenAI gpt-5.6-terra视觉模型,要求返回结构化JSON;解析出单据类型、标题、摘要、金额、币种、日期、置信度;可识别时UPSERT进Postgres的biz_documents表(doc_id唯一,有status字段)并用Gmail发摘要给运营;缺图或无法识别时发“无法读取”邮件;每天08:00(Asia/Jakarta)查超过24小时未标记done的单据,邮件催办。模板未附可下载文件,表结构以模板说明为准。

这次做成什么

搭一条“webhook收单据照片→视觉模型抽取结构化JSON→Postgres建档→Gmail摘要/异常通知→每日催办”的单据入口流程,并用一张虚构发票图片URL完成端到端测试。

准备什么

  • 可访问的n8n实例,能对外暴露webhook URL(自托管需公网可达)
  • OpenAI API Key,且账户能访问gpt-5.6-terra这一视觉模型
  • 一个Postgres数据库及有建表、写表权限的账号
  • Gmail账号并完成OAuth2授权,可代发邮件
  • 运营收件邮箱地址,用于摘要、异常和催办三处收件人
  • 用于测试的图片公网URL或可转成base64的单据照片

具体怎么做

  1. 建Postgres表

    在Postgres执行下方材料C的建表SQL,得到biz_documents表(doc_id唯一约束、status默认open)。在n8n凭据里添加Postgres连接并用SELECT 1测试连通。

  2. 配置webhook入口

    新建工作流,加Webhook节点,HTTP方法POST,路径填docintake,响应模式选“立即响应”或“最后节点响应”均可(练习选最后节点响应便于看结果)。保存后复制Test URL。

  3. 校验是否带图

    加IF节点,条件为{{$json.body.image_url}}不为空或{{$json.body.image_base64}}不为空。为空的分支直接连Gmail节点发“无法读取单据:未检测到图片”通知给运营邮箱,并结束。

  4. 调用视觉模型抽取字段

    有图分支加OpenAI节点(Chat Completions),模型填gpt-5.6-terra,消息用下方材料D的提示词,图片以image_url内容块传入(base64时用data:image/jpeg;base64,...拼接)。要求模型只返回JSON。

  5. 解析JSON并判定置信度

    加Code节点:try{data=JSON.parse(模型输出)}catch{data=null}。再判断data为null或confidence<0.5时走“无法识别”分支:Gmail发“无法读取”通知(附submitter和note);否则进入建档分支。

  6. UPSERT建档并发摘要邮件

    识别分支加Postgres节点执行INSERT ... ON CONFLICT (doc_id) DO UPDATE(语句见材料C后半段),doc_id可用doc_type+日期+随机后缀生成。随后Gmail节点发摘要邮件:主题“新单据已建档:{{title}}”,正文列类型、金额、币种、日期、置信度和摘要。

  7. 配置每日催办并测试

    加第二个触发工作流(或同图新分支):Schedule Trigger每天08:00、时区Asia/Jakarta,Postgres查询SELECT * FROM biz_documents WHERE status<>'done' AND created_at < NOW()-INTERVAL '24 hours',有结果时Gmail把清单(每行doc_id+标题+金额)发给运营。最后用下方示例数据POST到webhook Test URL走通全流程。

可直接复制的材料

材料C:建表与UPSERT SQL

本站按原文描述的字段独立编写的参考表结构,列名需与模板实际INSERT语句核对;金额单位为元,NUMERIC避免浮点误差。

CREATE TABLE IF NOT EXISTS biz_documents (
  doc_id TEXT PRIMARY KEY,
  doc_type TEXT,
  title TEXT,
  summary TEXT,
  amount NUMERIC(12,2),
  currency TEXT,
  doc_date DATE,
  confidence NUMERIC(3,2),
  status TEXT NOT NULL DEFAULT 'open',
  submitter TEXT,
  note TEXT,
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

INSERT INTO biz_documents (doc_id, doc_type, title, summary, amount, currency, doc_date, confidence, submitter, note)
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10)
ON CONFLICT (doc_id) DO UPDATE SET
  doc_type=EXCLUDED.doc_type, title=EXCLUDED.title, summary=EXCLUDED.summary,
  amount=EXCLUDED.amount, currency=EXCLUDED.currency, doc_date=EXCLUDED.doc_date,
  confidence=EXCLUDED.confidence, submitter=EXCLUDED.submitter, note=EXCLUDED.note;

材料D:单据识别提示词(视觉模型)

本站独立编写示例,表达式路径按你webhook节点实际输出调整;可在节点上启用JSON响应格式提高稳定性。

你是单据录入助手。阅读这张单据照片,只输出一个JSON对象,不要输出markdown代码块或其他文字。
字段:
- doc_type:单据类型,取值invoice/receipt/purchase_order/delivery_note/other之一;
- title:一行中文标题,概括单据主体与用途;
- summary:80字以内中文摘要;
- extracted:对象,含vendor(对方单位)、items(品名数组,最多5条);
- amount:数字,含税总额,找不到填null;
- currency:三字母币种代码,如CNY/USD,找不到填null;
- doc_date:单据日期,YYYY-MM-DD,找不到填null;
- confidence:0到1的置信度,图片模糊或字段缺失时降低;
- readable:布尔值,完全无法辨认时填false,其余字段尽量填null。
提交人备注(可能为空):{{$json.body.note}}

输入与输出示例

本站虚构演示,非真实模型输出,图片URL不存在,数字仅为字段映射示例。

输入

POST到/webhook/docintake的body:{"image_url":"https://img.example.com/test/fapiao-0091.jpg","doc_type":"invoice","submitter":"阿May","note":"9月办公用品采购"}

对应输出

模型返回{"doc_type":"invoice","title":"某文具公司办公用品采购发票","summary":"采购打印纸与硒鼓一批,含税合计486.00元。","extracted":{"vendor":"某文具(深圳)有限公司","items":["A4打印纸10包","硒鼓2支"]},"amount":486.00,"currency":"CNY","doc_date":"2026-09-02","confidence":0.93,"readable":true};Postgres中biz_documents新增doc_id=invoice-20260902-0091一行status=open,运营邮箱收到主题“新单据已建档:某文具公司办公用品采购发票”的摘要邮件。

做完检查这些

  • POST示例body后,biz_documents表出现一行,amount=486.00、currency=CNY、status=open,且运营邮箱收到摘要邮件
  • POST一个不含image_url和image_base64的body,运营邮箱收到“无法读取”通知而不是流程静默成功
  • POST一张模糊图片(或用confidence阈值模拟),走无法识别分支并收到通知邮件
  • 把某行created_at改到25小时前且status保持open,手动执行催办分支后收到含该doc_id的清单邮件

容易卡住的地方

  • gpt-5.6-terra为原文指定模型名,你的OpenAI账户若无该模型权限会在调用时报错,需先确认可用模型列表
  • 自托管n8n的webhook默认可能只在内网可达,手机拍照转发场景需公网域名或隧道
  • base64图片体积大,注意webhook与节点的请求体大小限制,大图建议走image_url
  • 置信度阈值0.5是本站设定的练习参考值,需按实际识别质量调整,不代表模板原设定
  • Asia/Jakarta时区与业务不符时要在Schedule Trigger中改时区,否则催办时间会偏移
  • 不要向测试webhook POST含真实个人信息或真实财务单据的图片,用合成测试图

原文与作者资料 ↗

本站借助AI整理来源事实,独立编写中文操作指南与示例。示例不代表实际运行结果;来源效果尚未由本站独立复现。付费模板与模型、服务费用分别计算。

原文标题
Turn forwarded business document images into structured records with gpt-5.6-terra Vision, Postgres, and Gmail
原作者
Khairul Muhtadin
原始发布日期
2026-09-04T02:22:48.327Z
来源
https://n8n.io/workflows/19167