Skip to content
广告 · 本站推荐广告

发票自动识别录入 - 企业财务自动化

通过 OpenClaw 的 Cron(定时任务)+ Hooks(钩子)组合,实现发票附件的自动发现、OCR(光学字符识别)信息提取、数据校验和财务系统录入的全自动化流程。每月可为财务人员节省 80% 以上的发票处理时间。

整体架构

邮件/微信/钉钉
    │ 附件

┌──────────────┐   Cron 定时触发    ┌─────────────┐
│  附件扫描     │ ◄──────────────── │  Gateway     │
│  (多渠道)     │                   │  定时调度     │
└──────┬───────┘                   └─────────────┘
       │ 发票文件

┌──────────────┐     提取结果      ┌─────────────┐
│  OCR 识别     │ ───────────────> │  数据校验     │
│  Agent Tool   │                  │  去重检测     │
└──────────────┘                   └──────┬──────┘
                                          │ 有效数据

                                   ┌─────────────┐
                                   │  录入财务系统 │
                                   │  发送通知     │
                                   └─────────────┘

配置步骤

Step 1: 配置邮件扫描

通过 Polls(轮询)定期检查邮箱中的发票附件:

json
{
  "polls": {
    "entries": {
      "invoice-email-scanner": {
        "enabled": true,
        "interval": 300000,
        "source": {
          "type": "imap",
          "host": "imap.exmail.qq.com",
          "port": 993,
          "ssl": true,
          "username": "${FINANCE_EMAIL}",
          "password": "${FINANCE_EMAIL_PASS}",
          "folder": "INBOX"
        },
        "filter": {
          "unseen": true,
          "hasAttachment": true,
          "subjectContains": ["发票", "invoice", "报销"]
        },
        "action": {
          "session": "isolated",
          "message": "检测到发票邮件,开始处理附件"
        }
      }
    }
  }
}

Step 2: 配置 Cron 定时批处理

每天下午 6 点统一批量处理当日收集的发票:

bash
openclaw cron add \
  --name "daily-invoice-batch" \
  --cron "0 18 * * 1-5" \
  --timezone "Asia/Shanghai" \
  --session isolated \
  --message "执行每日发票批量处理:扫描所有渠道的新发票,OCR识别,校验入库,生成日报"

Step 3: 创建发票处理 Hook

创建 Workspace Hook 处理发票识别逻辑:

markdown
---
name: invoice-processor
version: 1.0.0
events:
  - message:received
description: 自动处理发票附件,OCR 识别并录入
---

# 发票自动处理 Hook

监听附件消息,自动识别发票并提取信息。
typescript
import type { HookContext, MessageReceivedEvent } from "@openclaw/sdk";

export default async function handler(
  ctx: HookContext<MessageReceivedEvent>
) {
  const { message, session } = ctx.event;

  // 过滤:仅处理含附件的消息
  if (!message.attachments?.length) return;

  for (const attachment of message.attachments) {
    // 仅处理 PDF 和图片格式
    if (!isInvoiceFile(attachment.mimeType)) continue;

    // Step 1: OCR 识别
    const ocrResult = await ctx.agent.tool("ocr", {
      file: attachment.url,
      lang: "zh-CN",
    });

    // Step 2: 提取发票字段
    const invoiceData = await ctx.agent.tool("extract-invoice", {
      text: ocrResult.text,
      fields: INVOICE_FIELDS,
    });

    // Step 3: 校验与去重
    const validation = await validateInvoice(invoiceData);
    if (!validation.valid) {
      await ctx.notify(`⚠️ 发票校验失败: ${validation.reason}`);
      continue;
    }

    // Step 4: 录入财务系统
    await ctx.agent.tool("http-request", {
      method: "POST",
      url: "${FINANCE_API}/invoices",
      body: invoiceData,
    });

    await ctx.notify(`✅ 发票 ${invoiceData.number} 已录入`);
  }
}

const INVOICE_FIELDS = [
  "invoiceNumber",    // 发票号码
  "invoiceCode",      // 发票代码
  "amount",           // 金额
  "taxAmount",        // 税额
  "totalAmount",      // 价税合计
  "issueDate",        // 开票日期
  "sellerName",       // 销售方名称
  "sellerTaxId",      // 销售方税号
  "buyerName",        // 购买方名称
  "buyerTaxId",       // 购买方税号
];

function isInvoiceFile(mimeType: string): boolean {
  return [
    "application/pdf",
    "image/jpeg",
    "image/png",
    "image/tiff",
  ].includes(mimeType);
}

async function validateInvoice(data: any) {
  // 必填字段检查
  if (!data.invoiceNumber || !data.amount) {
    return { valid: false, reason: "缺少必填字段" };
  }
  // 金额合理性检查
  if (data.amount <= 0 || data.amount > 10000000) {
    return { valid: false, reason: "金额异常" };
  }
  return { valid: true };
}

Step 4: 配置通知渠道

将处理结果推送到企业微信群:

json
{
  "notifications": {
    "invoice-report": {
      "channel": "wecom",
      "webhook": "${WECOM_INVOICE_GROUP_WEBHOOK}",
      "template": "📋 发票处理报告\n处理数量: {count}\n成功: {success}\n失败: {failed}\n总金额: ¥{totalAmount}"
    }
  }
}

完整配置示例

json
{
  "polls": {
    "entries": {
      "invoice-email-scanner": {
        "enabled": true,
        "interval": 300000,
        "source": {
          "type": "imap",
          "host": "imap.exmail.qq.com",
          "port": 993,
          "ssl": true
        },
        "filter": {
          "unseen": true,
          "hasAttachment": true
        }
      }
    }
  },
  "cron": {
    "entries": {
      "daily-invoice-batch": {
        "cron": "0 18 * * 1-5",
        "timezone": "Asia/Shanghai",
        "session": "isolated",
        "message": "执行每日发票批量处理"
      }
    }
  },
  "hooks": {
    "workspace": {
      "entries": {
        "invoice-processor": { "enabled": true }
      }
    }
  }
}

发票数据字段

OCR 识别后提取的标准字段:

字段说明示例
invoiceNumber发票号码04193051
invoiceCode发票代码3100204130
amount不含税金额8849.56
taxAmount税额1150.44
totalAmount价税合计10000.00
issueDate开票日期2026-03-01
sellerName销售方名称XX科技有限公司
buyerName购买方名称YY集团有限公司

校验与去重逻辑

防重策略

系统通过 invoiceCode + invoiceNumber 组合作为唯一标识,自动检测重复发票:

  • 完全重复:跳过并记录
  • 疑似重复(金额/日期相同但号码不同):标记待人工确认

常见问题

问题解决方案
OCR 识别率低确保图片清晰度 ≥ 300 DPI,使用 lang: "zh-CN"
邮件扫描遗漏检查 IMAP 连接和过滤条件配置
金额识别错误启用 doubleCheck 模式,两次识别结果对比
电子发票 PDF 无法识别优先使用 PDF 文本提取而非 OCR

🇨🇳 中国用户须知

  • 企业邮箱推荐:腾讯企业邮箱(imap.exmail.qq.com)和阿里企业邮箱均支持 IMAP
  • 增值税发票:国内增值税专用发票和普通发票的字段格式不同,Agent 会自动适配
  • 发票真伪验证:可集成国家税务总局的发票查验平台 API 进行真伪校验
  • 通知渠道:推荐使用企业微信群机器人或钉钉群机器人接收处理报告
  • 数据安全:发票数据涉及企业财务信息,建议 Gateway 部署在内网环境

基于MIT协议开源 | 内容翻译自 官方文档,同步更新