再次吐槽下,微信素材管理和群发这块文档对java很不友好,此文需要结合我前文和官方文档。
测试号调试群发只需看是否群发消息是否能组装成功,不需要看结果如何(反正不会发送成功的),因为微信还没开放这个功能(估计也不会开放的)。
一、群发说明
在公众平台网站上,为订阅号提供了每天一条的群发权限,为服务号提供每月(自然月)4条的群发权限。
1、对于认证订阅号,群发接口每天可成功调用1次,此次群发可选择发送给全部用户或某个标签;
2、对于认证服务号虽然开发者使用高级群发接口的每日调用限制为100次,但是用户每月只能接收4条,无论在公众平台网站上,还是使用接口群发,用户每月只能接收4条群发消息,多于4条的群发将对该用户发送失败;
3、开发者可以主动设置 clientmsgid 来避免重复推送。
4、群发接口每分钟限制请求60次,超过限制的请求会被拒绝。
5、图文消息正文中插入自己帐号和其他公众号已群发文章链接的能力。
二、群发图文消息过程
1、首先,预先将图文消息中需要用到的图片,使用上传图文消息内图片接口,上传成功并获得图片 url;参考前文的上传图文消息内的图片获取url方法
2、上传图文消息素材,需要用到图片时,请使用上一步获取的图片 url;
3、使用对用户标签的群发,或对 openid 列表的群发,将图文消息群发出去,群发时微信会进行原创校验,并返回群发操作结果;
4、在上述过程中,如果需要,还可以预览图文消息、查询群发状态,或删除已群发的消息等。
三、群发图片、文本等其他消息类型的过程
1、如果是群发文本消息,则直接根据下面的接口说明进行群发即可;
2、如果是群发图片、视频等消息,则需要预先通过素材管理接口准备好 mediaid。
四、is_to_all说明
用于设定是否向全部用户发送,值为true或false,选择true该消息群发给所有用户,选择false可根据tag_id发送给指定群组的用户。
五、两种群发方式
根据标签进行群发,订阅号与服务号必须通过认证
接口:https://api.weixin.qq.com/cgi-bin/message/mass/sendall?access_token=access_token
根据openid列表群发,只适用于认证后的服务号
接口:https://api.weixin.qq.com/cgi-bin/message/mass/send?access_token=access_token
post数据可以是图文消息、文本、语音/音频、图片、视频、卡券消息(所有使用到media_id的地方,现在都可以使用素材管理中的永久素材media_id了)
1、图文消息post数据中的media_id需要通过上传图文消息素材接口获取(https://api.weixin.qq.com/cgi-bin/media/uploadnews?access_token=access_token)
这个跟素材管理里的新增永久图文素材接口post数据一样,只是接口不一样、返回的json多了一个type和created_at,参考我前文的新增永久图文素材方法
2、语音/音频、图片post数据中的media_id需要通过上传下载多媒体文件接口获得,参考我前文的新增临时/永久素材方法
3、视频post数据中的media_id最麻烦,先得通过上传下载多媒体文件接口获取到media_id(经测试,永久的下一步报错提示无效media_id),然后再通过特别接口再获取到一个media_id,这才是群发所需要的media_id
六、群发示例controller
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
@requestmapping ( "/sendbyopenid" ) public massmsgresult sendbyopenid() throws exception { // 根据openid列表群发图文消息 string mediapath1 = "c:/users/phil/pictures/image/8538572f61d7a94cf0b9fe0f290cdb28.jpg" ; uploadmediasresult result1 = httprequtil.uploadtempmedia( "phil_token" , "image" , mediapath1); string mediapath2 = "c:/users/phil/pictures/image/685977abgw1f8xqp46dgyj20qo0zktfi.jpg" ; uploadmediasresult result2 = httprequtil.uploadtempmedia( "phil_token" , "image" , mediapath2); list<uploadnewsmedia> array = new arraylist<>(); uploadnewsmedia entity1 = new uploadnewsmedia(); entity1.setauthor( "phil" ); entity1.setcontent( "人生只有经历才会懂得,只有懂得才知道珍惜,一生中,总会有一个人让你笑得最甜,也总会有一个人让你痛得最深,忘记,是善待自己" ); entity1.setcontent_source_url( "http://blog.csdn.net/phil_jing" ); // entity1.setdigest("digest"); entity1.setshow_conver_pic( 1 ); entity1.setthumb_media_id(result1.getmedia_id()); entity1.settitle( "心灵鸡汤" ); array.add(entity1); uploadnewsmedia entity2 = new uploadnewsmedia(); entity2.setauthor( "phil" ); entity2.setcontent( "什么是幸福,幸福就是自己的一种愉快的心理状态和感受。时时、事事都能使自己快乐的人才是最幸福的人。最快乐的人,就是最幸福的人。笑口常开的人,是最幸福的。" ); entity2.setcontent_source_url( "http://www.qq.com" ); // entity2.setdigest("digest"); entity2.setshow_conver_pic( 0 ); entity2.setthumb_media_id(result2.getmedia_id()); entity2.settitle( " 经典语录" ); array.add(entity2); uploadmediasresult ur = httprequtil.uploadnewsmedia( "phil_token" , array); list<string> openids = new arraylist<>(); openids.add( "ovhq5v9-zshucax_ntcqwip-sbcg" ); openids.add( "ovhq5v6cw3inkwuscl3olodif0cc" ); massmsgresult result_news = wechatmsgservice.sendmpnewstoopenid( "phil_token" , openids, ur.getmedia_id()); logger.debug( " send by openid msg {} " ,result_news.geterrmsg()); // 根据openid列表群发文字消息 massmsgresult result_text = wechatmsgservice.sendtexttoopenid( "phil_token" , openids, "什么是幸福,幸福就是自己的一种愉快的心理状态和感受。时时、事事都能使自己快乐的人才是最幸福的人。最快乐的人,就是最幸福的人。笑口常开的人,是最幸福的" ); logger.debug( " send by openid msg {} " ,result_text.geterrmsg()); return null ; } |
七、部分用到的类和方法
群发方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
|
/** * 根据标签进行群发文本消息 * @param accesstoken 授权token * @param entity 图文消息对象 * @return */ public massmsgresult sendtexttotag(string accesstoken, int tagid, string content){ massmsgresult result = null ; treemap<string, string> params = new treemap<>(); params.put( "access_token" , accesstoken); // post 提交的参数 map<string, object> filterparams = new hashmap<>(); filterparams.put( "is_to_all" , false ); filterparams.put( "tag_id" , tagid); map<string, object> textparams = new hashmap<>(); textparams.put( "content" , content); treemap<string,object> dataparams = new treemap<>(); dataparams.put( "filter" , filterparams); dataparams.put( "text" , textparams); dataparams.put( "msgtype" , "text" ); string data = jsonutil.tojsonstring(dataparams); string json = httprequtil.httpsdefaultexecute(systemconfig.post_method, wechatconfig.send_all_mass_message_url, params, data); try { result = jsonutil.fromjsonstring(json, massmsgresult. class ); } catch (exception e) { e.printstacktrace(); } return result; } /** * 根据标签进行群发图文消息 * @param accesstoken 授权token * @param tagid 标签 * @param mediaid uploadmedia方法获得 * @return */ public massmsgresult sendmpnewstotag(string accesstoken, int tagid, string mediaid){ massmsgresult result = null ; treemap<string, string> params = new treemap<>(); params.put( "access_token" , accesstoken); // post 提交的参数 map<string, object> filterparams = new hashmap<>(); filterparams.put( "is_to_all" , false ); filterparams.put( "tag_id" , tagid); map<string, object> mpnewsparams = new hashmap<>(); mpnewsparams.put( "media_id" , mediaid); treemap<string,object> dataparams = new treemap<>(); dataparams.put( "filter" , filterparams); dataparams.put( "mpnews" , mpnewsparams); dataparams.put( "msgtype" , "mpnews" ); dataparams.put( "send_ignore_reprint" , 0 ); //不能省略 string data = jsonutil.tojsonstring(dataparams); string json = httprequtil.httpsdefaultexecute(systemconfig.post_method, wechatconfig.send_all_mass_message_url, params, data); try { result = jsonutil.fromjsonstring(json, massmsgresult. class ); } catch (exception e) { e.printstacktrace(); } return result; } /** * 根据标签进行群发图片 * @param accesstoken 授权token * @param tagid 标签 * @param mediaid uploadmedia方法获得 * @return */ public massmsgresult sendimagetotag(string accesstoken, int tagid, string mediaid){ massmsgresult result = null ; treemap<string, string> params = new treemap<>(); params.put( "access_token" , accesstoken); // post 提交的参数 map<string, object> filterparams = new hashmap<>(); filterparams.put( "is_to_all" , false ); filterparams.put( "tag_id" , tagid); map<string, object> imageparams = new hashmap<>(); imageparams.put( "media_id" , mediaid); treemap<string,object> dataparams = new treemap<>(); dataparams.put( "filter" , filterparams); dataparams.put( "image" , imageparams); dataparams.put( "msgtype" , "image" ); string data = jsonutil.tojsonstring(dataparams); string json = httprequtil.httpsdefaultexecute(systemconfig.post_method, wechatconfig.send_all_mass_message_url, params, data); try { result = jsonutil.fromjsonstring(json, massmsgresult. class ); } catch (exception e) { e.printstacktrace(); } return result; } /** * 根据标签进行群发语音/音频 * @param accesstoken 授权token * @param tagid 标签 * @param mediaid uploadmedia方法获得 * @return */ public massmsgresult sendvoicetotag(string accesstoken, int tagid, string mediaid){ massmsgresult result = null ; treemap<string, string> params = new treemap<>(); params.put( "access_token" , accesstoken); // post 提交的参数 map<string, object> filterparams = new hashmap<>(); filterparams.put( "is_to_all" , false ); filterparams.put( "tag_id" , tagid); map<string, object> voiceparams = new hashmap<>(); voiceparams.put( "media_id" , mediaid); treemap<string,object> dataparams = new treemap<>(); dataparams.put( "filter" , filterparams); dataparams.put( "voice" , voiceparams); dataparams.put( "msgtype" , "voice" ); string data = jsonutil.tojsonstring(dataparams); string json = httprequtil.httpsdefaultexecute(systemconfig.post_method, wechatconfig.send_all_mass_message_url, params, data); try { result = jsonutil.fromjsonstring(json, massmsgresult. class ); } catch (exception e) { e.printstacktrace(); } return result; } /** * 根据标签进行群发视频 * @param accesstoken 授权token * @param tagid 标签 * @param mediaid uploadmedia方法获得 * @return */ public massmsgresult sendvideototag(string accesstoken, int tagid, string mediaid){ massmsgresult result = null ; treemap<string, string> params = new treemap<>(); params.put( "access_token" , accesstoken); // post 提交的参数 map<string, object> filterparams = new hashmap<>(); filterparams.put( "is_to_all" , false ); filterparams.put( "tag_id" , tagid); map<string, object> mpvideoparams = new hashmap<>(); mpvideoparams.put( "media_id" , mediaid); treemap<string,object> dataparams = new treemap<>(); dataparams.put( "filter" , filterparams); dataparams.put( "mpvideo" , mpvideoparams); dataparams.put( "msgtype" , "mpvideo" ); string data = jsonutil.tojsonstring(dataparams); string json = httprequtil.httpsdefaultexecute(systemconfig.post_method, wechatconfig.send_all_mass_message_url, params, data); try { result = jsonutil.fromjsonstring(json, massmsgresult. class ); } catch (exception e) { e.printstacktrace(); } return result; } /** * 根据标签进行群发卡券 * @param accesstoken 授权token * @param tagid 标签 * @param card_id * @return */ public massmsgresult sendwxcardtotag(string accesstoken, int tagid, string cardid){ massmsgresult result = null ; treemap<string, string> params = new treemap<>(); params.put( "access_token" , accesstoken); // post 提交的参数 map<string, object> filterparams = new hashmap<>(); filterparams.put( "is_to_all" , false ); filterparams.put( "tag_id" , tagid); map<string, object> wxcardparams = new hashmap<>(); wxcardparams.put( "card_id" , cardid); treemap<string,object> dataparams = new treemap<>(); dataparams.put( "filter" , filterparams); dataparams.put( "wxcard" , wxcardparams); dataparams.put( "msgtype" , "wxcard" ); string data = jsonutil.tojsonstring(dataparams); string json = httprequtil.httpsdefaultexecute(systemconfig.post_method, wechatconfig.send_all_mass_message_url, params, data); try { result = jsonutil.fromjsonstring(json, massmsgresult. class ); } catch (exception e) { e.printstacktrace(); } return result; } /** * 根据openid进行群发图文消息 * @param accesstoken 授权token * @param tagid 标签 * @param mediaid uploadmedia方法获得 * @return */ public massmsgresult sendmpnewstoopenid(string accesstoken, list<string> openids, string mediaid){ massmsgresult result = null ; treemap<string, string> params = new treemap<>(); params.put( "access_token" , accesstoken); // post 提交的参数 map<string, object> mpnewsparams = new hashmap<>(); mpnewsparams.put( "media_id" , mediaid); treemap<string,object> dataparams = new treemap<>(); dataparams.put( "touser" , openids); dataparams.put( "mpnews" , mpnewsparams); dataparams.put( "msgtype" , "mpnews" ); dataparams.put( "send_ignore_reprint" , 0 ); string data = jsonutil.tojsonstring(dataparams); string json = httprequtil.httpsdefaultexecute(systemconfig.post_method, wechatconfig.send_mass_message_url, params, data); try { result = jsonutil.fromjsonstring(json, massmsgresult. class ); } catch (exception e) { e.printstacktrace(); } return result; } /** * 根据openid进行群发文本消息 * @param accesstoken 授权token * @param openids openid * @param content * @return */ public massmsgresult sendtexttoopenid(string accesstoken, list<string> openids, string content){ massmsgresult result = null ; treemap<string, string> params = new treemap<>(); params.put( "access_token" , accesstoken); // post 提交的参数 map<string, object> textparams = new hashmap<>(); textparams.put( "content" , content); treemap<string,object> dataparams = new treemap<>(); dataparams.put( "touser" , openids); dataparams.put( "text" , textparams); dataparams.put( "msgtype" , "text" ); string data = jsonutil.tojsonstring(dataparams); system.out.println(data); string json = httprequtil.httpsdefaultexecute(systemconfig.post_method, wechatconfig.send_mass_message_url, params, data); try { result = jsonutil.fromjsonstring(json, massmsgresult. class ); } catch (exception e) { e.printstacktrace(); } return result; } /** * 根据openid进行群发语音消息 * @param accesstoken 授权token * @param openids openid * @param mediaid * @return */ public massmsgresult sendvocietoopenid(string accesstoken, list<string> openids, string mediaid){ massmsgresult result = null ; treemap<string, string> params = new treemap<>(); params.put( "access_token" , accesstoken); // post 提交的参数 map<string, object> voiceparams = new hashmap<>(); voiceparams.put( "media_id" , mediaid); treemap<string,object> dataparams = new treemap<>(); dataparams.put( "touser" , openids); dataparams.put( "voice" , voiceparams); dataparams.put( "msgtype" , "voice" ); string data = jsonutil.tojsonstring(dataparams); system.out.println(data); string json = httprequtil.httpsdefaultexecute(systemconfig.post_method, wechatconfig.send_mass_message_url, params, data); try { result = jsonutil.fromjsonstring(json, massmsgresult. class ); } catch (exception e) { e.printstacktrace(); } return result; } /** * 根据openid进行群发图片消息 * @param accesstoken 授权token * @param openids openid * @param mediaid * @return */ public massmsgresult sendimagetoopenid(string accesstoken, list<string> openids, string mediaid){ massmsgresult result = null ; treemap<string, string> params = new treemap<>(); params.put( "access_token" , accesstoken); // post 提交的参数 map<string, object> imageparams = new hashmap<>(); imageparams.put( "media_id" , mediaid); treemap<string,object> dataparams = new treemap<>(); dataparams.put( "touser" , openids); dataparams.put( "image" , imageparams); dataparams.put( "msgtype" , "image" ); string data = jsonutil.tojsonstring(dataparams); system.out.println(data); string json = httprequtil.httpsdefaultexecute(systemconfig.post_method, wechatconfig.send_mass_message_url, params, data); try { result = jsonutil.fromjsonstring(json, massmsgresult. class ); } catch (exception e) { e.printstacktrace(); } return result; } /** * 根据openid进行群发视频消息 * @param accesstoken 授权token * @param openids openid * @param mpvideomedia uploadmediavideo方法获得media * @return */ public massmsgresult sendvideotoopenid(string accesstoken, list<string> openids, mpvideomedia mpvideomedia){ massmsgresult result = null ; treemap<string, string> params = new treemap<>(); params.put( "access_token" , accesstoken); // post 提交的参数 treemap<string,object> dataparams = new treemap<>(); dataparams.put( "touser" , openids); dataparams.put( "mpvideo" , mpvideomedia); dataparams.put( "msgtype" , "mpvideo" ); string data = jsonutil.tojsonstring(dataparams); system.out.println(data); string json = httprequtil.httpsdefaultexecute(systemconfig.post_method, wechatconfig.send_mass_message_url, params, data); try { result = jsonutil.fromjsonstring(json, massmsgresult. class ); } catch (exception e) { e.printstacktrace(); } return result; } /** * 根据openid进行群发卡券消息 * @param accesstoken 授权token * @param openids openid * @param mediaid * @return */ public massmsgresult sendwxcardtoopenid(string accesstoken, list<string> openids, string cardid){ massmsgresult result = null ; treemap<string, string> params = new treemap<>(); params.put( "access_token" , accesstoken); // post 提交的参数 map<string, object> wxcardparams = new hashmap<>(); wxcardparams.put( "card_id" , cardid); treemap<string,object> dataparams = new treemap<>(); dataparams.put( "touser" , openids); dataparams.put( "wxcard" , wxcardparams); dataparams.put( "msgtype" , "wxcard" ); string data = jsonutil.tojsonstring(dataparams); string json = httprequtil.httpsdefaultexecute(systemconfig.post_method, wechatconfig.send_mass_message_url, params, data); try { result = jsonutil.fromjsonstring(json, massmsgresult. class ); } catch (exception e) { e.printstacktrace(); } return result; } |
视频post数据bean
1
2
3
4
5
6
7
8
9
10
11
|
/** * 视频post数据bean * @author phil * @date 2017年9月20日 * */ public class mpvideomedia { private string media_id; private string title; private string description; } |
获取群发视频post中的media_id
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
/** * 获取群发视频post中的media_id * * @param accesstoken * @param uploadvideo * @return */ public static uploadmediasresult uploadmediavideo(string accesstoken, mpvideomedia mpvideomedia) { uploadmediasresult result = null ; treemap<string, string> params = new treemap<string, string>(); params.put( "access_token" , accesstoken); // post 提交的参数 string data = jsonutil.tojsonstring(mpvideomedia); string json = httprequtil.httpsdefaultexecute(systemconfig.post_method, wechatconfig.upload_video_media_url, params, data); result = jsonutil.fromjsonstring(json, uploadmediasresult. class ); return result; } |
群发返回的结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
package com.phil.wechat.msg.model.resp; import com.phil.wechat.base.result.resultstate; /** * 群发消息返回的结果 * 根据openid列表群发 * @author phil * @date 2017年7月2日 * */ public class massmsgresult extends resultstate{ private string type; //媒体文件类型,分别有图片(image)、语音(voice)、视频(video)和缩略图(thumb),次数为news,即图文消息 private string msg_id; private string msg_data_id; } |
配置类
1
2
3
4
5
6
7
8
|
// 按分组进行群发 public static final string send_all_mass_message_url = "https://api.weixin.qq.com/cgi-bin/message/mass/sendall" ; // 按照openid进行群发消息(openid最少2个,最多10000个 10000个) public static final string send_mass_message_url = "https://api.weixin.qq.com/cgi-bin/message/mass/send" ; //上传图文消息素材 public static final string upload_news_media_url = "https://api.weixin.qq.com/cgi-bin/media/uploadnews" ; //获取群发视频post中的media_id public static final string upload_video_media_url = " https://api.weixin.qq.com/cgi-bin/media/uploadvideo" ; |
关于源码,希望帮到了你
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/phil_jing/article/details/78764879