资讯动态

ABAP对接企业微信机器人:模版卡片消息的实战开发指南

发布时间:2026/8/24 4:10:20 来源:尧图企业网站定制
1. 项目概述为什么我们需要模版卡片在企业微信机器人消息推送这个场景里我们之前聊过文本、Markdown、图片甚至文件这些类型已经能覆盖大部分日常通知需求。但如果你做过一些复杂的业务状态推送比如采购订单审批结果、生产工单完工汇报、或者一张包含多个关键指标的日报你就会发现纯文本太单薄Markdown的排版在移动端又常常“水土不服”显示效果难以保证统一。这时候企业微信提供的“模版卡片”消息类型就成了我们ABAP开发者的“秘密武器”。简单来说模版卡片是一种预定义好样式和结构的富文本消息。它不像Markdown那样需要你手写一堆标记而是通过一个结构化的JSON数据来告诉企业微信客户端“这里放标题那里放关键数据下面再放几个按钮”。最终呈现给用户的是一个视觉上规整、信息层次清晰、并且可以交互的卡片。这对于将SAP中复杂的业务单据状态、或包含多个KPI的数据看板推送到移动端供管理者查阅体验提升不是一星半点。我最初接触它是因为业务部门抱怨每天的销售日报邮件太长关键信息总被淹没。用文本机器人推送又显得杂乱。直到试用了模版卡片把销售额、订单数、重点客户等几个核心指标做成卡片上的“关键数据”把详细报表作为“附件”链接放在下面反馈一下子就好了很多。它解决的核心痛点就两个在有限的屏幕空间内尤其是手机实现业务信息的高密度、结构化、美观呈现并赋予用户快捷的操作入口如跳转SAP、审批等。所以如果你正在用ABAP对接企业微信机器人并且你的消息内容符合以下几种情况那么模版卡片几乎是你必须掌握的技能状态通知类如“采购订单#4500001234已审批通过”、“生产工单100001234已完成良品率98.5%”。数据汇报类如“昨日销售总额¥1,234,567环比12%”、“本月库存周转率2.5次”。待办任务类如“你有3张报销单待审批”、“客户A的信用申请需您处理”。混合内容类需要同时展示文本、数据、图片如图表缩略图和操作按钮。接下来我们就深入拆解如何在ABAP中一步步构造并发送出各种类型的模版卡片消息。2. 模版卡片核心类型与选择策略企业微信的模版卡片主要分为两大类每一类下又有不同子类型适用于不同场景。选择对的类型是成功的第一步。2.1 文本通知型模版卡片这类卡片以文字信息展示为主是使用最广泛的类型。1. 文本通知型 (text_notice)这是最基础的模版卡片也是我推荐新手最先上手的类型。它的结构清晰包含标题、描述、提示信息等固定字段。核心字段source: 消息来源比如“SAP系统”、“ERP通知”。main_title: 卡片主标题通常用加粗大字体显示用于概括事件如“采购订单审批完成”。sub_title_text: 副标题在主标题下方常用作补充说明如“单号4500001234”。emphasis_content: 强调内容会以醒目样式如橙色、加大字体展示用于突出最关键的数据或状态如“状态已批准”。horizontal_content_list: 水平内容列表用于以“标签: 值”的形式平行展示多个关键信息非常适合展示业务单据的多个字段。jump_list: 跳转链接列表可以添加多个带图标的链接比如“查看SAP单据”、“下载PDF”。card_action: 整个卡片的点击动作可以设置为跳转一个URL。2. 图文展示型 (news_notice)当你的通知需要配图时就用它。比如推送一个带有产品图片的新品上市通知或者一个带有统计图表缩略图的日报。核心特点在左侧或上方有一个显著的图片区域右侧或下方是文字内容。图片能极大提升消息的吸引力和信息传达效率。ABAP实现注意点图片需要先上传到企业微信素材库获取media_id或者使用公网可访问的图片URL。在ABAP中通常更推荐先上传到临时素材因为内网图片地址无法被企业微信客户端直接访问。2.2 交互按钮型模版卡片这类卡片的核心是提供了用户可直接在聊天窗口内操作的按钮无需跳转到其他应用极大简化了操作流程。1. 按钮交互型 (button_interaction)这是功能最强大的类型之一。它允许你在卡片底部放置1到3个按钮。按钮类型url_button: 点击后跳转指定网页可以用于跳转SAP WebGUI、Fiori Launchpad或自定义的Web应用页面。call_phone_button: 点击后直接拨打电话。copy_text_button: 点击后将指定文本复制到剪贴板非常适合分享订单号、合同编号等信息。应用场景一个“设备报警”通知卡片可以放置“查看详情”跳转监控页面、“确认接收”调用企业微信API回传状态到SAP、“呼叫负责人”三个按钮。2. 投票选择型 (vote_interaction)用于简单的投票、调研或状态选择。例如推送一个“会议时间征集”卡片让接收者在几个时间选项上点击选择。核心字段checkbox或radio类型的选项列表以及提交按钮。ABAP对接难点用户提交选择后企业微信服务器会向你的应用服务器接收消息的URL推送一个事件。这意味着你需要在ABAP端或通过ABAP调用的中间件提供一个能接收并解析HTTP POST请求的服务来处理用户的反馈。这对纯ABAP环境有一定挑战通常需要借助NetWeaver的ICF服务或一个简单的Java/Python中间件。3. 多项选择型 (multiple_interaction)比投票更复杂允许用户填写表单。例如推送一个“故障报修”卡片包含设备编号文本输入、故障描述多行文本、紧急程度下拉选择等字段。实现复杂度最高。同样需要处理用户提交的表单数据回传。选择策略与心得 对于绝大多数SAP集成场景文本通知型 (text_notice)和按钮交互型 (button_interaction)的组合已经能解决95%的问题。我的经验是纯通知无操作- 用text_notice把信息排版漂亮即可。通知且需要跳转查看详情- 用text_notice并在jump_list或card_action里设置跳转链接。通知且需要用户在消息里完成简单操作如确认、选择- 用button_interaction。把复杂的表单填写留在跳转后的页面在卡片上只做最关键的“动作分发”。投票、调研等轻互动- 评估技术可行性后考虑vote_interaction。如果接收消息的服务端不好实现不如直接推送一个带链接的卡片让用户点进去到网页上操作。3. ABAP实现详解从数据结构到消息发送理论说完了我们上干货。如何在ABAP里构造这些复杂的JSON并发送出去核心在于精心设计数据结构和使用高效的JSON生成方法。3.1 定义ABAP内部表与结构我强烈建议不要用字符串拼接的方式去构造JSON那是一场维护灾难。我们应该定义与微信API文档匹配的ABAP结构。首先定义最核心的卡片内容结构。这里以text_notice为例TYPES: BEGIN OF ty_template_card_text, card_type TYPE string, text_notice source TYPE BEGIN OF ty_source, icon_url TYPE string, desc TYPE string, END OF ty_source, main_title TYPE BEGIN OF ty_main_title, title TYPE string, desc TYPE string, END OF ty_main_title, emphasis_content TYPE BEGIN OF ty_emphasis, title TYPE string, desc TYPE string, END OF ty_emphasis, sub_title_text TYPE string, horizontal_content_list TYPE STANDARD TABLE OF ty_horizontal_content WITH EMPTY KEY, jump_list TYPE STANDARD TABLE OF ty_jump WITH EMPTY KEY, card_action TYPE BEGIN OF ty_card_action, type TYPE i, 1 代表跳转url url TYPE string, END OF ty_card_action, END OF ty_template_card_text. TYPES: BEGIN OF ty_horizontal_content, keyname TYPE string, 如“订单类型” value TYPE string, 如“标准采购订单” END OF ty_horizontal_content. TYPES: BEGIN OF ty_jump, title TYPE string, 如“查看详情” url TYPE string, END OF ty_jump.然后定义整个请求报文的结构TYPES: BEGIN OF ty_wechat_robot_msg, msgtype TYPE string, template_card template_card TYPE ty_template_card_text, 这里根据类型可变化 END OF ty_wechat_robot_msg.3.2 使用/UI2/CL_JSON高效生成JSONSAP NetWeaver 7.4 以上版本推荐使用官方类/UI2/CL_JSON。它非常强大能直接将ABAP结构序列化为JSON。METHODS send_template_card IMPORTING is_card_data TYPE ty_wechat_robot_msg. DATA: lo_json TYPE REF TO /ui2/cl_json, lv_json_string TYPE string, lv_response TYPE string. CREATE OBJECT lo_json. 设置序列化选项转换日期格式、忽略初始值等 lo_json-serialize( EXPORTING data is_card_data compress abap_true 压缩输出去掉无用的空格 name_mapping /ui2/cl_jsoncamel_case 将ABAP字段名如CARD_TYPE转换为JSON的cardType RECEIVING r_json lv_json_string ). 现在 lv_json_string 就是完美的JSON payload 接下来调用HTTP客户端发送到企业微信机器人Webhook地址 ... (HTTP POST调用代码同之前文章)关键技巧name_mapping /ui2/cl_jsoncamel_case这个参数至关重要因为企业微信API要求字段名是驼峰命名cardType而我们的ABAP结构是下划线命名CARD_TYPE。这个参数会自动完成转换。compress abap_true可以让生成的JSON更紧凑虽然不是必须但是个好习惯。确保所有字符串字段的类型是STRING而不是CHAR避免尾部空格被序列化到JSON中。3.3 一个完整的text_notice发送示例假设我们要推送一个采购订单创建成功的通知。DATA: ls_msg TYPE ty_wechat_robot_msg, ls_card TYPE ty_template_card_text, lt_horizontal TYPE TABLE OF ty_horizontal_content, ls_horizontal TYPE ty_horizontal_content, lt_jump TYPE TABLE OF ty_jump, ls_jump TYPE ty_jump. 1. 构建卡片内容 ls_card-card_type text_notice. ls_card-source-icon_url https://example.com/sap-icon.png. 可选的来源图标 ls_card-source-desc SAP采购系统. ls_card-main_title-title 采购订单创建成功. ls_card-main_title-desc 请知悉. ls_card-emphasis_content-title 状态已保存. emphasis_content.desc 可选 ls_card-sub_title_text |订单号{ lv_ebeln }|. lv_ebeln 是订单号变量 水平内容列表 ls_horizontal-keyname 供应商. ls_horizontal-value lv_lifnr_name. 供应商名称 APPEND ls_horizontal TO lt_horizontal. CLEAR ls_horizontal. ls_horizontal-keyname 金额. ls_horizontal-value |{ lv_netwr CURRENCY lv_waers } { lv_waers }|. APPEND ls_horizontal TO lt_horizontal. CLEAR ls_horizontal. ls_horizontal-keyname 创建人. ls_horizontal-value lv_ernam. APPEND ls_horizontal TO lt_horizontal. ls_card-horizontal_content_list lt_horizontal. 跳转列表 ls_jump-title 在SAP中查看. ls_jump-url |https://your-sap-server/sap/bc/gui/sap/its/webgui?~transactionME23N~{ lv_ebeln }|. APPEND ls_jump TO lt_jump. ls_card-jump_list lt_jump. 整个卡片的点击动作点击卡片任意处跳转 ls_card-card_action-type 1. ls_card-card_action-url ls_jump-url. 同上跳转到ME23N 2. 构建完整消息 ls_msg-msgtype template_card. ls_msg-template_card ls_card. 3. 调用发送方法 send_template_card( ls_msg ).这样用户在企业微信里就会收到一张美观的卡片清晰地展示了订单关键信息并且点击卡片或“在SAP中查看”链接都能直接打开SAP事务码ME23N查看该订单。4. 按钮交互型卡片的进阶实现按钮卡片(button_interaction)的实现略有不同关键在于定义按钮列表。首先需要扩展我们的类型定义TYPES: BEGIN OF ty_template_card_button, card_type TYPE string, button_interaction source TYPE ty_source, 同前 main_title TYPE ty_main_title, 同前 sub_title_text TYPE string, horizontal_content_list TYPE STANDARD TABLE OF ty_horizontal_content WITH EMPTY KEY, card_action TYPE ty_card_action, 同前 button_selection TYPE BEGIN OF ty_button_selection, question_key TYPE string, title TYPE string, button_list TYPE STANDARD TABLE OF ty_button WITH EMPTY KEY, END OF ty_button_selection, END OF ty_template_card_button. TYPES: BEGIN OF ty_button, text TYPE string, key TYPE string, 按钮唯一标识点击事件会回传这个key type TYPE i, 按钮类型0-点击事件1-跳转URL url TYPE string, type1时有效 END OF ty_button.发送一个带有“确认收货”和“查看详情”按钮的送货单通知DATA: ls_button_card TYPE ty_template_card_button, lt_buttons TYPE TABLE OF ty_button, ls_button TYPE ty_button. ls_button_card-card_type button_interaction. ls_button_card-main_title-title 送货单待确认. ls_button_card-main_title-desc |单号{ lv_delivery_doc }|. ls_button_card-sub_title_text |供应商{ lv_supplier } 物料{ lv_material }|. 定义按钮 ls_button-text 确认收货. ls_button-key CONFIRM_RECEIPT. ls_button-type 0. 点击事件需要接收回调 APPEND ls_button TO lt_buttons. CLEAR ls_button. ls_button-text 查看详情. ls_button-key VIEW_DETAIL. ls_button-type 1. 跳转URL ls_button-url |{ gv_sap_base_url }/delivery/{ lv_delivery_doc }|. APPEND ls_button TO lt_buttons. ls_button_card-button_selection-title 请选择操作. ls_button_card-button_selection-button_list lt_buttons. 发送...重要提示当按钮类型(type)为0点击事件时用户点击按钮后企业微信会向你的“接收消息”服务器在应用管理里配置的URL推送一个事件。你需要在后端服务中解析这个事件其中包含button_key然后执行相应的ABAP逻辑如更新数据库表LIKP并可能通过企业微信API给用户发送一个操作结果反馈。这需要你有一个能处理HTTP POST请求的接收端点在纯ABAP环境中可以通过创建ICF服务来实现。5. 常见问题、调试技巧与性能优化在实际开发中你肯定会遇到各种坑。这里分享一些我踩过并总结出来的经验。5.1 消息发送失败排查清单JSON格式错误这是最常见的问题。务必使用/UI2/CL_JSON等工具生成JSON避免手拼。将生成的lv_json_string输出到应用日志或调试器中复制到在线JSON校验器如 jsonlint.com检查格式。字段名不符合驼峰命名确认序列化时使用了name_mapping /ui2/cl_jsoncamel_case。检查生成的JSON字段名应该是cardType而不是card_type。字段类型或值不符合API要求仔细阅读企业微信官方文档。例如card_type的值必须是特定的字符串如text_noticebutton的type字段是整数不是字符串。Webhook地址错误或机器人被禁用再次检查机器人的Webhook地址是否复制正确并在企业微信手机端确认该机器人仍在群聊中且未被移除。网络或代理问题确保你的SAP服务器能够访问外网的qyapi.weixin.qq.com。如果公司有网络代理需要在HTTP客户端的DESTINATION中配置或使用类CL_HTTP_EXT设置代理。内容长度超限模版卡片的总内容JSON文本有一定长度限制。如果内容过长特别是horizontal_content_list或描述信息太多可能导致发送失败。尽量精简文字关键信息用字段展示。5.2 在ABAP中调试HTTP请求与响应光靠猜是不行的必须把请求和响应内容记录下来。 在调用HTTP客户端发送前记录请求JSON DATA(lv_request_json) lv_json_string. 来自serialize方法 可以将lv_request_json记录到应用日志表、发送到外部监控系统或简单地在测试时用WRITE输出 在收到HTTP响应后记录状态码和响应体 IF lo_http_client IS BOUND. DATA(lv_status) lo_http_client-response-get_status( ). DATA(lv_response_body) lo_http_client-response-get_cdata( ). 记录 lv_status 和 lv_response_body ENDIF.企业微信API在失败时响应体通常是JSON如{errcode:40035,errmsg:invalid json format}。errcode是排查的关键。5.3 性能优化与最佳实践复用HTTP客户端如果在一个程序内需要发送多条消息不要为每条消息都创建和销毁一个HTTP客户端。复用同一个客户端对象只替换请求数据和重新发送可以显著减少开销。异步发送对于非实时性要求极高的通知如批量报表推送可以考虑使用后台作业或ABAP Channels进行异步发送避免阻塞主业务进程。消息模板化将常用的卡片样式如“成功通知”、“失败告警”、“待办提醒”抽象成可配置的模板。在ABAP中可以定义一些模板结构通过传入不同的参数如订单号、金额、状态来动态填充。甚至可以将其配置在自定义表中让业务人员能维护模板内容。错误处理与重试网络请求可能失败。实现一个简单的重试机制比如失败后等待2秒重试一次。同时将发送失败的消息包括目标、内容、错误信息记录到数据库表中便于后续排查和手动补发。敏感信息脱敏在构造消息内容时尤其是金额、客户信息等要确保符合公司的数据安全政策。避免在通知中泄露不必要的敏感信息。5.4 关于“接收消息”服务器回调的ABAP实现思路如果你想实现按钮的点击回调需要在ABAP端提供一个HTTP服务。一个可行的方案是使用SAP的Internet Communication Framework (ICF)创建一个简单的服务。步骤使用事务码SICF创建一个新的服务。为其分配一个处理器类Handler Class这个类需要实现接口IF_HTTP_EXTENSION。在HANDLE_REQUEST方法中解析收到的HTTP POST请求体即企业微信推送的JSON事件。根据事件类型EventType和按钮KEYButtonKey调用相应的ABAP业务逻辑。按照企业微信要求返回一个特定的JSON响应以表示接收成功。注意这涉及到企业微信应用服务器的配置设置接收消息的URL和Token、EncodingAESKey以及ABAP ICF服务的公网暴露可能需要网络部门开通防火墙策略实施复杂度较高。对于很多场景用按钮跳转URL到Web页面再操作是更简单直接的选择。模版卡片极大地丰富了ABAP推送消息的表现力和交互能力。从简单的文本通知到带按钮的交互卡片它让SAP的后台业务事件能够以更友好、更高效的方式触达前端用户。掌握它你的SAP消息集成方案就从“能用”升级到了“好用”。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价