上一篇我们讲述了《微信公众号开发之根据标签进行群发(十二)》,这次我们讲解一下【根据OpenID列表群发】
根据OpenID列表群发【订阅号不可用,服务号认证后可用】
接口调用请求说明
http请求方式: POST https://api.weixin.qq.com/cgi-bin/message/mass/send?access_token=ACCESS_TOKEN
POST数据说明
POST数据示例如下:
图文消息(注意图文消息的media_id需要通过上述方法来得到):
文本:
语音:
图片:
视频:
请注意,此处视频的media_id需通过POST请求到下述接口特别地得到: https://api.weixin.qq.com/cgi-bin/media/uploadvideo?access_token=ACCESS_TOKEN POST数据如下(此处media_id需通过素材管理->新增素材来得到):
返回将为
然后,POST下述数据(将media_id改为上一步中得到的media_id),即可进行发送
卡券:
参数 | 是否必须 | 说明 |
---|---|---|
touser | 是 | 填写图文消息的接收者,一串OpenID列表,OpenID最少2个,最多10000个 |
mpnews | 是 | 用于设定即将发送的图文消息 |
media_id | 是 | 用于群发的图文消息的media_id |
msgtype | 是 | 群发的消息类型,图文消息为mpnews,文本消息为text,语音为voice,音乐为music,图片为image,视频为video,卡券为wxcard |
title | 否 | 消息的标题 |
description | 否 | 消息的描述 |
thumb_media_id | 是 | 视频缩略图的媒体ID |
send_ignore_reprint | 是 | 图文消息被判定为转载时,是否继续群发。 1为继续群发(转载),0为停止群发。 该参数默认为0。 |
返回说明
返回数据示例(正确时的JSON返回结果):
参数 | 说明 |
---|---|
type | 媒体文件类型,分别有图片(image)、语音(voice)、视频(video)和缩略图(thumb),次数为news,即图文消息 |
errcode | 错误码 |
errmsg | 错误信息 |
msg_id | 消息发送任务的ID |
msg_data_id | 消息的数据ID,,该字段只有在群发图文消息时,才会出现。可以用于在图文分析数据接口中,获取到对应的图文消息的数据,是图文分析数据接口中的msgid字段中的前半部分,详见图文分析数据接口中的msgid字段的介绍。 |
请注意:在返回成功时,意味着群发任务提交成功,并不意味着此时群发已经结束,所以,仍有可能在后续的发送过程中出现异常情况导致用户未收到消息,如消息有时会进行审核、服务器不稳定等。此外,群发任务一般需要较长的时间才能全部发送完毕,请耐心等待。
错误时微信会返回错误码等信息,请根据错误码查询错误信息
一、在SendUtil中添加发送的字符串和发送接口两个方法
package com.xu.wemall.components.weixin;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xu.wemall.commons.constants.URIConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import java.util.List;
/**
* 功能:群发工具类
*/
@Slf4j
@Component
public class SendUtil {
@Autowired
private RestTemplate restTemplate;
@Autowired
private AccessTokenUtil accessTokenUtil;
private String createSendAllString(boolean isToAll, String tagId, String mediaId, String msgtype){
JSONObject data = new JSONObject();
JSONObject filter = new JSONObject();
filter.put("is_to_all",isToAll);
if(tagId != null){
filter.put("tag_id",tagId);
}
JSONObject type = new JSONObject();
if(mediaId != null){
type.put("media_id",mediaId);
}
data.put("filter",filter);
//图文消息
if(msgtype.equalsIgnoreCase("mpnews")){
data.put("mpnews",type);
data.put("send_ignore_reprint",1);
}else if(msgtype.equalsIgnoreCase("text")){
data.put("text",type); //文本
}else if(msgtype.equalsIgnoreCase("voice")){
data.put("voice",type); //声音
}else if(msgtype.equalsIgnoreCase("image")){
data.put("image",type); //图片
}else if(msgtype.equalsIgnoreCase("mpvideo")){
data.put("mpvideo",type); //声音
}else if(msgtype.equalsIgnoreCase("wxcard")) {
data.put("wxcard", type); //卡券
}
if(msgtype !=null){
data.put("msgtype",msgtype);
}
return data.toJSONString();
}
private String createSendString(List<String> openIdList, String mediaId, String msgtype){
JSONObject data = new JSONObject();
JSONArray touser = new JSONArray();
touser.addAll(openIdList);
data.put("touser",touser);
JSONObject type = new JSONObject();
if(mediaId != null){
type.put("media_id",mediaId);
}
//图文消息
if(msgtype.equalsIgnoreCase("mpnews")){
data.put("mpnews",type);
data.put("send_ignore_reprint",1);
}else if(msgtype.equalsIgnoreCase("text")){
data.put("text",type); //文本
}else if(msgtype.equalsIgnoreCase("voice")){
data.put("voice",type); //声音
}else if(msgtype.equalsIgnoreCase("image")){
data.put("image",type); //图片
}else if(msgtype.equalsIgnoreCase("mpvideo")){
data.put("mpvideo",type); //声音
}else if(msgtype.equalsIgnoreCase("wxcard")) {
data.put("wxcard", type); //卡券
}
if(msgtype !=null){
data.put("msgtype",msgtype);
}
return data.toJSONString();
}
/**
*根据标签进行群发
*/
public String sendByTagId(boolean isToAll, String tagId, String mediaId, String msgtype) {
String accessToken = accessTokenUtil.getAccessToken();
if (accessToken != null) {
log.info("URL{}", URIConstant.SEND_ALL_URL);
String url = URIConstant.SEND_ALL_URL.replace("ACCESS_TOKEN", accessToken);
log.info("SEND_ALL_URL:{}", url);
//将菜单对象转换成JSON字符串
String dataString = this.createSendAllString(isToAll, tagId, mediaId, msgtype);
log.info("dataString:{}",dataString);
//发起POST请求创建菜单
String jsonObject = restTemplate.postForObject(url, dataString,String.class);
return jsonObject;
}
return null;
}
/**
*根据OpenID列表群发
*/
public String sendByOpenId(List<String> touser, String mediaId, String msgtype) {
String accessToken = accessTokenUtil.getAccessToken();
if (accessToken != null) {
log.info("URL{}", URIConstant.SEND_URL);
String url = URIConstant.SEND_URL.replace("ACCESS_TOKEN", accessToken);
log.info("SEND_URL:{}", url);
//将菜单对象转换成JSON字符串
String dataString = this.createSendString(touser, mediaId, msgtype);
log.info("dataString:{}",dataString);
//发起POST请求创建菜单
String jsonObject = restTemplate.postForObject(url, dataString,String.class);
return jsonObject;
}
return null;
}
}
二、在SendController中添加swagger方法
三,测试
我们需要先通过获取关注公众号的用户获得至少两个openid,然后测试如下
结果(泪奔中……)结果又是没有权限,因为我们用的是测试账号,测试账号现在已经没有群发功能权限了
查询微信公众号开发文档中的【全局返回码说明】确认的确是没有这个接口的权限,哎
如果您觉得此文有帮助,可以小小打赏一下,持续更新更有动力哟!
谢谢观看,下回我们继续不见不散!