公司动态

ABAP 对接钉钉待办:从证书配置到任务创建实战

📅 2026/7/15 7:37:58
ABAP 对接钉钉待办:从证书配置到任务创建实战
1. 为什么需要SAP与钉钉待办集成在企业日常运营中审批流程是绕不开的重要环节。想象一下这样的场景采购部门的同事在SAP系统提交了采购申请审批人却整天泡在钉钉上处理各种消息。传统做法是审批人需要定期登录SAP系统查看待审批事项这种操作既低效又容易造成延误。而通过SAP与钉钉待办的集成审批流程可以主动找上门——审批人直接在钉钉待办中就能处理SAP发起的审批请求就像处理普通钉钉消息一样简单。这种集成带来的价值远不止于审批场景。比如HR部门的入职流程当SAP系统中创建了新员工档案后自动在钉钉生成待办任务提醒IT部门配置账号权限又比如财务部门的付款流程SAP中的付款申请审批通过后自动在钉钉生成付款确认待办。这些场景都体现了业务系统与办公协同工具深度整合的必要性。从技术角度看这种集成需要解决几个关键问题首先是安全通信企业级系统对接必须保证数据传输的安全性其次是接口稳定性要能应对网络波动、服务暂时不可用等情况最后是易用性对接方案应该足够灵活方便扩展到其他业务场景。接下来我们就从零开始一步步实现这个集成方案。2. 准备工作与环境配置2.1 钉钉开放平台应用创建登录钉钉开放平台开发者后台选择应用开发-企业内部应用。点击创建应用填写应用名称如SAP待办集成、应用图标等基本信息。创建完成后在应用详情页记下AppKey和AppSecret这两个参数相当于应用的身份证后续获取接口调用权限时会用到。特别要注意的是应用权限配置。在权限管理页面找到待办任务相关权限通常包括待办任务读写权限等。勾选所需权限后点击申请根据钉钉的要求提交权限申请材料。权限审批通过后应用才能正常调用待办任务相关接口。2.2 SAP系统准备工作在SAP系统中我们需要准备以下几个关键要素开发密钥环(SSL证书存储)使用事务码STRUST进入证书管理界面。这里可以看作是一个数字证书的保险箱后续我们会把钉钉的SSL证书存放在这里。HTTP连接配置通过事务码SM59可以配置SAP系统与外部系统的HTTP连接。这相当于在SAP系统中建立一条通往钉钉服务器的专用通道。ABAP开发环境确保你有SE37(函数构建器)、SE80(对象导航器)等开发事务码的使用权限。这些工具将用于编写和调试对接代码。建议在开发前创建一个专门的开发包(SE80中创建)用于存放所有与钉钉对接相关的开发对象这样便于后续管理和传输。3. SSL证书配置实战3.1 获取钉钉API证书钉钉API使用HTTPS协议进行通信这意味着我们需要先处理好SSL证书的问题。打开浏览器访问api.dingtalk.com在地址栏点击锁形图标选择证书信息。你会发现钉钉的证书链包含三个层级根证书、中间证书和终端证书。我们需要将这三个证书都导出到本地。具体操作步骤在证书查看器中切换到证书路径选项卡依次点击每个层级的证书选择导出。建议将证书保存为Base64编码的CER格式并按照层级命名如DigiCert Root.cer、DigiCert Intermediate.cer、dingtalk.cer。3.2 SAP证书导入回到SAP系统输入事务码STRUST进入SSL配置界面。选择SSL客户端标准(匿名)点击编辑进入修改模式。然后按照以下步骤操作点击导入证书按钮选择刚才导出的根证书文件在弹出的对话框中证书类型选择CA证书点击添加到证书列表重复上述过程导入中间证书最后导入终端证书这时证书类型应选择SSL服务器证书导入完成后点击保存按钮。一个常见的错误是只导入终端证书而忽略了根证书和中间证书这会导致SSL握手失败。建议导入后立即测试连接在STRUST界面点击测试连接输入api.dingtalk.com作为主机名端口填443。如果看到SSL握手成功的提示说明证书配置正确。4. HTTP连接配置4.1 创建SM59连接在SAP系统中输入事务码SM59选择HTTP连接类型点击创建按钮。在弹出窗口中填写以下关键信息目标主机api.dingtalk.com服务编号443路径前缀/v1.0登录安全性勾选活动选项SSL证书选择标准在SSL配置部分选择我们之前导入证书的SSL客户端标准。这里有个实用技巧可以勾选SNI扩展选项这有助于解决某些特定环境下的SSL握手问题。4.2 连接测试与排错配置完成后点击工具栏上的连接测试按钮。理想情况下你应该看到HTTP 200的响应状态码。如果遇到问题常见的排查步骤包括检查证书是否完整导入所有三个层级的证书确认SM59中配置的主机名和端口完全正确检查网络连接确保SAP服务器能够访问api.dingtalk.com查看系统日志(事务码SMICM)获取更详细的错误信息我曾在一个项目中遇到连接始终失败的情况后来发现是公司的防火墙拦截了对外443端口的访问。所以如果经过多次检查仍然无法建立连接可能需要联系网络管理员确认网络策略。5. 通用请求函数封装5.1 函数设计与参数定义为了避免重复编写相似的HTTP调用代码我们创建一个通用的请求函数ZDD_SEND_TO_DING。这个函数需要接收以下参数IV_PATH接口路径如/todo/users/xxx/tasksIV_METHODHTTP方法如POST或GETIV_BODY请求体内容通常是JSON字符串IT_HEADER自定义请求头表IT_PARAMURL参数表函数会返回两个关键信息EV_DATA响应内容和EV_STATUS执行状态S成功/E错误。5.2 HTTP客户端实现函数的核心是使用CL_HTTP_CLIENT创建HTTP客户端实例。关键代码如下DATA: lr_http_client TYPE REF TO if_http_client. 通过SM59配置创建HTTP客户端 cl_http_clientcreate_by_destination( EXPORTING destination DINGTALK SM59中配置的连接名称 IMPORTING client lr_http_client EXCEPTIONS OTHERS 4 ). 设置请求方法和URI lr_http_client-request-set_method( iv_method ). cl_http_utilityset_request_uri( EXPORTING request lr_http_client-request uri lv_path ). 设置请求头 lr_http_client-request-set_header_field( name Content-Type value application/json ). 设置请求体 lr_http_client-request-set_data( data lv_xstr ). 发送请求 lr_http_client-send( ). 接收响应 lr_http_client-receive( ). 获取响应数据 ev_data lr_http_client-response-get_cdata( ).这段代码处理了HTTP请求的全生命周期包括创建连接、设置参数、发送请求和接收响应。特别要注意的是错误处理部分应该捕获各种可能的异常情况如网络超时、SSL错误等并给出有意义的错误信息。6. Token管理机制6.1 钉钉Token获取原理钉钉的API采用OAuth2.0认证机制调用大多数接口都需要在请求头中携带access_token。获取token的接口相对简单只需要提供AppKey和AppSecret即可。但需要注意以下几点Token有有效期通常2小时过期后需要重新获取钉钉对获取token的接口有调用频率限制通常每小时最多100次同一个token可以用于多个接口调用因此我们不能每次调用接口都去获取新token而应该实现一个token缓存机制。6.2 ABAP实现方案我们创建一个函数ZDD_GET_TOKEN来管理token的生命周期。首先需要创建一张配置表ZDDT001用于存储token及其过期时间TYPES: BEGIN OF zddt001, appname TYPE zel_appname, 应用名称 appkey TYPE string, AppKey appsecret TYPE string, AppSecret token TYPE zel_token, 当前token overdate TYPE datum, 过期日期 overtime TYPE uzeit, 过期时间 END OF zddt001.函数的主要逻辑如下 检查token是否过期 IF sy-datum ls_zddt001-overdate AND sy-uzeit ls_zddt001-overtime. 使用缓存token ev_token ls_zddt001-token. ELSE. 构造token请求 lv_path /v1.0/oauth2/accessToken. ls_request-appkey ls_zddt001-appkey. ls_request-appsecret ls_zddt001-appsecret. 调用通用请求函数 CALL FUNCTION ZDD_SEND_TO_DING EXPORTING iv_path lv_path iv_body lv_body iv_method POST IMPORTING ev_data lv_result ev_status lv_status. 解析响应并更新token信息 /ui2/cl_jsondeserialize( EXPORTING json lv_result CHANGING data ls_result ). 计算新的过期时间提前10分钟过期 ls_zddt001-overtime sy-uzeit 110 * 60. 110分钟 ls_zddt001-overdate sy-datum. IF ls_zddt001-overtime 240000. ls_zddt001-overtime ls_zddt001-overtime - 86400. ls_zddt001-overdate ls_zddt001-overdate 1. ENDIF. 保存新token ls_zddt001-token ls_result-accesstoken. MODIFY zddt001 FROM ls_zddt001. ev_token ls_result-accesstoken. ENDIF.这个实现有几个优化点首先token的实际过期时间是2小时但我们设置110分钟就认为过期这样可以避免在临界时间点调用接口失败其次处理了跨日的情况避免时间计算错误最后所有数据库操作都在同一逻辑单元内完成保证数据一致性。7. 待办任务创建接口实现7.1 接口参数分析钉钉创建待办任务的API需要以下关键参数operatorId操作人钉钉IDsubject待办标题description待办描述支持富文本dueTime截止时间Unix时间戳毫秒级priority优先级0-低1-中2-高其中operatorId需要特别注意它不是钉钉账号的手机号或邮箱而是用户在钉钉组织内的唯一ID。可以通过钉钉的获取用户ID接口查询或者让用户在SAP系统中绑定自己的钉钉账号时记录这个ID。7.2 ABAP函数实现创建函数ZDD_CREATE_TASK核心代码如下 获取token CALL FUNCTION ZDD_GET_TOKEN EXPORTING iv_appname SAP_TODO IMPORTING ev_token lv_token. 设置请求头 ls_header-key x-acs-dingtalk-access-token. ls_header-value lv_token. APPEND ls_header TO lt_header. 构造请求体 ls_request-subject iv_subject. ls_request-description iv_description. ls_request-duetime iv_duetime. 需要转换为Unix时间戳 调用通用请求函数 CALL FUNCTION ZDD_SEND_TO_DING EXPORTING iv_path /v1.0/todo/users/ iv_userid /tasks iv_method POST iv_body lv_body IMPORTING ev_data lv_result ev_status lv_status TABLES it_header lt_header. 解析响应 /ui2/cl_jsondeserialize( EXPORTING json lv_result CHANGING data ls_result ). ev_taskid ls_result-id.实际项目中我们还需要考虑以下几点增强日期时间转换SAP中的日期和时间通常分开存储需要转换为Unix时间戳富文本支持description字段支持HTML格式可以利用SAP的文本编辑器生成错误处理区分网络错误、认证错误、业务错误等不同情况日志记录记录每次接口调用的请求和响应便于问题排查8. 实际应用场景扩展8.1 SAP审批流集成将待办创建逻辑嵌入到SAP的标准审批流程中可以在以下关键点触发审批任务创建时在METHOD EXECUTE_BEFORE_APPROVAL中调用审批任务超时提醒通过后台作业定期检查待审批事项审批结果通知在METHOD EXECUTE_AFTER_APPROVAL中更新待办状态例如在审批工作流的配置中可以添加一个自定义出口在出口函数中调用我们的ZDD_CREATE_TASK函数。8.2 批量任务处理对于需要批量创建待办的情况如月度报表审批我们可以优化实现 批量创建待办任务 LOOP AT lt_approvals INTO DATA(ls_approval). 转换日期格式 lv_duetime convert_to_unixtime( iv_date ls_approval-end_date iv_time 180000 ). 截止时间18:00 CALL FUNCTION ZDD_CREATE_TASK EXPORTING iv_userid ls_approval.ding_id iv_subject |请审批{ ls_approval-document_type }{ ls_approval-document_id }| iv_description ls_approval-description iv_duetime lv_duetime IMPORTING ev_taskid lv_taskid EXCEPTIONS OTHERS 1. IF sy-subrc 0. 记录SAP单据与钉钉待办的关联关系 ls_mapping-doc_id ls_approval-document_id. ls_mapping-task_id lv_taskid. APPEND ls_mapping TO lt_mapping. ENDIF. ENDLOOP. 批量提交数据库更新 MODIFY zapproval_mapping FROM TABLE lt_mapping.这种批量处理需要注意钉钉API的速率限制必要时可以添加延迟如使用WAIT UP TO 1 SECONDS语句。8.3 状态同步机制待办任务在钉钉端完成后我们需要将状态同步回SAP系统。这可以通过两种方式实现主动查询定时任务定期调用钉钉接口查询任务状态事件订阅在钉钉开放平台配置回调地址当任务状态变更时接收通知对于第二种方式需要在SAP系统中创建一个能够接收HTTP请求的服务。这可以通过实现IHTTP_EXTENSION接口的HANDLE_REQUEST方法来完成。收到回调后解析其中的任务ID和状态更新SAP系统中的对应记录。9. 性能优化与安全建议9.1 连接池管理频繁创建和销毁HTTP连接会消耗系统资源。我们可以实现一个简单的连接池CLASS zcl_dingtalk_conn_pool DEFINITION. PUBLIC SECTION. METHODS get_client RETURNING VALUE(ro_client) TYPE REF TO if_http_client. METHODS release_client IMPORTING io_client TYPE REF TO if_http_client. PRIVATE SECTION. DATA mt_clients TYPE TABLE OF REF TO if_http_client. ENDCLASS. METHOD get_client. IF lines( mt_clients ) 0. ro_client mt_clients[ 1 ]. DELETE mt_clients INDEX 1. ELSE. cl_http_clientcreate_by_destination( EXPORTING destination DINGTALK IMPORTING client ro_client ). ENDIF. ENDMETHOD.9.2 安全加固措施敏感信息加密将AppSecret等敏感信息存储在SAP安全存储中而非透明表接口权限控制限制可以调用钉钉接口的SAP账号和IP地址请求签名验证对于回调接口验证钉钉的签名防止伪造请求完备的日志记录所有接口调用的关键信息但注意不要记录敏感数据9.3 监控与告警建议实现以下监控点Token获取失败率接口平均响应时间任务创建成功率回调接收延迟可以在SAP中配置异常情况告警或者将监控数据推送到企业现有的监控平台。