java微信公众号开发(一)《基础配置对接部分(4)》:回复用户消息
回复用户消息
在接收到微信用户的各类消息之后,我们根据实际业务需要进行处理之后,需要回复消息给微信用户。
回复消息我们在MessageManage类中进行统一处理:
/*
*向用户发送消息的管理类
*/
/**
* (一)被动回复用户消息
* 当用户发送消息给公众号时(或某些特定的用户操作引发的事件推送时),会产生一个POST请求,开发者可以在响应包(Get)中返回特定XML结构,
* 来对该消息进行响应(现支持回复文本、图片、图文、语音、视频、音乐)。严格来说,发送被动响应消息其实并不是一种接口,而是对微信服务器发过来消息的一次回复。
* 微信服务器在将用户的消息发给公众号的开发者服务器地址(开发者中心处配置)后,微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次,
* 如果在调试中,发现用户无法收到响应的消息,可以检查是否消息处理超时。关于重试的消息排重,有msgid的消息推荐使用msgid排重。
* 事件类型消息推荐使用FromUserName + CreateTime 排重。
* 如果开发者希望增强安全性,可以在开发者中心处开启消息加密,这样,用户发给公众号的消息以及公众号被动回复用户消息都会继续加密,详见被动回复消息加解密说明。
* 假如服务器无法保证在五秒内处理并回复,必须做出下述回复,这样微信服务器才不会对此作任何处理,并且不会发起重试(这种情况下,可以使用客服消息接口进行异步回复),
* 否则,将出现严重的错误提示。详见下面说明:
* 1、直接回复success(推荐方式) 2、直接回复空串(指字节长度为0的空字符串,而不是XML结构体中content字段的内容为空)
* 一旦遇到以下情况,微信都会在公众号会话中,向用户下发系统提示“该公众号暂时无法提供服务,请稍后再试”:
* 1、开发者在5秒内未回复任何内容 2、开发者回复了异常数据,比如JSON数据等
* 另外,请注意,回复图片(不支持gif动图)等多媒体消息时需要预先通过素材管理接口上传临时素材到微信服务器,可以使用素材管理中的临时素材,也可以使用永久素材。
* 各消息类型需要的XML数据包结构如下:
* 目录
* 1 回复文本消息
* 2 回复图片消息
* 3 回复语音消息
* 4 回复视频消息
* 5 回复音乐消息
* 6 回复图文消息
*
* (二)主动发送用户模板消息
* 模板消息
* 说明:服务号订阅通知功能开启灰度测试,模板消息能力可正常使用
* 模板消息仅用于公众号向用户发送重要的服务通知,只能用于符合其要求的服务场景中,如信用卡刷卡通知,商品购买成功通知等。
* 不支持广告等营销类消息以及其它所有可能对用户造成骚扰的消息。
* 关于使用规则,请注意:
* 所有服务号都可以在功能->添加功能插件处看到申请模板消息功能的入口,但只有认证后的服务号才可以申请模板消息的使用权限并获得该权限;
* 需要选择公众账号服务所处的2个行业,每月可更改1次所选行业;
* 在所选择行业的模板库中选用已有的模板进行调用;
* 每个账号可以同时使用25个模板。
* 当前每个账号的模板消息的日调用上限为10万次,单个模板没有特殊限制。
* 【2014年11月18日将接口调用频率从默认的日1万次提升为日10万次,可在MP登录后的开发者中心查看】。
* 当账号粉丝数超过10W/100W/1000W时,模板消息的日调用上限会相应提升,以公众号MP后台开发者中心页面中标明的数字为准。
* 关于接口文档,请注意:
* 模板消息调用时主要需要模板ID和模板中各参数的赋值内容;
* 模板中参数内容必须以".DATA"结尾,否则视为保留字;
* 模板保留符号""。
*/
public class MessageManage {
}
回复文本消息
/**
*回复文本消息
* <xml>
* <ToUserName><![CDATA[toUser]]></ToUserName>
* <FromUserName><![CDATA[fromUser]]></FromUserName>
* <CreateTime>12345678</CreateTime>
* <MsgType><![CDATA[text]]></MsgType>
* <Content><![CDATA[你好]]></Content>
* </xml>
* 参数 是否必须 描述
* ToUserName 是 接收方账号(收到的OpenID)
* FromUserName 是 开发者微信号
* CreateTime 是 消息创建时间 (整型)
* MsgType 是 消息类型,文本为text
* Content 是 回复的消息内容(换行:在content中能够换行,微信客户端就支持换行显示)
* @param mapRequest 接收到的用户请求消息
* @param text 文本内容 根据文本内容来进行逻辑处理,以此配置返回文本消息的内容
* @return
*/
public static BaseMessage returnText(Map<String, String> mapRequest, String text) {
return MessageUtils.returnText(mapRequest,text);
}
回复图文消息
/**
* 回复图文消息
* <xml>
* <ToUserName><![CDATA[toUser]]></ToUserName>
* <FromUserName><![CDATA[fromUser]]></FromUserName>
* <CreateTime>12345678</CreateTime>
* <MsgType><![CDATA[news]]></MsgType>
* <ArticleCount>1</ArticleCount>
* <Articles>
* <item>
* <Title><![CDATA[title1]]></Title>
* <Description><![CDATA[description1]]></Description>
* <PicUrl><![CDATA[picurl]]></PicUrl>
* <Url><![CDATA[url]]></Url>
* </item>
* </Articles>
* </xml>
* 参数 是否必须 说明
* ToUserName 是 接收方账号(收到的OpenID)
* FromUserName 是 开发者微信号
* CreateTime 是 消息创建时间 (整型)
* MsgType 是 消息类型,图文为news
* ArticleCount 是 图文消息个数;当用户发送文本、图片、语音、视频、图文、地理位置这六种消息时,开发者只能回复1条图文消息;其余场景最多可回复8条图文消息
* Articles 是 图文消息信息,注意,如果图文数超过限制,则将只发限制内的条数
* Title 是 图文消息标题
* Description 是 图文消息描述
* PicUrl 是 图片链接,支持JPG、PNG格式,较好的效果为大图360*200,小图200*200
* Url 是 点击图文消息跳转链接
* @param mapRequest 接收到的用户请求消息
* @param text 文本内容 根据文本内容来进行逻辑处理,以此配置返回图文消息的内容
* @return
*/
public static BaseMessage returnNews(Map<String, String> mapRequest, String text) {
//实际应用中应根据业务需求来设置需要返回的图文信息
List<Article> articles = new ArrayList<>();
String title="图文标题";
String description="图文说明";
String picUrl="http://www.gainetbd.cn/gainet-data/images/bigdatamap.png";
String url="http://www.gainetbd.cn/gainet-data/index.html";
Article article =new Article(title,description,picUrl,url);
articles.add(article);
return MessageUtils.returnNews(mapRequest,articles);
}
回复音乐消息
/**
* 回复音乐消息
* <xml>
* <ToUserName><![CDATA[toUser]]></ToUserName>
* <FromUserName><![CDATA[fromUser]]></FromUserName>
* <CreateTime>12345678</CreateTime>
* <MsgType><![CDATA[music]]></MsgType>
* <Music>
* <Title><![CDATA[TITLE]]></Title>
* <Description><![CDATA[DESCRIPTION]]></Description>
* <MusicUrl><![CDATA[MUSIC_Url]]></MusicUrl>
* <HQMusicUrl><![CDATA[HQ_MUSIC_Url]]></HQMusicUrl>
* <ThumbMediaId><![CDATA[media_id]]></ThumbMediaId>
* </Music>
* </xml>
* 参数 是否必须 说明
* ToUserName 是 接收方账号(收到的OpenID)
* FromUserName 是 开发者微信号
* CreateTime 是 消息创建时间 (整型)
* MsgType 是 消息类型,音乐为music
* Title 否 音乐标题
* Description 否 音乐描述
* MusicURL 否 音乐链接
* HQMusicUrl 否 高质量音乐链接,WIFI环境优先使用该链接播放音乐
* ThumbMediaId 是 缩略图的媒体id,通过素材管理中的接口上传多媒体文件,得到的id
* @param mapRequest
* @param text
* @return
*/
public static BaseMessage returnMusic(Map<String, String> mapRequest, String text) {
//实际应用中应根据业务需求来设置需要返回的音乐信息
String title="";
String description="";
String musicURL="";
String hQMusicUrl="";
String thumbMediaId="";
Music music =new Music(title,description,musicURL,hQMusicUrl,thumbMediaId);
return MessageUtils.returnMusic(mapRequest,music);
}
回复视频消息
/**
* 回复视频消息
* <xml>
* <ToUserName><![CDATA[toUser]]></ToUserName>
* <FromUserName><![CDATA[fromUser]]></FromUserName>
* <CreateTime>12345678</CreateTime>
* <MsgType><![CDATA[video]]></MsgType>
* <Video>
* <MediaId><![CDATA[media_id]]></MediaId>
* <Title><![CDATA[title]]></Title>
* <Description><![CDATA[description]]></Description>
* </Video>
* </xml>
* 参数 是否必须 说明
* ToUserName 是 接收方账号(收到的OpenID)
* FromUserName 是 开发者微信号
* CreateTime 是 消息创建时间 (整型)
* MsgType 是 消息类型,视频为video
* MediaId 是 通过素材管理中的接口上传多媒体文件,得到的id
* Title 否 视频消息的标题
* Description 否 视频消息的描述
* @param mapRequest
* @param text
* @return
*/
public static BaseMessage returnVideo(Map<String, String> mapRequest, String text) {
//实际应用中应根据业务需求来设置需要返回的视频消息
String title="";
String description="";
String mediaId="";
return MessageUtils.returnVideo(mapRequest,mediaId,title,description);
}
回复语音消息
/**
*回复语音消息
* <xml>
* <ToUserName><![CDATA[toUser]]></ToUserName>
* <FromUserName><![CDATA[fromUser]]></FromUserName>
* <CreateTime>12345678</CreateTime>
* <MsgType><![CDATA[voice]]></MsgType>
* <Voice>
* <MediaId><![CDATA[media_id]]></MediaId>
* </Voice>
* </xml>
* 参数 是否必须 说明
* ToUserName 是 接收方账号(收到的OpenID)
* FromUserName 是 开发者微信号
* CreateTime 是 消息创建时间戳 (整型)
* MsgType 是 消息类型,语音为voice
* MediaId 是 通过素材管理中的接口上传多媒体文件,得到的id
* @param mapRequest
* @param text
* @return
*/
public static BaseMessage returnVoice(Map<String, String> mapRequest, String text) {
//实际应用中应根据业务需求来设置需要返回的语音消息
String mediaId="";
return MessageUtils.returnVoice(mapRequest,mediaId);
}
回复图片消息
/**
* 回复图片消息
* <xml>
* <ToUserName><![CDATA[toUser]]></ToUserName>
* <FromUserName><![CDATA[fromUser]]></FromUserName>
* <CreateTime>12345678</CreateTime>
* <MsgType><![CDATA[image]]></MsgType>
* <Image>
* <MediaId><![CDATA[media_id]]></MediaId>
* </Image>
* </xml>
* 参数 是否必须 说明
* ToUserName 是 接收方账号(收到的OpenID)
* FromUserName 是 开发者微信号
* CreateTime 是 消息创建时间 (整型)
* MsgType 是 消息类型,图片为image
* MediaId 是 通过素材管理中的接口上传多媒体文件,得到的id。
* @param mapRequest
* @param text
* @return
*/
public static BaseMessage returnImage(Map<String, String> mapRequest, String text) {
//实际应用中应根据业务需求来设置需要返回的图片消息
String mediaId="";
return MessageUtils.returnImage(mapRequest,mediaId);
}
发送模板消息
/**
* 回复图片消息
* <xml>
* <ToUserName><![CDATA[toUser]]></ToUserName>
* <FromUserName><![CDATA[fromUser]]></FromUserName>
* <CreateTime>12345678</CreateTime>
* <MsgType><![CDATA[image]]></MsgType>
* <Image>
* <MediaId><![CDATA[media_id]]></MediaId>
* </Image>
* </xml>
* 参数 是否必须 说明
* ToUserName 是 接收方账号(收到的OpenID)
* FromUserName 是 开发者微信号
* CreateTime 是 消息创建时间 (整型)
* MsgType 是 消息类型,图片为image
* MediaId 是 通过素材管理中的接口上传多媒体文件,得到的id。
* @param mapRequest
* @param text
* @return
*/
public static BaseMessage returnImage(Map<String, String> mapRequest, String text) {
//实际应用中应根据业务需求来设置需要返回的图片消息
String mediaId="";
return MessageUtils.returnImage(mapRequest,mediaId);
}
/**
*发送模板消息
* 接口调用请求说明
* http请求方式: POST https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN
*
* POST数据说明
* POST数据示例如下:
* {
* "touser":"OPENID",
* "template_id":"ngqIpbwh8bUfcSsECmogfXcV14J0tQlEpBO27izEYtY",
* "url":"http://weixin.qq.com/download",
* "miniprogram":{
* "appid":"xiaochengxuappid12345",
* "pagepath":"index?foo=bar"
* },
* "client_msg_id":"MSG_000001",
* "data":{
*
* "keyword1":{
* "value":"巧克力"
* },
* "keyword2": {
* "value":"39.8元"
* },
* "keyword3": {
* "value":"2014年9月22日"
* }
* }
* }
*
* 参数说明
* 参数 是否必填 说明
* touser 是 接收者openid
* template_id 是 模板ID
* url 否 模板跳转链接(海外账号没有跳转能力)
* miniprogram 否 跳小程序所需数据,不需跳小程序可不用传该数据
* appid 是 所需跳转到的小程序appid(该小程序appid必须与发模板消息的公众号是绑定关联关系,暂不支持小游戏)
* pagepath 否 所需跳转到小程序的具体页面路径,支持带参数,(示例index?foo=bar),要求该小程序已发布,暂不支持小游戏
* data 是 模板数据
* client_msg_id 否 防重入id。对于同一个openid + client_msg_id, 只发送一条消息,10分钟有效,超过10分钟不保证效果。若无防重入需求,可不填
* 注:url和miniprogram都是非必填字段,若都不传则模板无跳转;若都传,会优先跳转至小程序。开发者可根据实际需要选择其中一种跳转方式即可。
* 当用户的微信客户端版本不支持跳小程序时,将会跳转至url。
*
* 返回码说明
* 在调用模板消息接口后,会返回JSON数据包。正常时的返回JSON数据包示例:
* {
* "errcode":0,
* "errmsg":"ok",
* "msgid":200228332
* }
* 可能出现的返回码
* 返回码 含义
* 43116 该模板因滥用被滥用过多,已被限制下发
* 40249 不支持下发营销/推广类的消息内容
* 40250 下发消息内容不规范(包含空值等),建议检查内容规范性后再下发
* 40251 因历史违规导致平台限制账号调用上限,当前已到达下发上限
* 40252 正在调用的模板下发的部分内容已进入平台审核流程,在审核完成前,相关内容暂时无法下发
* @param mapRequest
* @param text
*/
public static void returnTemplateMsg(Map<String, String> mapRequest, String text) {
System.out.println("发送模板消息--------------");
First first = new First("您的会员注册申请已完成审核:","#D9006C");
Keyword1 keyword1 =new Keyword1("刘德华",null);
Keyword2 keyword2 =new Keyword2("个人会员",null);
Keyword3 keyword3 =new Keyword3("未通过","#D9006C");
Remark remark =new Remark("您提交的信息有误,请重新提交","颜色");
Miniprogram miniprogram=new Miniprogram(null,null);
Data da =new Data(first,keyword1,keyword2,keyword3,remark);
AuditResultsMessage resultsMessage =new AuditResultsMessage(da);
resultsMessage.setTouser("o0nBp5uMweDuyg4VH4FTM57ltE7Q");
resultsMessage.setTemplate_id("-NGOs9cRbiksXI4wGnc7nEhYLMZaV9OkSCno23aFKkg");
resultsMessage.setUrl(null);
resultsMessage.setMiniprogram(miniprogram);
//ApiUtils是封装的工具类,向微信接口发送请求进行各项业务处理的方法统一在此类内
boolean rt = ApiUtils.sendTemplateMsg(resultsMessage);
System.out.println("发送模板消息的结果:"+rt);
}
代码中使用到的各类型消息封装的实体类,请下载绑定的资源获取