SAP ABAP 動態結構實現傳送企業微信應用訊息

2023-06-27 18:00:48

企業微信官方介面檔案: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: <is_str> TYPE any.
 84   "參照建立的動態構造
 85   IF dref_str IS BOUND.
 86     ASSIGN  dref_str->* TO <is_str>.
 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. "人員ID
103     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. "部門ID
113     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.   "標籤ID
123     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:<fs_msg_value> TYPE any.
133   "用指標<fs_msg_value>指向工作區<is_str>中的一個欄位,欄位名為i_msgtype.
134   ASSIGN COMPONENT i_msgtype OF STRUCTURE <is_str> TO <fs_msg_value>.
135   "給指標指向的欄位賦值
136   <fs_msg_value> = i_message.  "介面message傳值
137 
138 *--通用引數處理
139   MOVE-CORRESPONDING VALUE ty_common( touser = l_touser
140                              toparty = l_toparty
141                                totag = l_totag
142                              msgtype = i_msgtype
143                              agentid = i_agentid
144               enable_duplicate_check = 1 ) TO <is_str>.  "開啟重複訊息檢查
145 
146   "abap結構轉json
147   /ui2/cl_json=>serialize( EXPORTING data = <is_str>
148                               pretty_name = 'L' "空大寫,L小寫,X駝峰,Y增強駝峰
149                          RECEIVING r_json = lv_json ).
150 
151 
152   "特殊字元反跳脫
153   lv_json = replace(  val = lv_json
154                       sub = '\"'
155                      with = '"'
156                       occ = '0' ).
157 
158   lv_json = replace(  val = lv_json
159                       sub = '\\'
160                      with = '\'
161                       occ = '0' ).
162 
163   lv_json = replace(  val = lv_json
164                       sub = '"{'
165                      with = '{'
166                       occ = '0' ).
167 
168   lv_json = replace(  val = lv_json
169                       sub = '}"'
170                      with = '}'
171                       occ = '0' ).
172 
173 
174 
175 *--http請求處理
176   CALL FUNCTION 'ZWECHAT_GET_ACCESS_TOKEN'    "獲取token
177     EXPORTING
178       i_corpid       = i_corpid
179       i_corpsecret   = i_corpsecret
180     IMPORTING
181       o_access_token = access_token.
182 
183 
184   url =  url && access_token.
185 
186 
187   CALL METHOD cl_http_client=>create_by_url
188     EXPORTING
189       url                = url
190     IMPORTING
191       client             = lv_client
192     EXCEPTIONS
193       argument_not_found = 1
194       plugin_not_active  = 2
195       internal_error     = 3
196       OTHERS             = 4.
197 
198 
199   lv_client->request->set_header_field( name = '~request_method' value = 'POST' )."呼叫方法get OR post
200   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     EXCEPTIONS
208       http_communication_failure = 1
209       http_invalid_state         = 2 ).
210 * Prepare client-receive:
211 
212   CALL METHOD lv_client->receive
213     EXCEPTIONS
214       http_communication_failure = 1
215       http_invalid_state         = 2
216       http_processing_failed     = 3
217       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     EXPORTING
23       date = s_budat-low
24     IMPORTING
25       week = l_week
26 *   EXCEPTIONS
27 *     DATE_INVALID       = 1
28 *     OTHERS             = 2
29     .
30   IF sy-subrc <> 0.
31 * Implement suitable error handling here
32   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 = '<div class=\"gray\">' && s_budat-low && '-' && s_budat-high && '</div>'.
42   ls_textcard-description = ls_textcard-description && '<div class=\"normal\">' && '' && l_week+0(4) && 'W' && l_week+4(2) && ''.
43   ls_textcard-description = ls_textcard-description && '供應商來料不良情況彙總-Week</div>'.
44   ls_textcard-description = ls_textcard-description && '<div class=\"normal\">未達標供應商個數:' && lv_count_v && '</div>'.
45   ls_textcard-description = ls_textcard-description && '<div class=\"normal\">不良物料號個數:' && lv_count_m && '</div>'.
46   ls_textcard-description = ls_textcard-description && '<div class=\"highlight\">具體明細已傳送至您的郵箱</div>'.
47 
48   "abap資料轉json
49   CLEAR:lv_json.
50   /ui2/cl_json=>serialize( EXPORTING data = ls_textcard
51                                      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     EXPORTING
59       i_message = lv_json
60       i_msgtype = 'textcard'
61     IMPORTING
62       e_message = e_message
63     TABLES
64       t_totag   = lt_wechat_tag[].
65 
66 ENDFORM.

 

3.實現效果:企業微信通知