SAP ABAP 动态结构实现发送企业微信应用消息
企业微信官方接口文档:https://developer.work.weixin.qq.com/document/path/90236
(资料图片仅供参考)
应用支持推送文本、图片、视频、文件、图文等类型。
请求方式:POST(HTTPS)请求地址:https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=ACCESS_TOKEN
大概思路:
1. 封装调用企业微信函数 SE37 :ZWECHAT_SEND_MESSAGE_MSGTYPE
注:
a. I_MSGTYPE参数值 作为动态值新增到表结构,构造企业微信API body
b. I_MESSAGE参数值 为json格式的消息内容
2.程序调用 ZWECHAT_SEND_MESSAGE_MSGTYPE,传入处理过的I_MESSAGE
代码实现:
1.SE37 :ZWECHAT_SEND_MESSAGE_MSGTYPE
1 FUNCTION zwechat_send_message_msgtype. 2 *"---------------------------------------------------------------------- 3 *"*"本地接口: 4 *" IMPORTING 5 *" VALUE(I_MESSAGE) TYPE STRING 6 *" VALUE(I_MSGTYPE) TYPE STRING 7 *" EXPORTING 8 *" VALUE(E_MESSAGE) TYPE STRING 9 *" TABLES 10 *" T_TOUSER STRUCTURE ZWECHAT_NOTIFYER OPTIONAL 11 *" T_TOPARTY STRUCTURE ZWECHAT_NOTIFYER OPTIONAL 12 *" T_TOTAG STRUCTURE ZWECHAT_NOTIFYER OPTIONAL 13 *"---------------------------------------------------------------------- 14 15 16 DATA:url TYPE string VALUE "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token="."接口地址 17 DATA:i_agentid TYPE string VALUE "小程序ID". 18 DATA:i_corpid TYPE string VALUE "公司的ID". 19 DATA:i_corpsecret TYPE string VALUE "企业应用secret". 20 21 DATA:access_token TYPE string. 22 DATA:lv_client TYPE REF TO if_http_client. 23 24 DATA:l_touser TYPE string. 25 DATA:l_toparty TYPE string. 26 DATA:l_totag TYPE string. 27 28 29 "http通用参数 30 TYPES:BEGIN OF ty_common, 31 touser TYPE string, "成员ID列表,多个接收者用‘|’分隔,最多支持1000个 32 toparty TYPE string, "部门ID列表,多个接收者用‘|’分隔,最多支持100个 33 totag TYPE string, "标签ID列表,多个接收者用‘|’分隔,最多支持100个 34 msgtype TYPE string, "消息类型 35 agentid TYPE string, "企业应用的id 36 safe TYPE i, "表示是否是保密消息,0表示可对外分享,1表示不能分享且内容显示水印,默认为0 37 enable_id_trans TYPE i, "是否开启id转译,0表示否,1表示是,默认0。仅第三方应用需要用到,企业自建应用可以忽略 38 enable_duplicate_check TYPE i, "是否开启重复消息检查,0表示否,1表示是,默认0 39 duplicate_check_interval TYPE i, "是否重复消息检查的时间间隔,默认1800s,最大不超过4小时 40 END OF ty_common. 41 42 43 "http返回 44 TYPES:BEGIN OF t_record, 45 errcode TYPE string, 46 errmsg TYPE string, 47 END OF t_record. 48 49 DATA:json TYPE string. 50 DATA:record TYPE t_record. 51 DATA:common TYPE ty_common. 52 53 DATA:ev_data(6000) TYPE c."返回 54 DATA:lv_json TYPE string. 55 56 57 *--动态创建结构和表 58 DATA: 59 dref_str TYPE REF TO data, 60 struct_type TYPE REF TO cl_abap_structdescr, 61 elem_type TYPE REF TO cl_abap_elemdescr, 62 comp_tab TYPE cl_abap_structdescr=>component_table WITH HEADER LINE. 63 64 "动态创建结构类型 65 * struct_type ?= cl_abap_structdescr=>describe_by_name( "ZTPP200" ). "根据名称获取系统创建好的结构 66 struct_type ?= cl_abap_structdescr=>describe_by_data( common ). "根据程序中定义的结构,创建结构类型 67 68 "获取该结构类型中,结构组件(字段) 69 comp_tab[] = struct_type->get_components( )."组成结构体的各个字段组件 70 71 "扩展结构字段 72 elem_type ?= cl_abap_elemdescr=>get_string( ). 73 comp_tab-name = i_msgtype. "新增成员的类型名称,消息类型 74 comp_tab-type = elem_type. "新增成员的类型对象 75 INSERT comp_tab INTO comp_tab INDEX 1. 76 77 78 "根据新的组件创建结构类型 79 struct_type = cl_abap_structdescr=>create( comp_tab[] ). 80 "根据结构类型,创建结构对象 81 CREATE DATA dref_str TYPE HANDLE struct_type. 82 83 FIELD-SYMBOLS:TYPE any. 84 "引用创建的动态构造 85 IF dref_str IS BOUND. 86 ASSIGN dref_str->* TO . 87 ENDIF. 88 89 90 91 *--基本检查 92 CHECK ( t_touser[] IS NOT INITIAL 93 OR t_toparty[] IS NOT INITIAL 94 OR t_totag[] IS NOT INITIAL ) AND i_message IS NOT INITIAL. 95 96 97 CLEAR:l_touser,l_toparty,l_totag,lv_json,ev_data,record,json. 98 99 *--通知人员处理100 DATA(l_lines) = lines( t_touser ).101 102 LOOP AT t_touser. "人员ID103 IF sy-tabix = l_lines.104 l_touser = t_touser-notifyer && l_touser && "".105 ELSE.106 l_touser = l_touser && "|" && t_touser-notifyer.107 ENDIF.108 ENDLOOP.109 110 CLEAR:l_lines.111 l_lines = lines( t_totag ).112 LOOP AT t_toparty. "部门ID113 IF sy-tabix = l_lines.114 l_toparty = t_toparty-notifyer && l_toparty && "".115 ELSE.116 l_toparty = l_toparty && "|" && t_toparty-notifyer.117 ENDIF.118 ENDLOOP.119 120 CLEAR:l_lines.121 l_lines = lines( t_totag ).122 LOOP AT t_totag. "标签ID123 IF sy-tabix = l_lines.124 l_totag = t_totag-notifyer && l_totag && "".125 ELSE.126 l_totag = l_totag && "|" && t_totag-notifyer.127 ENDIF.128 ENDLOOP.129 130 131 *--message处理132 FIELD-SYMBOLS: TYPE any.133 "用指针 指向工作区 中的一个字段,字段名为i_msgtype.134 ASSIGN COMPONENT i_msgtype OF STRUCTURE TO .135 "给指针指向的字段赋值136 = i_message. "接口message传值137 138 *--通用参数处理139 MOVE-CORRESPONDING VALUE ty_common( touser = l_touser140 toparty = l_toparty141 totag = l_totag142 msgtype = i_msgtype143 agentid = i_agentid144 enable_duplicate_check = 1 ) TO . "开启重复消息检查145 146 "abap结构转json147 /ui2/cl_json=>serialize( EXPORTING data = 148 pretty_name = "L" "空大写,L小写,X驼峰,Y增强驼峰149 RECEIVING r_json = lv_json ).150 151 152 "特殊字符反转义153 lv_json = replace( val = lv_json154 sub = "\""155 with = """156 occ = "0" ).157 158 lv_json = replace( val = lv_json159 sub = "\\"160 with = "\"161 occ = "0" ).162 163 lv_json = replace( val = lv_json164 sub = ""{"165 with = "{"166 occ = "0" ).167 168 lv_json = replace( val = lv_json169 sub = "}""170 with = "}"171 occ = "0" ).172 173 174 175 *--http请求处理176 CALL FUNCTION "ZWECHAT_GET_ACCESS_TOKEN" "获取token177 EXPORTING178 i_corpid = i_corpid179 i_corpsecret = i_corpsecret180 IMPORTING181 o_access_token = access_token.182 183 184 url = url && access_token.185 186 187 CALL METHOD cl_http_client=>create_by_url188 EXPORTING189 url = url190 IMPORTING191 client = lv_client192 EXCEPTIONS193 argument_not_found = 1194 plugin_not_active = 2195 internal_error = 3196 OTHERS = 4.197 198 199 lv_client->request->set_header_field( name = "~request_method" value = "POST" )."调用方法get OR post200 lv_client->request->set_content_type( "application/json" ).201 202 "传入参数json格式203 lv_client->request->set_cdata( lv_json ).204 205 206 CALL METHOD lv_client->send(207 EXCEPTIONS208 http_communication_failure = 1209 http_invalid_state = 2 ).210 * Prepare client-receive:211 212 CALL METHOD lv_client->receive213 EXCEPTIONS214 http_communication_failure = 1215 http_invalid_state = 2216 http_processing_failed = 3217 OTHERS = 4.218 219 * Get HTML:220 ev_data = lv_client->response->get_cdata( )."返回值221 222 json = ev_data.223 224 /ui2/cl_json=>deserialize( EXPORTING json = json CHANGING data = record ).225 226 e_message = record-errmsg.227 228 229 ENDFUNCTION.
2.程序调用ZWECHAT_SEND_MESSAGE_MSGTYPE
1 FORM frm_send_wechat . 2 3 DATA:BEGIN OF ls_textcard, 4 title TYPE string VALUE "FDPPM质量预警监控平台推送", 5 description TYPE string, 6 url TYPE string VALUE "https://exmail.qq.com/login", 7 btntxt TYPE string VALUE "更多", 8 END OF ls_textcard. 9 10 DATA:lv_json TYPE string.11 DATA:e_message TYPE string.12 CLEAR:lv_json.13 14 DATA:l_week LIKE scal-week.15 16 17 SELECT ad_smtpadr FROM zmm_t_0003 INTO TABLE @DATA(lt_wechat_tag) WHERE status = "W" AND zprogram = @sy-repid.18 19 CHECK lt_wechat_tag[] IS NOT INITIAL.20 21 CALL FUNCTION "DATE_GET_WEEK"22 EXPORTING23 date = s_budat-low24 IMPORTING25 week = l_week26 * EXCEPTIONS27 * DATE_INVALID = 128 * OTHERS = 229 .30 IF sy-subrc <> 0.31 * Implement suitable error handling here32 ENDIF.33 34 CONDENSE lv_count_v.35 CONDENSE lv_count_m.36 37 IF s_budat-high IS INITIAL.38 s_budat-high = sy-datum.39 ENDIF.40 41 ls_textcard-description = "" && s_budat-low && "-" && s_budat-high && "".42 ls_textcard-description = ls_textcard-description && "" && "【" && l_week+0(4) && "W" && l_week+4(2) && "】".43 ls_textcard-description = ls_textcard-description && "供应商来料不良情况汇总-Week".44 ls_textcard-description = ls_textcard-description && "未达标供应商个数:" && lv_count_v && "".45 ls_textcard-description = ls_textcard-description && "不良物料号个数:" && lv_count_m && "".46 ls_textcard-description = ls_textcard-description && "具体明细已发送至您的邮箱".47 48 "abap数据转json49 CLEAR:lv_json.50 /ui2/cl_json=>serialize( EXPORTING data = ls_textcard51 pretty_name = "L" "空大写,L小写,X驼峰,Y增强驼峰52 RECEIVING r_json = lv_json ).53 54 lv_json = replace( val = lv_json sub = "\"" with = """ occ = "0" ).55 lv_json = replace( val = lv_json sub = "\\" with = "\" occ = "0" ).56 57 CALL FUNCTION "ZWECHAT_SEND_MESSAGE_MSGTYPE"58 EXPORTING59 i_message = lv_json60 i_msgtype = "textcard"61 IMPORTING62 e_message = e_message63 TABLES64 t_totag = lt_wechat_tag[].65 66 ENDFORM.
3.实现效果:企业微信通知
关键词: