- 首先,预先将图文消息中需要用到的图片,使用上传图文消息内图片接口,上传成功并获得图片 URL;
- 上传图文消息素材,需要用到图片时,请使用上一步获取的图片 URL;
- 使用对用户标签的群发,或对 OpenID 列表的群发,将图文消息群发出去,群发时微信会进行原创校验,并返回群发操作结果;
这是根据OpenID列表群发的步骤。废话不多说,这直接上干活。
/*** 推送消息
* @Author FM_南风
* @Date 2024/5/21 15:05
**/
@Override
public JsonResult pushMessage(String filePath) {
logger.info("发送图片本地地址:===>【{}】",filePath);
Map<String,Object> resultMap = new HashMap<>();
List<String> mediaIdList = new LinkedList<>();
String token = "token";//自己的token获取逻辑
String mediaId = null;
try {
//上传至微信服务器,获取media_id
JsonResult result = HttpUtil.upload(filePath, 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);
}
Integer regCount = messageMapper.selectRegCount();
logger.info("绑定总人数:===>【{}】",regCount );
int i = regCount/8000;
//群发限制一次调用一次最多发送10000万个用户,此处使用8000,给自己留点空间
i += 1;
for (int j = 0; j < i; j++) {
List<String> openIdList = mapper.selectOpenIdList(j*8000,8000);//SQL
String json = MessageUtil.PushMessage(mediaIdList,openIdList,null);
String sendUrl = "https://api.weixin.qq.com/cgi-bin/message/mass/send?access_token=" + token;//增加自己的获取token逻辑
JsonResult result = HttpUtil.sendMessage(sendUrl, json);
logger.info("发送结果:[{}]",result);
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"+(j+1),map);
logger.info("循环结束");
}
return JsonResult.ok(resultMap);
}
此处是几个封装的工具类:
HttpUtil.upload与HttpUtil.sendMessage
public class HttpUtil {
/**
* 上传本地文件到微信获取mediaId
*/
public static JsonResult upload(String filePath, String accessToken, String type) throws IOException {
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 {
// String url = ConfigUtil.UPLOAD_URL.replace("ACCESS_TOKEN", accessToken).replace("TYPE",type);
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);
logger.info("上传返回结果:===>【{}】",jsonObj);
String typeName = "media_id";
if (!"image".equals(type)) {
typeName = type + "_media_id";
}
String mediaId = jsonObj.getString(typeName);
return JsonResult.ok(mediaId);
}
/**
* 连接请求微信后台发送消息
*/
public static JsonResult sendMessage(String sendUrl, String json) {
URL url;
JsonResult jsonResult = new JsonResult();
try {
url = new URL(sendUrl);
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) {
logger.error("发送失败:",e);
return JsonResult.fail(ServiceCode.ERROR_SERVICE,"发送失败");
}
return jsonResult;
}
}
还有一个拼装json的工具类:MessageUtil.PushMessage,需要将数据拼装成微信三方要求的格式
public class MessageUtil {
public static String PushMessage(List<String> openIdList ,List<String> mediaIdList,String title){
Map <String,Object> map = new HashMap<>();
Map <String,Object> map2 = new HashMap<>();
map2.put("media_ids",mediaIdList);
map2.put("need_open_comment",1);
map2.put("only_fans_can_comment",0);
if(title != null){
map2.put("recommend",title);
}
map.put("touser",openIdList);
map.put("images", map2);
map.put("msgtype" ,"image");
return JSONObject.toJSONString(map);
}
}
以上就是全部代码干货,最后是结果: