OpenClaw与钉钉审批深度集成实践:实现自动化审批全流程管理
摘要:在现代企业运营中,高效、透明的审批流程是提升组织效能的关键环节。随着企业数字化转型的深入,传统纸质或孤立信息系统的审批方式已难以满足快速响应业务需求、降低运营成本、提升员工体验的要求。本文将以OpenClaw平台为核心,详细阐述其如何与钉钉审批系统进行深度集成,实现从自动发起审批、实时跟踪审批进度到审批结果精准推送的全流程自动化管理。文章将从集成背景、技术方案、核心功能实现、安全考量、应用场景及实施效果等方面展开,为企业构建智能审批流提供实践参考。
关键词:OpenClaw, 钉钉审批, 流程自动化, 系统集成, 审批流, 消息推送, API对接
第一章:引言 - 企业审批流程自动化的迫切需求
企业内部充斥着各种类型的审批请求:费用报销、采购申请、请假休假、合同签署、项目立项等等。这些看似日常的事务性工作,却直接关系到企业的资金流动、资源调配、合规风控和员工满意度。传统的审批流程通常存在以下痛点:
- 效率低下:申请人需手动填写纸质表单或在不同系统间切换,审批人可能因出差、会议等原因无法及时处理,导致流程卡顿,影响业务推进速度。
- 透明度不足:申请人难以实时了解审批进展到哪一步、卡在哪个环节,只能被动等待或反复询问,沟通成本高。
- 数据孤岛:审批数据分散在各个部门或独立系统,难以汇总分析,无法为管理决策提供有效支持。
- 操作繁琐:重复性的人工操作(如录入、传递、提醒)占用员工大量时间,降低了整体工作效率。
- 合规风险:手工操作易出错,流程缺乏标准化监控,可能带来合规性风险。
钉钉作为广泛使用的企业协同平台,其内置的审批功能因其便捷性(移动端处理)、可配置性(自定义表单流程)和集成性(与组织架构打通)深受企业欢迎。然而,钉钉审批通常需要用户主动发起,缺乏与后端业务系统(如ERP、CRM、项目管理系统)的深度联动能力。这正是OpenClaw发挥价值的场景。
OpenClaw作为一个强大的流程自动化与集成平台,其核心能力在于连接异构系统、编排复杂业务流程、执行自动化任务。通过OpenClaw对接钉钉审批,可以实现:
- 事件驱动审批:当业务系统中发生特定事件(如销售订单金额超标、库存低于安全阈值、员工提交加班申请),自动触发钉钉审批流程。
- 信息自动填充:从业务系统中自动提取相关数据(申请人、部门、金额、事由、附件等),填充至钉钉审批表单,减少人工录入。
- 进度透明可视:实时获取审批状态(待审批、审批中、已通过、已拒绝、已撤回),并在业务系统或OpenClaw监控界面中清晰展示。
- 结果驱动后续:审批结果(通过/拒绝)实时回传给业务系统或OpenClaw,自动触发后续业务操作(如付款、下单、解锁权限、通知相关人员)。
- 集中监控分析:OpenClaw提供统一的流程监控和数据分析平台,对审批效率、瓶颈环节、常见拒绝原因等进行洞察。
这种深度集成将钉钉审批从孤立的应用转变为贯穿业务流程的关键节点,显著提升了流程效率、透明度和智能化水平。
第二章:OpenClaw对接钉钉审批的技术方案
实现OpenClaw与钉钉审批的集成,主要依赖钉钉开放平台提供的丰富API接口。整个集成架构如下图所示(此处省略图示,用文字描述):
[业务系统/OpenClaw触发事件] -> [OpenClaw集成流] -> [调用钉钉API发起审批] -> [钉钉审批流处理] | V [钉钉审批状态变更] -> [钉钉回调OpenClaw] -> [OpenClaw更新状态/触发后续] -> [通知业务系统/执行操作]2.1 核心API接口
钉钉审批开放API主要涉及以下几个关键接口:
发起审批实例接口 (
processinstance_create):- 功能:用于在钉钉上创建一个新的审批实例。
- 关键参数:
process_code: 审批模板的唯一标识码(需先在钉钉管理后台创建并获取)。originator_user_id: 发起审批用户的钉钉用户ID。dept_id: 发起人所在部门ID(可选,但推荐)。approvers: 审批人列表(钉钉用户ID,可指定或按规则自动选择)。form_component_values: 审批表单的具体内容值列表。这是一个核心参数,包含了表单中每个字段的值。字段值需要与钉钉审批模板中定义的组件一一对应。
- OpenClaw调用:OpenClaw在侦听到业务事件或满足触发条件后,构造符合要求的请求体(包括从业务系统获取的数据填充
form_component_values),调用此接口发起审批。钉钉返回process_instance_id(审批实例ID),OpenClaw需存储此ID用于后续跟踪。
获取审批实例详情接口 (
processinstance_get):- 功能:根据审批实例ID查询该实例的当前状态、审批记录、表单值等详细信息。
- 关键参数:
process_instance_id。 - OpenClaw调用:OpenClaw可以定期轮询此接口(例如每分钟或根据业务需求),主动获取审批的最新状态。适用于对实时性要求不是极端高的场景。
注册审批事件回调接口 (
call_back):- 功能:更高效的方案是使用钉钉的事件回调机制。OpenClaw向钉钉注册一个回调地址 (
callback_url),并订阅审批状态变更事件 (bpms_instance_change)。 - 原理:当钉钉审批实例状态发生变更(如被审批、被拒绝、被撤回、完成)时,钉钉服务器会主动向OpenClaw注册的
callback_url发送一个HTTP POST请求,请求体中携带事件类型、审批实例ID、当前状态等关键信息。 - OpenClaw处理:OpenClaw需要实现一个安全的Webhook端点来接收钉钉的回调消息。收到消息后,解析内容,更新内部审批状态,并触发后续逻辑(如通知业务系统审批结果)。这种方式实时性更高,避免了轮询的开销。
- 安全:钉钉回调会携带签名 (
sign),OpenClaw需使用预先约定的令牌 (token) 和钉钉提供的加密算法进行签名验证,确保消息来源的合法性,防止伪造请求。
- 功能:更高效的方案是使用钉钉的事件回调机制。OpenClaw向钉钉注册一个回调地址 (
2.2 身份认证与安全
调用钉钉API需要进行身份认证,以确保请求的合法性:
- 获取AccessToken:几乎所有钉钉API的调用都需要在HTTP Header中附带有效的
access_token。OpenClaw需要定期调用钉钉的gettoken接口,使用企业的AppKey和AppSecret来换取access_token。access_token有效期为7200秒(2小时),OpenClaw需实现自动刷新机制。 - 数据安全:
- 传输安全:所有API调用均需使用HTTPS协议。
- 敏感信息:避免在日志或配置文件中明文存储
AppSecret、access_token。 - 回调安全:如前所述,需严格验证回调请求的签名。
- 权限控制:OpenClaw访问钉钉API的权限应受到严格控制,仅允许访问必要的审批接口。
2.3 OpenClaw集成流设计
在OpenClaw平台中,需要设计相应的集成流来处理整个审批生命周期:
- 触发节点:定义什么事件会触发审批发起(如数据库记录变更、API调用、定时器、消息队列消息)。
- 数据准备节点:从触发事件中提取数据,或调用其他系统接口获取所需信息(申请人信息、部门信息、审批事由、金额、相关单据号等)。
- 构造请求节点:将准备好的数据映射到钉钉审批接口所需的
form_component_values结构中。处理复杂的表单结构(如明细表)。 - 调用发起接口节点:获取有效的
access_token,调用processinstance_create接口。处理可能的错误(如网络异常、参数错误)。 - 状态跟踪节点(轮询模式):启动一个定时任务或循环逻辑,定期调用
processinstance_get接口检查状态。状态变化时触发后续处理。 - 回调接收节点(回调模式):实现一个HTTP端点接收钉钉回调。解析事件数据,验证签名,更新状态。
- 结果处理节点:根据审批结果(通过/拒绝/其他状态),执行后续业务逻辑:
- 通过:调用业务系统接口完成业务操作(如ERP创建付款单、HR系统记录休假、项目系统启动任务)。
- 拒绝:通知申请人(通过钉钉消息、邮件或其他方式),记录拒绝原因,可能需要触发修正流程。
- 其他:处理撤回、转交等情况。
- 日志与监控节点:记录完整的审批发起、状态变更、结果处理日志。OpenClaw的监控界面可实时查看审批流状态、耗时、成功率等指标。
第三章:核心功能实现细节
3.1 自动发起审批
这是集成的起点,关键在于数据的准确映射和高效调用。
- 审批模板 (
process_code) 管理:在钉钉管理后台创建好所需的审批模板(如“大额采购审批”、“请假审批”)。OpenClaw需要维护一个映射关系,将业务事件类型关联到对应的process_code。可将process_code存储在OpenClaw的配置中心或数据库。 - 表单数据填充 (
form_component_values):这是最复杂的部分之一。钉钉审批表单由各种组件构成(单行文本、多行文本、数字、金额、日期、部门、人员、明细表、附件等)。每个组件在API请求中对应一个特定的结构。OpenClaw需要:- 了解目标审批模板的详细结构(组件ID、组件类型)。
- 将业务数据按规则转换为对应组件的值。
- 对于明细表组件,需要构造嵌套的数组结构。
- 对于附件组件,可能需要先上传文件到钉钉或其他存储,获取文件ID。
- 发起人 (
originator_user_id) 确定:通常基于业务事件确定(如报销单提交人、请假申请人)。OpenClaw需要将业务系统中的用户标识(如工号、邮箱)映射到钉钉用户ID。这可能需要调用钉钉用户接口 (user/get) 或维护一个映射表。 - 审批人 (
approvers) 指定:方式多样:- 固定人员:直接指定钉钉用户ID列表。
- 按规则动态计算:基于发起人部门、审批金额、项目类型等规则,调用钉钉部门接口 (
department/list) 或用户接口,动态计算出审批人列表(或审批人ID)。 - 钉钉审批模板自带规则:如果钉钉模板已配置好审批人规则(如主管、部门负责人),则
approvers可以为空或只指定部分人员。
- 错误处理:接口调用可能失败(网络问题、参数错误、权限不足)。OpenClaw需捕获异常,记录详细日志,并实现重试机制或告警通知。
3.2 跟踪审批进度
实时掌握审批状态是提升透明度的关键。
- 轮询模式:
- 存储
process_instance_id:成功发起审批后,OpenClaw必须将返回的process_instance_id与原始业务单据关联存储(如数据库)。 - 定时任务:为每个进行中的审批实例创建定时任务(或统一扫描),定期(如每1-5分钟)调用
processinstance_get接口。 - 状态解析:解析接口返回的
status字段(如RUNNING,COMPLETED,TERMINATED)以及结果 (result-agree,refuse)。 - 更新状态:将最新状态更新到OpenClaw内部存储或业务系统。
- 效率考虑:大量审批实例时,频繁轮询会增加钉钉API调用压力。需评估优化策略(如按状态分组轮询、减少轮询频率)。
- 存储
- 回调模式(推荐):
- 注册回调:OpenClaw调用钉钉接口注册回调地址,并订阅
bpms_instance_change事件。 - 实现Webhook:OpenClaw提供一个安全的、可公网访问的HTTPS端点。
- 接收与验证:接收到POST请求后,首先验证请求头中的签名 (
sign) 是否合法(使用token和指定算法计算对比)。 - 解析事件:解析请求体JSON,获取事件类型 (
EventType)、审批实例ID (processInstanceId)、当前状态 (status)、结果 (result)、时间戳等。 - 处理事件:根据事件内容更新审批状态,并立即触发结果处理逻辑。
- 可靠性:需要考虑回调的可靠性。钉钉有重试机制,OpenClaw端点需幂等处理(相同事件多次到达不影响结果)。端点需具备一定吞吐能力。
- 优势:实时性高,减少不必要的API调用,减轻系统负载。
- 注册回调:OpenClaw调用钉钉接口注册回调地址,并订阅
3.3 审批结果实时推送
审批结果的及时反馈是驱动后续业务的关键。
- 结果解析:无论是轮询还是回调获取到状态为完成 (
COMPLETED) 时,都需要判断结果 (result) 是通过 (agree) 还是拒绝 (refuse)。回调模式下,结果信息通常已包含在事件数据中。 - 获取详情(可选):如果回调事件或轮询结果未包含足够的审批信息(如审批意见、拒绝原因),OpenClaw可能需要再次调用
processinstance_get接口获取完整详情。 - 推送目标:
- 业务系统:这是最主要的推送目标。OpenClaw调用业务系统提供的API(如RESTful API, SOAP, 数据库存储过程),将审批结果(通过/拒绝)、审批实例ID、相关业务单据ID、审批意见、附件信息(如有)等传递给业务系统。
- OpenClaw后续流:OpenClaw可以根据结果触发不同的子流程。例如,审批通过后执行付款操作;审批拒绝后发送通知给申请人要求修改。
- 通知相关人员:除了驱动业务系统,OpenClaw还可以集成消息平台(如钉钉机器人、企业微信、邮件、短信):
- 通知申请人:告知审批结果(通过/拒绝)及原因/意见。
- 通知相关团队:如采购审批通过后通知采购部执行;费用报销通过后通知财务部付款。
- 通知管理员:对于异常情况(多次拒绝、超时未审批)进行告警。
- 数据一致性:确保审批结果信息准确无误地传递到下游系统,避免因信息不一致导致业务错误。OpenClaw的事务管理或补偿机制在此环节很重要。
- 日志记录:详细记录结果推送的时间、目标、内容、状态(成功/失败),便于审计和问题排查。
第四章:安全性与可靠性考量
系统集成必须重视安全和稳定。
4.1 安全措施
- HTTPS:所有与钉钉API的交互(调用、回调)必须使用TLS加密。
- 认证令牌管理:
AppKey/AppSecret:严格保密,存储在安全的配置管理系统(如HashiCorp Vault, AWS Secrets Manager),避免硬编码。OpenClaw访问时动态获取。access_token:实现高效的自动刷新机制。在OpenClaw中缓存token,并在接近过期时主动刷新,避免调用因token失效而失败。
- 回调安全:
- 签名验证:对钉钉回调请求必须进行严格的签名验证。使用钉钉提供的加密算法(如HMAC-SHA256)和配置的
token计算签名,并与请求头中的sign进行比对。验证失败应拒绝请求。 - Token管理:回调配置的
token应具有一定复杂度,并定期更新。 - IP白名单(可选):如果条件允许,可以在钉钉后台配置OpenClaw回调服务器的出口IP白名单,增加一层防护。
- 签名验证:对钉钉回调请求必须进行严格的签名验证。使用钉钉提供的加密算法(如HMAC-SHA256)和配置的
- 数据安全:
- 敏感数据(如身份证号、银行账号)在传输和存储时应考虑加密。
- 存储在OpenClaw或数据库中的审批相关数据(用户ID、表单值)应遵循最小权限原则。
- 权限最小化:为OpenClaw访问钉钉API的应用分配最小必要的权限(仅审批相关接口)。
4.2 可靠性设计
- 错误处理与重试:
- API调用:对钉钉API调用失败(网络错误、5xx错误)实现指数退避重试机制。超过重试次数后记录错误并告警。
- 回调处理:OpenClaw的回调处理逻辑应尽可能幂等。处理失败时应有重试队列或机制。同时,钉钉对未成功响应的回调也会进行重试。
- 下游调用:调用业务系统接口失败时,同样需要重试和告警。
- 幂等性:关键操作(如发起审批、更新状态、结果推送)要设计成幂等的,即重复执行不会产生额外副作用或错误。例如,基于
process_instance_id或业务单据ID来判断是否已处理过。 - 异步处理:对于耗时操作(如大量数据处理、复杂映射、调用外部系统),OpenClaw应使用消息队列或异步任务机制,避免阻塞主流程。
- 监控告警:
- OpenClaw监控:利用OpenClaw内置的仪表盘监控集成流的运行状态、执行时长、成功率、错误率。
- 日志聚合:将OpenClaw日志、应用日志集中管理(如ELK, Splunk),便于排查问题。
- 关键指标告警:对API调用失败率升高、审批平均耗时异常增加、回调处理积压等情况设置告警阈值,及时通知运维人员。
- 高可用:OpenClaw平台本身应部署在具备高可用性的架构上(如集群部署、负载均衡)。回调服务器也需要考虑冗余。
第五章:典型应用场景与价值
OpenClaw + 钉钉审批的集成方案可应用于众多业务领域:
- 费用报销流程:
- 场景:员工在财务系统提交报销单 -> OpenClaw 触发钉钉审批(自动填充金额、事由、发票附件) -> 审批人钉钉处理 -> 审批通过后,OpenClaw 通知财务系统付款,并邮件通知员工;审批拒绝则通知员工修改。
- 价值:缩短报销周期,减少纸张,提高员工满意度,财务数据自动同步。
- 采购申请流程:
- 场景:员工在采购系统申请购买 -> 根据金额/类型,OpenClaw 自动触发不同层级的钉钉审批 -> 审批通过后,OpenClaw 通知采购系统下单或生成采购订单;审批拒绝则反馈原因。
- 价值:规范采购行为,控制成本,加快采购执行速度。
- 请假休假流程:
- 场景:员工在HR系统申请休假 -> OpenClaw 触发钉钉审批(带出剩余假期、工作交接人) -> 主管审批 -> 审批通过后,OpenClaw 同步状态给HR系统和考勤系统;拒绝则通知员工。
- 价值:简化申请流程,假期余额实时更新,考勤自动关联。
- 合同审批流程:
- 场景:业务人员上传合同草稿 -> OpenClaw 触发钉钉法务审批(自动关联合同编号、金额、客户信息) -> 法务、财务、业务负责人审批 -> 审批通过后,OpenClaw 通知合同管理系统生成正式合同/用印;关键节点可存档。
- 价值:加强合同风险控制,提高审批效率,合同状态全程可追溯。
- IT资源申请流程:
- 场景:新员工入职/项目需要 -> 申请系统账号、权限、虚拟机 -> OpenClaw 触发钉钉审批 -> IT主管审批 -> 审批通过后,OpenClaw 调用IT系统API自动开通权限/资源;拒绝则通知申请人。
- 价值:实现权限申请自动化,提高IT响应速度,保障安全合规。
- 项目立项/阶段审批:
- 场景:项目经理提交项目计划书 -> OpenClaw 触发钉钉多级审批 -> 审批通过后,OpenClaw 通知项目管理系统启动项目/进入下一阶段;审批记录存档。
- 价值:确保项目按流程推进,关键决策留痕。
价值总结:
- 显著提效:自动化发起、状态跟踪、结果处理,大幅缩短审批周期(从几天到几小时)。
- 提升透明度:申请人、审批人、管理者均可实时了解审批进展,减少沟通成本。
- 降低错误率:减少人工录入和传递环节,数据自动同步,降低出错概率。
- 改善体验:员工在熟悉的钉钉移动端处理审批,便捷高效;管理者随时随地审批。
- 数据驱动决策:OpenClaw提供审批数据分析(平均耗时、瓶颈节点、拒绝率),助力流程优化。
- 促进合规:标准化、可追溯的审批流程,满足内控和审计要求。
- 释放人力:员工从繁琐的事务性工作中解放,专注于更高价值工作。
第六章:实施建议与挑战应对
6.1 实施步骤
- 需求分析与方案设计:明确要集成的具体审批类型、业务触发点、数据来源、审批人规则、结果处理逻辑、通知要求等。设计OpenClaw集成流蓝图。
- 钉钉环境准备:
- 创建企业内部应用,获取
AppKey/AppSecret。 - 在钉钉管理后台配置好所需的审批模板 (
process_code),定义好表单字段和审批流程规则。 - 配置回调(如果需要):在钉钉后台设置回调地址 (
callback_url) 和令牌 (token)。
- 创建企业内部应用,获取
- OpenClaw环境配置:
- 安装或配置OpenClaw平台。
- 配置钉钉连接器(设置
AppKey/AppSecret)。 - 配置安全存储(用于token、敏感配置)。
- 集成流开发:在OpenClaw中开发实现:
- 触发逻辑。
- 数据获取与映射逻辑(业务系统 -> 钉钉表单)。
- 审批发起逻辑。
- 状态跟踪逻辑(轮询或回调接收)。
- 结果处理与推送逻辑。
- 错误处理、日志、监控逻辑。
- 测试:
- 单元测试:测试各个节点的功能。
- 集成测试:模拟业务事件,测试从发起到结果处理的完整流程。重点测试各种审批结果(通过、拒绝、撤回)、错误场景(网络中断、API错误、回调验证失败)。
- 用户验收测试:关键用户参与,验证是否符合业务需求。
- 部署上线:将集成流部署到生产环境。逐步迁移或并行运行。
- 监控与运维:上线后持续监控运行状态、性能指标、错误日志。定期审计。根据业务变化调整流程。
6.2 常见挑战与应对
- 表单映射复杂性:
- 挑战:钉钉表单结构可能很复杂(嵌套明细表、动态组件),业务系统数据结构可能不匹配。
- 应对:深入理解钉钉表单组件API表示。在OpenClaw中编写灵活的数据转换脚本或使用可视化映射工具。对于复杂表单,分阶段实施。
- 用户/部门信息同步:
- 挑战:业务系统中的用户标识(工号、邮箱)与钉钉用户ID (
userid) 需要映射。 - 应对:实施定期的用户信息同步机制(如每天同步一次),在OpenClaw或中间库维护映射关系。优先使用钉钉ID作为关联键。
- 挑战:业务系统中的用户标识(工号、邮箱)与钉钉用户ID (
- 审批人动态确定:
- 挑战:审批规则可能很复杂(按金额、按部门、按项目、按申请人级别),需要动态计算审批链。
- 应对:利用钉钉的组织机构接口。在OpenClaw中实现规则引擎,或将规则配置化。对于极其复杂的规则,可考虑在钉钉审批模板中配置。
- 高并发与性能:
- 挑战:大规模企业可能同时发起大量审批,对OpenClaw、钉钉API、回调服务器造成压力。
- 应对:OpenClaw采用异步处理、消息队列缓冲。合理设置轮询频率(如果使用)。优化回调处理逻辑。评估钉钉API调用频次限制,避免触发流控。OpenClaw集群部署。
- 业务系统接口不稳定:
- 挑战:结果推送时调用的业务系统API可能不可用或响应慢。
- 应对:在OpenClaw中实现重试机制、超时控制、熔断降级。与业务系统团队协作保障接口稳定性。采用异步消息通知。
- 流程异常处理:
- 挑战:审批可能被撤回、转交、长时间挂起,业务系统状态可能与审批状态不一致。
- 应对:在OpenClaw状态跟踪中捕获这些事件。设计补偿机制(如人工干预流程、状态核对任务)。加强日志记录。
第七章:总结与展望
OpenClaw与钉钉审批的深度集成,成功地将钉钉便捷的移动审批能力与后端业务系统的自动化处理能力无缝衔接,构建了一套高效、透明、智能的审批流水线。它不仅解决了传统审批流程的诸多痛点,更通过自动化释放了人力,通过数据洞察驱动了流程优化。
在实施过程中,需要重点关注表单数据的精准映射、审批规则的灵活实现、状态跟踪的实时可靠(尤其是回调模式的应用)、结果处理的准确联动以及整个流程的安全性与健壮性设计。成功的集成将显著提升相关业务领域的运营效率,改善员工体验,并为企业数字化转型注入强劲动力。
展望未来,随着人工智能技术的发展,审批流程有望更加智能化。例如,结合OpenClaw的AI能力,可以对提交的审批内容进行初步合规性检查或风险提示;利用历史审批数据训练模型,辅助审批人进行决策;甚至对简单、低风险的审批实现自动审批。OpenClaw与钉钉审批的集成平台,将成为探索和实践这些智能化应用的理想基础。
附录A:OpenClaw调用钉钉发起审批接口示例代码 (伪代码/逻辑示意)
# 注意:此为简化逻辑示意,非生产完整代码 import requests import json from openclaw_sdk import get_config, log # 假设OpenClaw提供的工具函数 def trigger_dingtalk_approval(event_data): # 1. 获取配置 app_key = get_config("DINGTALK_APP_KEY") app_secret = get_config("DINGTALK_APP_SECRET") dingtalk_api_url = "https://oapi.dingtalk.com/topapi/processinstance/create" token_url = "https://oapi.dingtalk.com/gettoken" # 2. 获取AccessToken (应有缓存和刷新机制) token_params = {"appkey": app_key, "appsecret": app_secret} token_resp = requests.get(token_url, params=token_params) access_token = token_resp.json().get("access_token") if not access_token: log.error("Failed to get DingTalk access token") return False # 3. 根据业务事件类型,确定钉钉审批模板码 (process_code) approval_type = event_data["type"] # e.g., "EXPENSE_REPORT" process_code_map = { "EXPENSE_REPORT": "PROC-XXXX-EXPENSE", "PURCHASE_REQ": "PROC-YYYY-PURCHASE" } process_code = process_code_map.get(approval_type) if not process_code: log.error(f"Unsupported approval type: {approval_type}") return False # 4. 映射业务数据到钉钉表单组件 (form_component_values) # 假设 event_data 包含报销单信息 form_values = [] # 单行文本示例 - 报销事由 form_values.append({ "name": "事由", # 钉钉表单组件标题 "value": event_data["reason"], "component_type": "Text" }) # 金额组件示例 - 报销金额 form_values.append({ "name": "金额", "value": str(event_data["amount"]), # 可能需要字符串格式 "component_type": "Money" }) # 明细表示例 - 报销明细 (假设 event_data["items"] 是列表) detail_items = [] for item in event_data["items"]: detail_items.append({ "name": "类别", "value": item["category"], "component_type": "Text" }, { "name": "金额", "value": str(item["amount"]), "component_type": "Money" }) form_values.append({ "name": "报销明细", "value": detail_items, "component_type": "Table" }) # 附件示例 (需先上传) # ... (此处省略文件上传和获取file_id的逻辑) # form_values.append({...}) # 5. 确定发起人 (originator_user_id) - 需要映射 applicant_ding_id = map_user_to_dingid(event_data["applicant_id"]) if not applicant_ding_id: log.error(f"Failed to map user {event_data['applicant_id']} to DingTalk ID") return False # 6. 构造审批请求体 request_body = { "process_code": process_code, "originator_user_id": applicant_ding_id, "dept_id": event_data.get("dept_id", -1), # 可选,-1可能代表根部门 # "approvers": "userid1,userid2", # 可选,如果模板有规则可不填 "form_component_values": form_values } # 7. 调用钉钉API发起审批 headers = {"Content-Type": "application/json"} params = {"access_token": access_token} resp = requests.post(dingtalk_api_url, params=params, headers=headers, data=json.dumps(request_body)) resp_data = resp.json() # 8. 处理响应 if resp_data.get("errcode") == 0: process_instance_id = resp_data["process_instance_id"] # 存储 process_instance_id 与业务单据关联 save_approval_reference(event_data["biz_id"], process_instance_id) log.info(f"Approval initiated successfully. Instance ID: {process_instance_id}") return True else: log.error(f"Failed to initiate approval. DingTalk error: {resp_data.get('errmsg')}") # 实现重试或告警逻辑 return False # 辅助函数示意 (需具体实现) def map_user_to_dingid(biz_user_id): # 查询映射表或调用接口 return "ding123456" # 示例返回值附录B:OpenClaw处理钉钉审批回调示例逻辑 (伪代码/逻辑示意)
# 注意:此为简化逻辑示意,非生产完整代码 from flask import request, jsonify # 假设使用Flask框架 import hashlib import hmac import json from openclaw_sdk import log, trigger_flow # 假设OpenClaw提供的工具函数 # OpenClaw暴露的Webhook端点 (e.g., POST /dingtalk/approval/callback) def dingtalk_approval_callback(): # 1. 获取请求签名和参数 timestamp = request.headers.get('timestamp') sign = request.headers.get('sign') received_body = request.data # 原始请求体,用于签名验证 # 2. 验证签名 app_token = get_config("DINGTALK_CALLBACK_TOKEN") # 与钉钉后台配置一致 sign_str = f"{timestamp}\n{app_token}" computed_sign = hmac.new(app_token.encode('utf-8'), sign_str.encode('utf-8'), hashlib.sha256).hexdigest() if computed_sign != sign: log.warning("Invalid DingTalk callback signature!") return jsonify({"errcode": 500, "errmsg": "Invalid signature"}), 403 # Forbidden # 3. 解析回调事件数据 event_data = request.json event_type = event_data.get("EventType") process_instance_id = event_data.get("processInstanceId") # 4. 只处理审批实例变更事件 if event_type != "bpms_instance_change": log.info(f"Ignoring non-approval event: {event_type}") return jsonify({"errcode": 0, "errmsg": "success"}) # 仍需返回success # 5. 解析审批状态和结果 status = event_data.get("status") # e.g., "COMPLETED" result = event_data.get("result") # e.g., "agree", "refuse" biz_id = event_data.get("businessId") # 钉钉业务ID,通常关联业务单据 # 6. 记录事件 log.info(f"Received approval event. Instance: {process_instance_id}, Status: {status}, Result: {result}") # 7. 触发OpenClaw后续流程 (例如,一个专门处理审批结果的子流程) # 将关键信息传递给子流程 trigger_flow("handle_approval_result", { "process_instance_id": process_instance_id, "status": status, "result": result, "biz_id": biz_id, # 用于关联业务单据 "event_data": event_data # 可选,传递完整数据 }) # 8. 返回成功响应 (钉钉要求) return jsonify({"errcode": 0, "errmsg": "success"}) # 后续在 'handle_approval_result' 流中实现: # - 根据 process_instance_id / biz_id 找到关联的业务单据 # - 根据 status 和 result 更新业务系统状态 # - 发送通知 (通过/拒绝) # - 执行后续业务操作 (如付款、下单)