在公众平台网站上,订阅号可每天群发一条消息,服务号提供每月(自然月)4条的群发权限。对于某些具备开发能力的公众号运营者,可以通过高级群发接口,实现更灵活的群发能力。该高级群发接口只对认证的订阅号、认证服务号有效。
群发图文消息的过程如下:
1)将图文消息中需要的图片,使用上传图片接口上传,获得URL
2)上传图文消息素材,需要用到图片时,使用上一步获取的图片URL
3)使用对用户分组的群发,或对OpenID列表的群发,默认可进行全部发送,将图文消息群发出去
下面就开始我们的编程历程
1、上传图文消息需要的图片资源获取URL
图片仅支持jpg/png格式,大小必须在1MB以下
请求接口:https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token=ACCESS_TOKEN
当然使用上面接口之前先要获得access_token
代码如下:
/**
* 根据appID,appsecret获取accessToken
* @param appID
* @param secret
* @return
* @throws Exception
*/
public static String getAccessToken(String appID, String appSecret) throws Exception{
String accessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appID+"&secret="+appSecret+"";
//获取accessToken
String accessTokenStr = accessTokenRequest(accessTokenUrl);
JSONObject json = new JSONObject(accessTokenStr);
return json.getString("access_token");
}
/**
* 根据URL路径,获取服务器返回的字符串
*/
public static String accessTokenRequest(String urlStr)throws Exception{
HttpURLConnection connection=null;
String tempStr = null;
try{
URL url=new URL(urlStr);
StringBuffer bankXmlBuffer=new StringBuffer();
//创建URL连接,提交到数据,获取返回结果
connection=(HttpURLConnection)url.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(true);
connection.setRequestProperty("User-Agent","directclient");
PrintWriter out=new PrintWriter(new OutputStreamWriter(connection.getOutputStream(),"GBK"));
out.println();
out.close();
BufferedReader in=new BufferedReader(new InputStreamReader(connection
.getInputStream(),"UTF-8"));
String inputLine;
while((inputLine = in.readLine())!=null){
bankXmlBuffer.append(inputLine);
}
in.close();
tempStr = bankXmlBuffer.toString();
}
catch(Exception e)
{
System.out.println("发送GET请求出现异常!"+e);
e.printStackTrace();
}finally{
if(connection!=null)
connection.disconnect();
}
return tempStr;
}
使用上传图片接口上传代码如下,返回值及图片URL:
/**
* 模拟form表单的形式 ,上传文件 以输出流的形式把文件写入到url中,然后用输入流来获取url的响应
*
* @param url 请求地址 form表单url地址
* @param filePath 文件在服务器保存路径
* @return String url的响应信息返回值
* @throws IOException
*/
public static String fileUpload(String accessToken, String filePath) throws IOException {
String result = null;
File file = new File(filePath);
if (!file.exists() || !file.isFile()) {
throw new IOException("文件不存在");
}
//第一部分
String url = "http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token="+ accessToken +"&type=image";
URL urlObj = new URL(url);
HttpURLConnection con = (HttpURLConnection) urlObj.openConnection();
//设置关键值
con.setRequestMethod("POST"); // 以Post方式提交表单,默认get方式
con.setDoInput(true);
con.setDoOutput(true);
con.setUseCaches(false); // post方式不能使用缓存
// 设置请求头信息
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();
StringBuffer buffer = new StringBuffer();
BufferedReader reader = null;
try {
// 定义BufferedReader输入流来读取URL的响应
reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null) {
//System.out.println(line);
buffer.append(line);
}
if(result==null){
result = buffer.toString();
}
} catch (IOException e) {
System.out.println("发送POST请求出现异常!" + e);
e.printStackTrace();
throw new IOException("数据读取异常");
} finally {
if(reader!=null){
reader.close();
}
}
JSONObject jsonObj = new JSONObject(result);
//System.out.println(jsonObj);
String mediaId = jsonObj.getString("media_id");
//String mediaId = jsonObj.getString("url");
return mediaId;
}
2、上传图文消息素材
http请求方式:POST
请求接口:https://api.weixin.qq.com/cgi-bin/media/uploadnews?access_token=ACCESS_TOKEN
图文消息格式详见:官方文档
上传代码:
/**
* 上传图文消息素材,获取"media_id;或用于群发消息"
* @param access_token
* @param data
* @param type为:"uploadFodderUrl"(上传图文消息)或"sendMessageUrl"(群发消息)或"delMessageUrl"(删除消息,但消息卡片无法删除)
* @return
*/
@SuppressWarnings({ "deprecation", "finally" })
public static String jsonInfoUpload(String access_token, String data, String type){
org.apache.commons.httpclient.HttpClient client = new org.apache.commons.httpclient.HttpClient();
//String posturl = String.format("%s?access_token=%s", uploadurl,access_token);
String uploadurl = null;
String para = null;
if ("uploadFodderUrl".equals(type)){
uploadurl = "https://api.weixin.qq.com/cgi-bin/media/uploadnews?access_token=" + access_token;
para = "media_id";
}else if("sendMessageUrl".equals(type)){
uploadurl = "https://api.weixin.qq.com/cgi-bin/message/mass/sendall?access_token=" + access_token;
para = "errmsg";
}else if("delMessageUrl".equals(type)){
uploadurl = "https://api.weixin.qq.com/cgi-bin/message/mass/delete?access_token=" + access_token;
para = "errmsg";
}
PostMethod post = new PostMethod(uploadurl);
post.setRequestHeader(
"User-Agent",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:30.0) Gecko/20100101 Firefox/30.0");
post.setRequestHeader("Host", "file.api.weixin.qq.com");
post.setRequestHeader("Connection", "Keep-Alive");
post.setRequestHeader("Cache-Control", "no-cache");
post.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "UTF-8");
String receiveInfo = null;
try {
post.setRequestBody(data);
int status = client.executeMethod(post);
if (status == HttpStatus.SC_OK) {
String responseContent = post.getResponseBodyAsString();
JSONObject jsonobj = new JSONObject(responseContent);
System.out.println(jsonobj.toString());
// 正确 { "type":"news",
// "media_id":"CsEf3ldqkAYJAU6EJeIkStVDSvffUJ54vqbThMgplD-VJXXof6ctX5fI6-aYyUiQ","created_at":1391857799}
receiveInfo = jsonobj.getString(para);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
return receiveInfo;
}
}
3、如此万事具备,只欠东风,就是编辑编辑发送的数据信息,详细格式参考官方文档
http请求方式:POST
请求链接:https://api.weixin.qq.com/cgi-bin/message/mass/sendall?access_token=ACCESS_TOKEN
4、如果发现群发消息有误可调用接口将其删除,但只删除详细内容,图文消息的标签不能删除,慎重发送。
http请求方式:POST
请求链接:https://api.weixin.qq.com/cgi-bin/message/mass/delete?access_token=ACCESS_TOKEN
第2、3、4步都是发送JSON格式的信息,故将三部分的函数写在一起,具体操作在参数里区分。
如此微信图文消息的群发工作就做完了,谢谢阅读。