SAP ABAP 动态结构实现发送企业微信应用消息

来源:博客园 2023-06-27 16:30:11

企业微信官方接口文档: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.实现效果:企业微信通知

关键词:

返回顶部