小弟应运营要求要更改公众号菜单,本以为是在公众号官网上进行配置即可,,谁知道 竟然是开发者模式编辑的。无奈,从未接触过公众号开发的我。有开始啃开了微信开发的api,原来的做这个得小伙伴,跑路了。但没有交接。哎~~~
废话不多说。开启流程。
1、小弟这个仅仅是【订阅号】的开发。进入公众号后左边菜单找到
这是该公众号开发时用到的关键参数列表,如下:
这里介绍下几个开发中用到的重要参数:
1、开发者ID(AppId):就是开发人员在开发该订阅号 的账号
2、开发者密码(AppSecret) : 就是开发人员在开发该订阅号 的密码
3、IP白名单:该参数是微信服务器的一个ip白名单的验证,如果没有该白名单,微信服务器就不会承认你的地址是安全的。不能获取access_token参数
4、服务器地址(URL):他是微信回调 你的服务器的地址。记住这个服务器地址是你的。不是微信的。而且这个地址有些硬性条件
(1)该url必须开通外网映射,不管你是在公司 还是在家。这个地址必须外网能够访问到。
(2)该url端口号必须是80,至于映射到本地应用端口是XXXX都无所谓。配置外网映射 我使用的是Sunny-Ngrok(https://www.ngrok.cc/)内网穿透服务,这个是一个网站提供,里面有免费的http外网映射。其他的映射服务均失败(可能是自己太菜)。。格式,外网映射地址+应用验证接口
5、令牌(Token):验证使用的一个自定义字符串
6、消息加解密密钥:这个参数是发送/接收消时加密用的。但如果设置是明文方式,那么这个参数没用到。我就没用到
7、消息加密/解密方式:明文、兼容、安全
以上参数,构成了微信开发的基础参数。但想要真正开发,还有一些准备要做。
一、验证:
不能可直接在生产环境开发,大牛这么做的都很少。所以需要一个测试环境。那么就是开发者工具中的【公众号测试账号】中,就可以创建,目前其他几项我就是看看没有仔细研究,后期补发。点击进入:
用手机微信直接授权登录即可:
简单说明一下,测试账号信息表中的内容是根据登录的微信生成的。。我试了好几次都不会变。应该是账号绑定的。注意,,这时测试账号的账号和密码,,前者的账号 密码是生产环境。还有 这个登录的微信必须是该公众号管理员授权绑定的微信账号才行。
在公众号左侧菜单 人员设置中添加人员(创建者忽略),然后开发者工具中的Web开发者工具绑定一个开发者的微信号即可。
* 然后说说接口配置信息,第一次测试账号配置是空的。url 也就是你的服务器地址,必须是80端口或443(也就是http和https默认端口)外网能够访问到的地址+你的验证应用接口地址 和第4 配置套路一模一样比如 http://xxxx.cn/wx/yanzhengApi,验证的java demo为:
@ResponseBody
@RequestMapping(value = "/WechatCallbackApi", method = RequestMethod.GET)
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 微信加密签名
String signature = request.getParameter("signature");
System.out.println("微信加密签名=====" + signature);
// 随机字符串
String echostr = request.getParameter("echostr");
System.out.println("随机字符串=====" + echostr);
// 时间戳
String timestamp = request.getParameter("timestamp");
System.out.println("时间戳=====" + echostr);
// 随机数
String nonce = request.getParameter("nonce");
System.out.println("随机数=====" + echostr);
String[] str = { TOKEN, timestamp, nonce };
Arrays.sort(str); // 字典序排序
String bigStr = str[0] + str[1] + str[2];
System.out.println("=====================" + bigStr);
MessageDigestUtils digestutil = new MessageDigestUtils();
String sha1 = MessageDigestUtils.sha1(bigStr);
// 确认请求来至微信
if (sha1.equals(signature)) {
System.out.println("=====验证成功============");
response.getWriter().print(echostr);
}
}
这个demo 方法上面肯定还有一个controller 的mapping,自己写吧。
* 下面的token 就是上述第5点的token
单机提交,如果没有问题,会提示配置成功(这里需要确定你的借口在接收到请求后的响应时间,太长微信都不认, 多试几次就可以了),否则就是配置失败。失败的原因,其实很简单。就是你的url配置的问题。一般token不会有问题。上述图片中是我配置很久才成功的截图。可以修改。提交验证是,会请求上述demo。大哥断点就知道怎么回事了。而且微信的api文档对这块说的还是比较清楚的。就是没有明说url配置需要80或443 端口(PS:其实api文档也说明了。但是,是在另一个页面说明的。。【开始开发】-【接入指南】最下方才说明,这里配置url啥都没说。)
完成以上工作久具备了 订阅号开发的最基本的配置。
* JS接口安全域名 我没有用到。这里不做介绍
使用你的登录测试账号的微信扫描一下 【测试号二维码】就会使当前微信关注这个订阅号了。点击关注。进入后,发现啥玩意都没有。咋办。新建菜单,这个自定义菜单可以使用微信提供的web页面创建 也可以使用java写,java 的demo如下
工具类:
package com.tiancaibao.service.weixin;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.log4j.Logger;
import org.springframework.util.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.tiancaibao.weixin.pojo.token.WeixinToken;
/**
* 获取微信access_token工具类
*/
public class WeiXinAccessTokenUtil
{
private static final Logger DEBUG_LOGGER = Logger.getLogger(WeiXinAccessTokenUtil.class);
/**
* 从微信上
* 获取微信access_token
*
*/
public static WeixinToken getWeiXinAccessToken(String appid,String secret)
{
if(StringUtils.isEmpty(appid)|| StringUtils.isEmpty(secret))
{
DEBUG_LOGGER.error("appid or secret is null");
return null;
}
WeixinToken token = new WeixinToken();
try
{
String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appid+"&secret="+secret;
HttpClient httpClient = new HttpClient();
GetMethod getMethod = new GetMethod(url);
int execute = httpClient.executeMethod(getMethod);
System.out.println("execute:"+execute);
String getResponse = getMethod.getResponseBodyAsString();
System.out.println("========return的json========"+getResponse);
JSONObject json = (JSONObject) JSON.parseObject(getResponse);
token.setAccessToken(json.getString("access_token"));
token.setExpiresIn(new Integer(json.getString("expires_in")));
Date createtime=new Date();;
token.setCreatetime(createtime);
}
catch (IOException e)
{
DEBUG_LOGGER.error("getAccessToken failed,desc:::"+e);
e.printStackTrace();
}
return token;
}
}
access_token实体:
package com.tiancaibao.weixin.pojo.token; import java.io.Serializable; import java.util.Date; public class WeixinToken implements Serializable { private Integer id; private String accessToken; private Integer expiresIn; private Date createtime; protected String fields; private static final long serialVersionUID = 1L; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getAccessToken() { return accessToken; } public void setAccessToken(String accessToken) { this.accessToken = accessToken == null ? null : accessToken.trim(); } public Integer getExpiresIn() { return expiresIn; } public void setExpiresIn(Integer expiresIn) { this.expiresIn = expiresIn; } public Date getCreatetime() { return createtime; } public void setCreatetime(Date createtime) { this.createtime = createtime; } public void setFields(String fields) { this.fields = fields; } public String getFields() { return fields; } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(getClass().getSimpleName()); sb.append(" ["); sb.append("Hash = ").append(hashCode()); sb.append(", id=").append(id); sb.append(", accessToken=").append(accessToken); sb.append(", expiresIn=").append(expiresIn); sb.append(", createtime=").append(createtime); sb.append(", fields=").append(fields); sb.append(", serialVersionUID=").append(serialVersionUID); sb.append("]"); return sb.toString(); } }
请求创建工具:
package com.tiancaibao.weixin.menu;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Date;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.tiancaibao.service.weixin.MyX509TrustManager;
/**
*
* 开发人员: liming </br>
*/
public class WeixinUtil {
private static Logger log = LoggerFactory.getLogger(WeixinUtil.class);
// 菜单创建(POST) 限100(次/天)
public static String menu_create_url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";
/***
* 自定义菜单创建接口:
http请求方式:POST(请使用https协议) https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN
自定义菜单查询接口:
http请求方式:GET https://api.weixin.qq.com/cgi-bin/menu/get?access_token=ACCESS_TOKEN
自定义菜单删除接口:
http请求方式:GET https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=ACCESS_TOKEN
*
*/
/**
* 创建菜单
*
* @param menu 菜单实例
* @param accessToken 有效的access_token
* @return 0表示成功,其他值表示失败
*/
public static int createMenu(Menu menu, String accessToken) {
int result = 0;
// 拼装创建菜单的url
String url = menu_create_url.replace("ACCESS_TOKEN", accessToken);
// 将菜单对象转换成json字符串
String jsonMenu = JSONObject.toJSONString(menu);
// 调用接口创建菜单
JSONObject jsonObject = httpRequest(url, "POST", jsonMenu);
if (null != jsonObject) {
if (0 != jsonObject.getInteger("errcode")) {
result = jsonObject.getInteger("errcode");
log.error("创建菜单失败 errcode:{} errmsg:{}", jsonObject.getInteger("errcode"), jsonObject.getString("errmsg"));
}
}
return result;
}
/**
* 描述: 发起https请求并获取结果
* @param requestUrl 请求地址
* @param requestMethod 请求方式(GET、POST)
* @param outputStr 提交的数据
* @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
*/
public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) {
JSONObject jsonObject = null;
StringBuffer buffer = new StringBuffer();
try {
// 创建SSLContext对象,并使用我们指定的信任管理器初始化
TrustManager[] tm = { new MyX509TrustManager() };
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
sslContext.init(null, tm, new java.security.SecureRandom());
// 从上述SSLContext对象中得到SSLSocketFactory对象
SSLSocketFactory ssf = sslContext.getSocketFactory();
URL url = new URL(requestUrl);
HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();
httpUrlConn.setSSLSocketFactory(ssf);
httpUrlConn.setDoOutput(true);
httpUrlConn.setDoInput(true);
httpUrlConn.setUseCaches(false);
// 设置请求方式(GET/POST)
httpUrlConn.setRequestMethod(requestMethod);
if ("GET".equalsIgnoreCase(requestMethod))
httpUrlConn.connect();
// 当有数据需要提交时
if (null != outputStr) {
OutputStream outputStream = httpUrlConn.getOutputStream();
// 注意编码格式,防止中文乱码
outputStream.write(outputStr.getBytes("UTF-8"));
outputStream.close();
}
// 将返回的输入流转换成字符串
InputStream inputStream = httpUrlConn.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String str = null;
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
bufferedReader.close();
inputStreamReader.close();
// 释放资源
inputStream.close();
inputStream = null;
httpUrlConn.disconnect();
jsonObject = JSONObject.parseObject(buffer.toString());
} catch (ConnectException ce) {
log.error("Weixin server connection timed out.");
} catch (Exception e) {
log.error("https request error:{}", e);
}
return jsonObject;
}
/**
* 发送图片消息
* @param accesstoken
* {
"touser":"OPENID",
"msgtype":"image",
"image":
{
"media_id":"MEDIA_ID"
}
}
* @param openid
*/
public static int SendCustomerMessage(String accesstoken ){
String url="https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token="+accesstoken;
ImageMsg image =new ImageMsg();
Image ima= new Image();
ima.setMedia_id("FsM7Uo7Nk1YDdSZr8zYu7p079vyXhsvdbW3ArYpwqcM");
image.setImage(ima);
image.setTouser("ovlNE1A7Zlufu0wfMYiweE6igo-c");
image.setMsgtype("image");// 图片类型消息
String jsonMenu = JSONObject.toJSONString(image);
System.out.println(jsonMenu);
// 调用接口创建菜单
JSONObject jsonObject = httpRequest(url, "POST", jsonMenu);
int result = 0;
if (null != jsonObject) {
if (0 != jsonObject.getInteger("errcode")) {
result = jsonObject.getInteger("errcode");
log.error("创建菜单失败 errcode:{} errmsg:{}", jsonObject.getInteger("errcode"), jsonObject.getString("errmsg"));
}
}
return result;
}
public static void main(String[] args) {
}
}
自定义菜单创建main:
package com.tiancaibao.weixin.menu;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.tiancaibao.service.weixin.WeiXinAccessTokenUtil;
import com.tiancaibao.weixin.pojo.token.WeixinToken;
/**
* 类名: MenuManager </br>
*
* 描述:菜单管理器类 </br>
*/
public class MenuManager {
private static Logger log = LoggerFactory.getLogger(MenuManager.class);
public static void main(String[] args) {
// 第三方用户唯一凭证 测试
String appId = "wxxxxxxx";
// 第三方用户唯一凭证密钥
String appSecret = "xxxxxxxxxxxx";
WeixinToken weiXinAccessToken = WeiXinAccessTokenUtil.getWeiXinAccessToken(appId, appSecret);
if (null != weiXinAccessToken) {
String asstoken=weiXinAccessToken.getAccessToken();
// 调用接口创建菜单
int result = WeixinUtil.createMenu(getMenu(), asstoken);
// 判断菜单创建结果
if (0 == result)
log.info("菜单创建成功!");
else
log.info("菜单创建失败,错误码:" + result);
}
}
/**
* 组装菜单数据
*
* @return
*/
private static Menu getMenu() {
//新菜单自定义
CommonButton mainBtn1New = new CommonButton();
mainBtn1New.setName("呀!活动");
mainBtn1New.setType("view");
mainBtn1New.setKey("http://weixin.xxxx");
CommonButton btn2_1 = new CommonButton();
btn2_1.setName("历史文章");
btn2_1.setType("view");
btn2_1.setUrl("xxxx");
CommonButton btn2_2 = new CommonButton();
btn2_2.setName("积分商城");
btn2_2.setType("view");
btn2_2.setUrl("http://xxxx");
CommonButton btn2_3 = new CommonButton();
btn2_3.setName("客服热线");
btn2_3.setType("click");
btn2_3.setKey("我们的服务热线xx,工作时间 9:00-20:00,欢迎有问题拨打热线哦~");
CommonButton btn3_1 = new CommonButton();
btn3_1.setName("我的资产");
btn3_1.setType("view");
btn3_1.setKey("http://xxxx");
CommonButton btn3_2 = new CommonButton();
btn3_2.setName("登录注册");
btn3_2.setType("view");
btn3_2.setKey("http://xxx");
CommonButton btn3_3 = new CommonButton();
btn3_3.setName("我要出借");
btn3_3.setType("view");
btn3_3.setKey("http://xxx");
CommonButton btn3_4 = new CommonButton();
btn3_4.setName("下载APP");
btn3_4.setType("view");
btn3_4.setKey("https://xxx");
/**
* 微信: mainBtn1,mainBtn2,mainBtn3底部的三个一级菜单。 执行前观察appSecret参数是否需要重置。记得的话就不需要。。不急的。估计悬了。。要重置,
* 但重置后会不会对全有的菜单有影响呢?~~
*/
// ComplexButton mainBtn1 = new ComplexButton();
// mainBtn1.setName("呀!活动");
// //一级下有4个子菜单
// mainBtn1.setSub_button(new CommonButton[] {btn8,btn9});
ComplexButton mainBtn2 = new ComplexButton();
mainBtn2.setName("呀!姿势");
mainBtn2.setSub_button(new CommonButton[] { btn2_1,btn2_2, btn2_3 });
ComplexButton mainBtn3 = new ComplexButton();
mainBtn3.setName("呀!我的");
mainBtn3.setSub_button(new CommonButton[] { btn3_1,btn3_2,btn3_3, btn3_4 });
/**
* 封装整个菜单
*/
Menu menu = new Menu();
menu.setButton(new Button[] { mainBtn1New, mainBtn2, mainBtn3 });
return menu;
}
}
CommonButton:
package com.tiancaibao.weixin.menu;
/**
* 类名: CommonButton </br>
* 包名: com.souvc.weixin.menu
* 描述: 子菜单项 :没有子菜单的菜单项,有可能是二级菜单项,也有可能是不含二级菜单的一级菜单。 </br>
*/
public class CommonButton extends Button {
private String type;
private String key;
private String url;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
}
complexButton:
package com.tiancaibao.weixin.menu;
public class ComplexButton extends Button {
private Button[] sub_button;
public Button[] getSub_button() {
return sub_button;
}
public void setSub_button(Button[] sub_button) {
this.sub_button = sub_button;
}
}
Button:
package com.tiancaibao.weixin.menu;
/**
* 类名: Button </br>
* 包名: com.souvc.weixin.menu
* 描述: 菜单项的基类 </br>
*/
public class Button {
private String name;//所有一级菜单、二级菜单都共有一个相同的属性,那就是name
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Menu:
package com.tiancaibao.weixin.menu;
/**
* 类名: Menu </br>
* 包名: com.souvc.weixin.menu
* 描述: 整个菜单对象的封装 </br>
*/
public class Menu {
private Button[] button;
public Button[] getButton() {
return button;
}
public void setButton(Button[] button) {
this.button = button;
}
}
以上就是 自定菜单的创建源码及过程。一级菜单和二级菜单的编辑 使用了java 的多态特性。api文档中也给出了具体的demo 可以参考。至于相关的事件和特性也请参看api文档,写的很详细了,不做赘述。
附加,接收微信回调处理方法:
/*
* 特别注意,req.getInputStream()只能获取一次,并且只能读取一次。如果想要多次读取,需要另外想办法。为了简单起见,
*/
@ResponseBody
@RequestMapping(value = "/WechatCallbackApi", method = RequestMethod.POST)
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 设置编码
req.setCharacterEncoding("utf-8");
resp.setContentType("html/text;charset=utf-8");
resp.setCharacterEncoding("utf-8");
/*
* 该部分我们获取用户发送的信息,并且解析成<K,V>的形式进行显示
*/
// 解析用户发送过来的信息
InputStream is = req.getInputStream();// 拿取请求流
// 将解析结果存储在HashMap中
Map<String, String> map = new HashMap<String, String>();
// 解析xml,将获取到的返回结果xml进行解析成我们习惯的文字信息
SAXReader reader = new SAXReader();//
Document document = null;
try {
document = reader.read(is);// 读取流中的内容
} catch (DocumentException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// 得到xml根元素
Element root = document.getRootElement();
// 得到根元素的所有子节点
List<Element> elementList = root.elements();
// 遍历所有子节点,将所有的节点存放到map中,读取的时候方便
for (Element e : elementList)
map.put(e.getName(), e.getText());
Set<String> keySet = map.keySet();
// 输出解析后用户发过来的信息
System.out.println("===解析用户发送过来的信息开始");
String FromUserName = "";// 用户的openid
String event = "";// 事件类型
boolean ismessage = false;
String messsgeContent = "";
String shopid = "";
String EventKey = "";
for (String key : keySet) {
System.out.println(key + ":" + map.get(key));
if ("FromUserName".equals(key)) {
FromUserName = map.get(key);
}
if ("Event".equals(key)) {
event = map.get(key);
}
// 关键词报文开头
if ("MsgId".equals(key)) {
ismessage = true;
}
if ("Content".equals(key)) {
messsgeContent = map.get(key);
}
if ("EventKey".equals(key)) {
EventKey = map.get(key);
}
}
System.out.println("==========是否发送message==============" + ismessage);
System.out.println(":解析用户发送过来的信息结束");
/*
* 该部分我们尝试按照文档的要求格式给用户回复文本信息、图文消息。重点:按照文档要求构造需要的参数。特别注意:参数区分大小写。
*/
// 发送普通文本消息,请查看文档关于“回复文本消息”的xml格式
// 第一步:按照回复文本信息构造需要的参数
TextMsg textMsg = new TextMsg();
textMsg.setToUserName(map.get("FromUserName"));// 发送和接收信息“User”刚好相反
textMsg.setFromUserName(map.get("ToUserName"));
textMsg.setCreateTime(new Date().getTime());// 消息创建时间 (整型)
textMsg.setMsgType("text");// 文本类型消息
Date subscribedate = new Date();
// 自定义菜单为 CLICK,关注为subscribe
if (event.equals("CLICK")) {
textMsg.setContent("我们的服务热线xxxx,工作时间 9:00-20:00,欢迎有问题拨打热线哦~\ue415");
} else if (event.equals("subscribe")) {
// 查询是否有关注记录
Weixinshopsubscriberecord selectInfoByOpenId = wexinSubscibeservice.selectInfoByOpenId(FromUserName);
System.out.println("=============查询是否有关注记录==========" + selectInfoByOpenId);
if (EventKey != "" || EventKey != null || !"".equals(EventKey)) {
System.out.println("===========================EventKey===============" + EventKey.toString());
String[] Str = EventKey.split("_");
// 此判断是为了防止二维码参数为空的情况
if (Str.length > 1) {
shopid = Str[1];
}
}
// 未关注
if (selectInfoByOpenId == null) {
// 初次关注
String FirstSubscribe = "终于等到你还好我没放弃,右下角快去开启你的财富之旅吧!" ;
if(!"".equals(shopid)){
FirstSubscribe+=" 来源编号:"+ shopid;
}
textMsg.setContent(FirstSubscribe);
Weixinshopsubscriberecord weixinshop = new Weixinshopsubscriberecord();
weixinshop.setOpenid(FromUserName);
weixinshop.setShopid(shopid);
weixinshop.setState("1");
weixinshop.setSubscribedate(subscribedate);
weixinshop.setSubscribetime(subscribedate);
// 保存openid
wexinSubscibeservice.SubscribeSave(weixinshop);
} else {
// 取消后再次关注
selectInfoByOpenId.setState("2");
selectInfoByOpenId.setSubscribedate(subscribedate);
selectInfoByOpenId.setSubscribetime(subscribedate);
selectInfoByOpenId.setOpenid(FromUserName);
selectInfoByOpenId.setShopid(shopid);
wexinSubscibeservice.UpdateSubscribe(selectInfoByOpenId);// 更改记录
String SecondSubscribe = "欢迎回到财富之路,等你启程!" ;
if(!"".equals(shopid)){
SecondSubscribe+=" 来源编号:"+ shopid;
}
textMsg.setContent(SecondSubscribe);
}
} else if (event.equals("unsubscribe")) {
Weixinshopsubscriberecord weixinshop = new Weixinshopsubscriberecord();
weixinshop.setState("0");// 取消关注为0
weixinshop.setSubscribedate(subscribedate);
weixinshop.setSubscribetime(subscribedate);
weixinshop.setOpenid(FromUserName);
weixinshop.setShopid(shopid);
wexinSubscibeservice.UpdateSubscribe(weixinshop);
}
// 是否发送客服消息
Boolean issend = false;
/**
* 回复图片消息
*/
ImageMsg imagemsg = new ImageMsg();
imagemsg.setToUserName(map.get("FromUserName"));// 发送和接收信息“User”刚好相反
imagemsg.setFromUserName(map.get("ToUserName"));
imagemsg.setCreateTime(new Date().getTime());// 消息创建时间 (整型)
imagemsg.setMsgType("image");// 文本类型消息
Image Image = new Image();
// Image.setMediaId("FsM7Uo7Nk1YDdSZr8zYu7p079vyXhsvdbW3ArYpwqcM");//图片ID,不固定
Image.setMediaId("6GTGDx7tGKMgnHv2Qzd9-orxsSaNBr4TdLN_n2zdw14");// 图片ID,不固定
imagemsg.setImage(Image);
// 消息内容
if (ismessage) {
if (messsgeContent.indexOf("建军节快乐") != -1) {
textMsg.setContent("活动已结束,欢迎下次来参加哦\ue409");
}else if(messsgeContent.indexOf("中秋") != -1){
textMsg.setContent("http://4xxx/index.jsp?aid=fe66eb90a5ea40e3a956ecaf2926f1c9&activityid=110312&wuid=457767&keyversion=0&isFromApiFilter=1");
}else if (messsgeContent.indexOf("客服 联系 电话") != -1) {
textMsg.setContent("我们的客服热线:xxx,快去拨打吧,美丽的客服妹子在等你~");
} else if (messsgeContent.indexOf("你好") != -1 || messsgeContent.indexOf("在么") != -1
|| messsgeContent.indexOf("在") != -1 || messsgeContent.indexOf("在?") != -1
|| messsgeContent.indexOf("你好?") != -1 || messsgeContent.indexOf("您好?") != -1
|| messsgeContent.indexOf("你好?") != -1 || messsgeContent.indexOf("你好啊?") != -1
|| messsgeContent.indexOf("hi") != -1 || messsgeContent.indexOf("hello") != -1) {
textMsg.setContent("Hi~~~想我了吗?有任何问题,请电话骚扰我们的客服哦,客服电话:xxx \ue032");
} else if (messsgeContent.indexOf("好买酒") != -1 || messsgeContent.indexOf("好卖酒") != -1
|| messsgeContent.indexOf("酒") != -1) {
// textMsg.setContent("呀呀,你是“好买酒”过来的吧?路途遥远,辛苦啦\ue056
// \n即日起,扫描上方二维码实名注册xxx,即可享受5000元体验金\ue106+80元现金红包\ue106+20%加息券\ue106“三重好礼”大礼包,机不可失,失不再来,快去完成注册吧\ue056");
XStream xStream = new XStream();
xStream.alias("xml", imagemsg.getClass());
String imagemsgXml = xStream.toXML(imagemsg);
System.out.println("回复图片的xml====" + imagemsgXml);
PrintWriter printWriter = resp.getWriter();
printWriter.print(imagemsgXml);
issend = true;
} else {
textMsg.setContent(
"憋~着~急~哈~\ue415你的消息,小编我已收到,容我慢慢回复哈~\ue056有问题最好还是找我们的客服妹子哈,xxx,人家可比我这个整天只知道码字送积分的小编专业滴多哈~~~\ue409");
}
}
XStream xStream = new XStream();
xStream.alias("xml", textMsg.getClass());
String textMsg2Xml = xStream.toXML(textMsg);
System.out.println("返回给微信服务器,让其发送用户消息的报文====" + textMsg2Xml);
// 第三步,发送xml的格式信息给微信服务器,服务器转发给用户
// 除了这个,已关注再扫描的事件
if (!event.equals("SCAN")) {
PrintWriter printWriter = resp.getWriter();
printWriter.print(textMsg2Xml);
System.out.println("======文本发送了============");
}
if (issend) {
/**
* 发送客服文本消息
*/
// 第一步 获取accesstoken
String accesstoken = "";
Date date1 = new Date();
Date date2 = new Date();
Weixincommoninfo selectaccesstoken = weixincommoInfoservice.selectInfo();
// 查看是否有accesstoken
if (selectaccesstoken == null) {
selectaccesstoken = new Weixincommoninfo();
WeixinToken weiXinAccessToken = WeiXinAccessTokenUtil.getWeiXinAccessToken();
accesstoken = weiXinAccessToken.getAccessToken();
selectaccesstoken.setSavefiled("accesstoken");
selectaccesstoken.setSaveinfo(accesstoken);
selectaccesstoken.setExpiresIn(weiXinAccessToken.getExpiresIn());
selectaccesstoken.setCreatetime(date1);
date2.setHours(date1.getHours() + 1);// 此处将accesstoken的有效期,设置为1小时
selectaccesstoken.setEffectivetime(date2);
weixincommoInfoservice.Saveinfo(selectaccesstoken);
} else {
Date date = new Date();
// 判断当前时间是否在accesstoken 的有效期内,
Date effectivetime = selectaccesstoken.getEffectivetime();
if (effectivetime.getTime() > date.getTime()) {
accesstoken = selectaccesstoken.getSaveinfo();
System.out.println("数据库中的accesstoken能用");
} else {
WeixinToken weiXinAccessToken = WeiXinAccessTokenUtil.getWeiXinAccessToken();
selectaccesstoken = new Weixincommoninfo();
accesstoken = weiXinAccessToken.getAccessToken();
selectaccesstoken.setSavefiled("accesstoken");
selectaccesstoken.setSaveinfo(accesstoken);
selectaccesstoken.setExpiresIn(weiXinAccessToken.getExpiresIn());
selectaccesstoken.setCreatetime(date1);
date2.setHours(date1.getHours() + 1);
selectaccesstoken.setEffectivetime(date2);
weixincommoInfoservice.upadateInfo(selectaccesstoken);
System.out.println("数据库中的accesstoken不呢能用,重新获取更新");
}
}
// 第二步发送消息
System.out.println("发送客服消息=======================");
String mescont = "呀呀,你是“好买酒”过来的吧?路途遥远,辛苦啦\ue056 \n即日起,扫描下方二维码实名注册xxx,即可享受5000元体验金\ue106+80元现金红包\ue106+20%加息券\ue106“三重好礼”大礼包,机不可失,失不再来,快去完成注册吧\ue056";
WeixinUtil.SendCustomerTextMessage(accesstoken, FromUserName, mescont);
}
}