文章目录
前言
需求说明:微信公众号需要对特定的关注用户群发图文消息。
根据自己的业务需求来选择群发方式标签或者openid选择对应的接口地址
发送内容也根据自己业务需求来拼装参数
下面是根据用户openId推送图片内容。
一、上传图片到微信服务器
1.新增素材获取media_id(参考文档)
链接: https://developers.weixin.qq.com/doc/offiaccount/Asset_Management/New_temporary_materials.html
2.代码
/**
* 上传本地文件到微信获取mediaId
*/
public static JsonResult upload(String accessToken, String type) throws IOException {
String filePath = "文件绝对路径"
File file = new File(filePath);
StringBuffer buffer = new StringBuffer();
BufferedReader reader = null;
String result = null;
HttpURLConnection con;
if (!file.exists() || !file.isFile()) {
return JsonResult.fail(ServiceCode.ERROR_SERVICE,"未查询到文件");
}
try {//accessToken的获取不做具体描述了,type为image
String url = "https://api.weixin.qq.com/cgi-bin/media/upload?access_token=" + accessToken + "&type=" + type;
URL urlObj = new URL(url);
//连接
con = (HttpURLConnection) urlObj.openConnection();
con.setRequestMethod("POST");
con.setDoInput(true);
con.setDoOutput(true);
con.setUseCaches(false);
//设置请求头信息
con.setRequestProperty("Connection", "Keep-Alive");
con.setRequestProperty("Charset", "UTF-8");
//设置边界
String BOUNDARY = "----------" + System.currentTimeMillis();
con.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
StringBuilder sb = new StringBuilder();
sb.append("--");
sb.append(BOUNDARY);
sb.append("\r\n");
sb.append("Content-Disposition: form-data;name=\"file\";filename=\"" + file.getName() + "\"\r\n");
sb.append("Content-Type:application/octet-stream\r\n\r\n");
byte[] head = sb.toString().getBytes("utf-8");
//获得输出流
OutputStream out = new DataOutputStream(con.getOutputStream());
//输出表头
out.write(head);
//文件正文部分
//把文件已流文件的方式 推入到url中
DataInputStream in = new DataInputStream(new FileInputStream(file));
int bytes = 0;
byte[] bufferOut = new byte[1024];
while ((bytes = in.read(bufferOut)) != -1) {
out.write(bufferOut, 0, bytes);
}
in.close();
//结尾部分
byte[] foot = ("\r\n--" + BOUNDARY + "--\r\n").getBytes("utf-8");//定义最后数据分隔线
out.write(foot);
out.flush();
out.close();
//定义BufferedReader输入流来读取URL的响应
reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
if (result == null) {
result = buffer.toString();
}
} catch (Exception e) {
logger.error("上传本地文件到微信异常e:===>",e);
return JsonResult.fail(ServiceCode.ERROR_SERVICE,"上传本地文件到微信异常");
} finally {
if (reader != null) {
reader.close();
}
}
com.alibaba.fastjson.JSONObject jsonObj = com.alibaba.fastjson.JSONObject.parseObject(result);
System.out.println(jsonObj);
String typeName = "media_id";
if (!"image".equals(type)) {
typeName = type + "_media_id";
}
String mediaId = jsonObj.getString(typeName);
return JsonResult.ok(mediaId);
}
二、根据OpenID列表群发【订阅号不可用,服务号认证后可用】
1.接口地址
http请求方式: POST https://api.weixin.qq.com/cgi-bin/message/mass/send?access_token=ACCESS_TOKEN
代码如下(示例):
/**推送
* @Description:
* @Param: [xm]
* @return: JsonResult
*/
@Override
public JsonResult mytest(String xm) {
Map<String,Object> resultMap = new HashMap<>();
List<String> mediaIdList = new LinkedList<>();
//获取token,使用自己的业务逻辑获取即可
String token = TokenUtil.getToken(userCacheRepository, appId, appSecret);
//获取的mediaId
String mediaId = null;
try {
JsonResult result = upload(token, "image");
if(200 != result.getCode()){
return result;
}
mediaId = result.getData().toString();
logger.info("mediaId:===>【{}】",mediaId);
mediaIdList.add(mediaId);
} catch (IOException e) {
throw new RuntimeException(e);
}
List<String> openIdList = new LinkedList<>();
//业务逻辑查询openId(多个),群发接口至少发送两个用户
String openId1 = "";
String openId3 = "";
openIdList.add(openId1);
openIdList.add(openId3);
JsonResult result = sendPicOrVoiceMessageToUser(mediaIdList, openIdList, "image", token);
Integer code = result.getCode();
String message = result.getMessage();
Map<String,Object> map = new HashMap<>();
map.put("message" , message);
map.put("code",code);
resultMap.put("sendCount"+(1),map);
return JsonResult.ok(resultMap);
}
public static JsonResult sendPicOrVoiceMessageToUser(List<String> mediaId, List<String> toUser, String msgType, String accessToken) {
String json = null;
if (msgType.equals("image")) {
json = MessageUtil.PushMessage(toUser,mediaId,null);
}
//此接口为根据OpenID列表群发接口,具体根据自己的需求选择是使用标签还是openid
String action = "https://api.weixin.qq.com/cgi-bin/message/mass/send?access_token=" + accessToken;
logger.info("发送地址:===>【{}】",action);
JsonResult result = new JsonResult();
try {
logger.info("sendJson:===>【{}】",json);
result = connectWeiXinInterface(action, json);
} catch (Exception e) {
e.printStackTrace();
}
finally {
return result;
}
}
/**
* 连接请求微信后台接口
* @param action 接口url
* @param json 请求接口传送的json字符串
*/
public static JsonResult connectWeiXinInterface(String action, String json) {
URL url;
JsonResult jsonResult = new JsonResult();
try {
url = new URL(action);
HttpURLConnection http = (HttpURLConnection) url.openConnection();
http.setRequestMethod("POST");
http.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
http.setDoOutput(true);
http.setDoInput(true);
System.setProperty("sun.net.client.defaultConnectTimeout", "30000");// 连接超时30秒
System.setProperty("sun.net.client.defaultReadTimeout", "30000"); // 读取超时30秒
http.connect();
OutputStream os = http.getOutputStream();
os.write(json.getBytes("UTF-8"));// 传入参数
InputStream is = http.getInputStream();
int size = is.available();
byte[] jsonBytes = new byte[size];
is.read(jsonBytes);
String result = new String(jsonBytes, "UTF-8");
JSONObject jsonObject = JSONObject.parseObject(result);
logger.info("发送图文返回结果:【{}】",jsonObject);
Object msg = jsonObject.get("errmsg");
Object errcode = jsonObject.get("errcode");
jsonResult.setCode(Integer.valueOf(String.valueOf(errcode)));
jsonResult.setMessage(String.valueOf(msg));
os.flush();
os.close();
} catch (Exception e) {
e.printStackTrace();
}
finally {
return jsonResult;
}
}
三、相关问题以及限制
1.问题
1.使用测试号进行群送时微信返回48001,说是没有api功能授权,但是打开测试号接口授权是有的。单独发送又成功,上到正式环境就没有此问题,不知道啥原因。
群发参数
{
"touser":[
"OPENID1",
"OPENID2"
],
"images": {
"media_ids": [
"aaa",
"bbb",
"ccc"
],
"recommend": "xxx",
"need_open_comment": 1,
"only_fans_can_comment": 0
},
"msgtype":"image"
}
单发参数 需要改变接口请求地址,在代码中有注释
{
"touser": "toUser",
"msgtype": "image",
"image": {
"media_id": "mediaId"
}
}
2.限制
总结
以上就是今天要讲的内容,根据自己是发送图文、视频、音频、图片来组装对应的参数就行。
参考文档链接: https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Batch_Sends_and_Originality_Checks.html