/**
* 在公众号第三方平台创建审核通过后,微信服务器会向其“授权事件接收URL”每隔10分钟定时推送component_verify_ticket。第三方平台方在收到ticket推送后也需进行解密(详细请见【消息加解密接入指引】),接收到后必须直接返回字符串success。
* @param msg_signature
* @param timestamp
* @param nonce
* @throws Exception
*/
@RequestMapping("/authorizer.do")
public void authorizer(String msg_signature,String timestamp,String nonce) throws Exception{
String bodyXml = Dom4jUtils.recieveData(request);
//String appid = Dom4jUtils.readStringXml(bodyXml, "AppId");
WeixinAuthorizer weixinAuthorizer=weixinAuthorizerService.getObjectById(WeixinAuthorizer.class, 1);
WXBizMsgCrypt wx=new WXBizMsgCrypt(weixinAuthorizer.getComponent_token(),weixinAuthorizer.getComponent_key(),weixinAuthorizer.getComponent_appid());
String result2 = wx.decryptMsg_AppId(msg_signature, timestamp, nonce, bodyXml);
String infoType = Dom4jUtils.readStringXml(result2, "InfoType");
if(null!=infoType&&"component_verify_ticket".equals(infoType)){
String componentVerifyTicket = Dom4jUtils.readStringXml(result2, "ComponentVerifyTicket");
weixinAuthorizer.setComponentVerifyTicket(componentVerifyTicket);
weixinAuthorizerService.save(weixinAuthorizer);
logger.warn("componentVerifyTicket==="+componentVerifyTicket);
}else if("unauthorized".equals(infoType)){//推送取消授权通知
String authorizerAppid = Dom4jUtils.readStringXml(result2, "AuthorizerAppid");
WeChatConfig weChatConfig = weChatConfigService.getWeChatConfigbyAppid(authorizerAppid);
if(weChatConfig!=null){
weChatConfig.setUseState(1);
weChatConfigService.save(weChatConfig);
}
}
PrintWriter sl = response.getWriter();
sl.write("success");
sl.flush();
sl.close();
}
/**
* 获取授权码
* @param auth_code
* @return
* @throws Exception
*/
@RequestMapping("/getAuth_code.do")
public String getAuth_code(String auth_code,String id) throws Exception{
User user=getLoginUser();
Provide provide=provideService.getObjectById(Provide.class, user.getAgentOrProvide());
logger.info("获取授权码成功");
WeixinAuthorizer weixinAuthorizer= weixinAuthorizerService.getObjectById(WeixinAuthorizer.class, 1);
weixinAuthorizer.setAuth_code(auth_code);
weixinAuthorizerService.save(weixinAuthorizer);
Map<String,String> mp = new HashMap<String,String>();
mp.put("component_appid", weixinAuthorizer.getComponent_appid());
mp.put("authorization_code", auth_code);
JSONObject obj = JSONObject.fromObject(mp);
logger.warn(obj.toString());
logger.warn("-------------------使用授权码换取公众号的授权信息---requestUrl------------------------");
JSONObject result=HttpTool.httpRequest("https://api.weixin.qq.com/cgi-bin/component/api_query_auth?component_access_token="+weixinAuthorizer.getComponent_access_token(),"POST", obj.toString());
logger.warn(result.toString());
WeChatConfig weChatConfig=new WeChatConfig();
weChatConfig.setAppid(result.getJSONObject("authorization_info").get("authorizer_appid").toString());
if (result.has("errcode")) {
logger.error("获取第三方平台access_token!errcode=" + result.getString("errcode") + ",errmsg = " + result.getString("errmsg"));
}
ApiGetAuthorizer apiGetAuthorizer=new ApiGetAuthorizer();
apiGetAuthorizer.setComponent_appid(weixinAuthorizer.getComponent_appid());
WeChatConfig oldweChatConfig=weChatConfigService.getWeChatConfigbyAppid(weChatConfig.getAppid());
if(null!=oldweChatConfig){
weChatConfig=oldweChatConfig;
}
weChatConfig.setAuthorizerType(1);
weChatConfig.setAccess_token(result.getJSONObject("authorization_info").get("authorizer_access_token").toString());
weChatConfig.setAuthorizer_refresh_token(result.getJSONObject("authorization_info").get("authorizer_refresh_token").toString());
apiGetAuthorizer.setAuthorizer_appid(weChatConfig.getAppid());
JSONObject param = JSONObject.fromObject(apiGetAuthorizer );
JSONObject result1 = HttpTool.httpRequest("https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_info?component_access_token="+weixinAuthorizer.getComponent_access_token(),"POST", param.toString());
ApiGetAuthorizerRet apiGetAuthorizerRet = (ApiGetAuthorizerRet)JSONObject.toBean(result1, ApiGetAuthorizerRet.class);
weChatConfig.setName(apiGetAuthorizerRet.getAuthorizer_info().getNick_name());
weChatConfig.setHead_img(apiGetAuthorizerRet.getAuthorizer_info().getHead_img());
if(apiGetAuthorizerRet.getAuthorizer_info().getService_type_info().getId()==2){
weChatConfig.setTypes(0);
}else{
weChatConfig.setTypes(1);
}
weChatConfig.setUseState(0);//启用
weChatConfig.setToUserName(apiGetAuthorizerRet.getAuthorizer_info().getUser_name());
weChatConfig.setProvide(provide);
weChatConfigService.save(weChatConfig);
List<WeChatMenu> rootList=weChatMenuService.getChatMenusByProvide(weChatConfig.getProvide());
WeChatConfigQuery weChatConfigQuery=new WeChatConfigQuery();
weChatConfigQuery.setMainNum(1);
weChatConfigQuery.setProvide(weChatConfig.getProvide());
WeChatConfig manweChatConfig=weChatConfigService.getByProvideId(weChatConfigQuery);//查询是否有主服务号
if(null!=manweChatConfig){//发布菜单
String jsonStr=menu(manweChatConfig, rootList,weChatConfig);//从微信号
String restlut=HttpRequestTool.sendPost("https://api.weixin.qq.com/cgi-bin/menu/create?access_token="+ weChatConfig.getAccess_token(),jsonStr);
logger.warn("restlut="+restlut);
}else{
String jsonStr=menu(weChatConfig, rootList,weChatConfig);//主微信号
String restlut=HttpRequestTool.sendPost("https://api.weixin.qq.com/cgi-bin/menu/create?access_token="+ weChatConfig.getAccess_token(),jsonStr);
logger.warn("restlut="+restlut);
}
if(null!=id){
return "redirect:../provide/list.do";
}
return "redirect:../weChatConfig/list.do";
}
/**
* 公众号消息与事件接收
*
* @param request
* @param response
* @throws Exception
* @throws DocumentException
* @throws IOException
*/
@RequestMapping(value = "/{appid}/callback.do")
public void acceptMessageAndEvent(String msg_signature,String timestamp,String nonce,@PathVariable("appid") String appid) throws Exception {
WeixinAuthorizer weixinAuthorizer= weixinAuthorizerService.getObjectById(WeixinAuthorizer.class, 1);
WXBizMsgCrypt wx=new WXBizMsgCrypt(weixinAuthorizer.getComponent_token(),weixinAuthorizer.getComponent_key(),weixinAuthorizer.getComponent_appid());
String bodyXml = Dom4jUtils.recieveData(request);
String result2 = wx.decryptMsg(msg_signature, timestamp, nonce, bodyXml);
String toUserName = Dom4jUtils.readStringXml(result2, "ToUserName");
String fromUserName = Dom4jUtils.readStringXml(result2, "FromUserName");
String msgType = Dom4jUtils.readStringXml(result2, "MsgType");
String event = Dom4jUtils.readStringXml(result2, "Event");
String content = Dom4jUtils.readStringXml(result2, "Content");
if (StringUtils.equalsIgnoreCase(toUserName, "gh_3c884a361561")) {
logger.info("全网发布接入检测消息反馈开始----------------appid="+appid+"--------toUserName="+toUserName);
checkWeixinAllNetworkCheck(request,response,bodyXml);
return ;
}
WeChatUser weChatUser= new WeChatUser();
WeChatConfig weChatConfig=weChatConfigService.getWeChatConfigbyAppid(appid);
//自动回复
WeChatInputReplyQuery weChatInputReplyQuery = new WeChatInputReplyQuery();
weChatInputReplyQuery.setConfigId(weChatConfig.getId());
pageInfo = weChatInputReplyService.findAll(weChatInputReplyQuery, null);
//把自动回复拼上去
StringBuilder sb = new StringBuilder();
StringBuilder sb1 = new StringBuilder();
sb.append(weChatConfig.getAutoReply());
if(null!=pageInfo && null!= pageInfo && pageInfo.getList().size()>0){
//如果有可输入的内容.
List<WeChatInputReply> list = pageInfo.getList();
for (WeChatInputReply weChatInputReply : list) {
sb1.append("\n"+weChatInputReply.getInputValue());
sb1.append("、"+weChatInputReply.getInputValueName());
}
}
// content=WeChartTemp.CreateRelayCustomMsg(toUserName,fromUserName);
// System.out.println("################"+fromUserName);
// System.out.println("################"+toUserName);
// String sEncryptMsg1 = wx.encryptMsg(content, timestamp, nonce);
// PrintWriter writer = response.getWriter();
// writer.write(sEncryptMsg1);
// writer.close();
if("subscribe".equals(event)) {//关注事件
String userInfor=HttpRequestTool.sendGet("https://api.weixin.qq.com/cgi-bin/user/info", "access_token="+weChatConfig.getAccess_token()+"&openid="+fromUserName+"&lang=zh_CN");
Gson gs=new Gson();
WeChatUser newweChatUser = gs.fromJson(userInfor, WeChatUser.class);
synchronized (this) {
if(weChatConfig.getMainNum()==1){//用户信息 只保存主微信用户信息
weChatUser=weChatUserService.getWeChatUserByOpenid(fromUserName);
if(weChatUser==null){
newweChatUser.setSubscribeTime(new Date());
newweChatUser.setGuanzhu(1);
newweChatUser.setOpenid(fromUserName);
newweChatUser.setProvide(weChatConfig.getProvide());
newweChatUser.setToUserName(weChatConfig.getToUserName());
weChatUserService.save(newweChatUser);
}else{
weChatUser.setCity(newweChatUser.getCity());
weChatUser.setCountry(newweChatUser.getProvince());
weChatUser.setCountry(newweChatUser.getCountry());
weChatUser.setNickname(newweChatUser.getNickname());
weChatUser.setSex(newweChatUser.getSex());
weChatUserService.save(weChatUser);
}
}
}
//查出这个配置下的自动回复
logger.warn(sb.append(sb1).toString());//顺序倒了..
content=WeChartTemp.responseCommonText(fromUserName,toUserName,event+"from_callback");
String sEncryptMsg = wx.encryptMsg(content, timestamp, nonce);
response.getWriter().write(sEncryptMsg);
}else if ("unsubscribe".equalsIgnoreCase(event)) {//取消关注
weChatUser=weChatUserService.getWeChatUserByOpenid(fromUserName);
weChatUser.setGuanzhu(2);
weChatUserService.save(weChatUser);
}else if("text".equalsIgnoreCase(msgType)){
content ="输入有误,请按要求输入!"+sb1.toString();
content=WeChartTemp.responseCommonText(fromUserName,toUserName,content);
//客户输入的信息
String recontent=Dom4jUtils.readStringXml(bodyXml, "Content");
if(null!=pageInfo && null!= pageInfo && pageInfo.getList().size()>0){
//如果有可输入的内容.
List<WeChatInputReply> list = pageInfo.getList();
for (WeChatInputReply weChatInputReply : list) {
if(weChatInputReply.getInputValue().equals(recontent) || weChatInputReply.getInputValueName().equals(recontent)){
if(weChatInputReply.getTypes()==0){
content = weChatInputReply.getReplyValue();
content=WeChartTemp.responseCommonText(fromUserName,toUserName,content);
}
if(weChatInputReply.getTypes()==1){
content=weChartArticleService.findArticleOne(weChatInputReply.getConfig().getProvide(),fromUserName,toUserName,8);
if(content==null){
content="暂无数据,等待更新";
content=WeChartTemp.responseCommonText(fromUserName,toUserName,content);
}
}
}
}
}
String sEncryptMsg = wx.encryptMsg(content, timestamp, nonce);
response.getWriter().write(sEncryptMsg);
}
}
public void checkWeixinAllNetworkCheck(HttpServletRequest request, HttpServletResponse response,String xml) throws Exception{
String nonce = request.getParameter("nonce");
String timestamp = request.getParameter("timestamp");
String msgSignature = request.getParameter("msg_signature");
WeixinAuthorizer weixinAuthorizer= weixinAuthorizerService.getObjectById(WeixinAuthorizer.class, 1);
WXBizMsgCrypt pc=new WXBizMsgCrypt(weixinAuthorizer.getComponent_token(),weixinAuthorizer.getComponent_key(),weixinAuthorizer.getComponent_appid());
xml = pc.decryptMsg(msgSignature, timestamp, nonce, xml);
Document doc = DocumentHelper.parseText(xml);
Element rootElt = doc.getRootElement();
String msgType = rootElt.elementText("MsgType");
String toUserName = rootElt.elementText("ToUserName");
String fromUserName = rootElt.elementText("FromUserName");
// LogUtil.info("---全网发布接入检测--step.1-----------msgType="+msgType+"-----------------toUserName="+toUserName+"-----------------fromUserName="+fromUserName);
// LogUtil.info("---全网发布接入检测--step.2-----------xml="+xml);
if("event".equals(msgType)){
// LogUtil.info("---全网发布接入检测--step.3-----------事件消息--------");
String event = rootElt.elementText("Event");
replyEventMessage(request,response,event,toUserName,fromUserName);
}else if("text".equals(msgType)){
// LogUtil.info("---全网发布接入检测--step.3-----------文本消息--------");
String content = rootElt.elementText("Content");
processTextMessage(request,response,content,toUserName,fromUserName);
}
}
public void replyEventMessage(HttpServletRequest request, HttpServletResponse response, String event, String toUserName, String fromUserName) throws Exception {
String content = event + "from_callback";
logger.info("---全网发布接入检测------step.4-------事件回复消息 content="+content + " toUserName="+toUserName+" fromUserName="+fromUserName);
replyTextMessage(request,response,content,toUserName,fromUserName);
}
public void processTextMessage(HttpServletRequest request, HttpServletResponse response,String content,String toUserName, String fromUserName) throws Exception{
if("TESTCOMPONENT_MSG_TYPE_TEXT".equals(content)){
String returnContent = content+"_callback";
replyTextMessage(request,response,returnContent,toUserName,fromUserName);
}else if(StringUtils.startsWithIgnoreCase(content, "QUERY_AUTH_CODE")){
output(response, "");
//接下来客服API再回复一次消息
try {
replyApiTextMessage(request,response,content.split(":")[1],fromUserName);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void replyApiTextMessage(HttpServletRequest request, HttpServletResponse response, String auth_code, String fromUserName) throws Exception {
String authorization_code = auth_code;
// 得到微信授权成功的消息后,应该立刻进行处理!!相关信息只会在首次授权的时候推送过来
logger.warn("------step.1----使用客服消息接口回复粉丝----逻辑开始-------------------------");
try {
WeixinAuthorizer weixinAuthorizer= weixinAuthorizerService.getObjectById(WeixinAuthorizer.class, 1);
ApiComponentToken apiComponentToken = new ApiComponentToken();
apiComponentToken.setComponent_appid(weixinAuthorizer.getComponent_appid());
apiComponentToken.setComponent_appsecret(weixinAuthorizer.getComponent_appSecret());
apiComponentToken.setComponent_verify_ticket(weixinAuthorizer.getComponentVerifyTicket());
JSONObject param = JSONObject.fromObject(apiComponentToken);
JSONObject api_component_token=HttpTool.sendPostUrl("https://api.weixin.qq.com/cgi-bin/component/api_component_token",param.toString(), "UTF-8");
logger.warn("api_component_token="+api_component_token.toString());
String component_access_token =JSONObject.fromObject(api_component_token).getString("component_access_token");
logger.warn("------step.2----使用客服消息接口回复粉丝------- component_access_token = "+component_access_token + "---------authorization_code = "+authorization_code);
net.sf.json.JSONObject authorizationInfoJson =getApiQueryAuthInfo(weixinAuthorizer.getComponent_appid(), authorization_code, component_access_token);
logger.warn("------step.3----使用客服消息接口回复粉丝-------------- 获取authorizationInfoJson = "+authorizationInfoJson);
net.sf.json.JSONObject infoJson = authorizationInfoJson.getJSONObject("authorization_info");
String authorizer_access_token = infoJson.getString("authorizer_access_token");
Map<String,Object> obj = new HashMap<String,Object>();
Map<String,Object> msgMap = new HashMap<String,Object>();
String msg = auth_code + "_from_api";
msgMap.put("content", msg);
obj.put("touser", fromUserName);
obj.put("msgtype", "text");
obj.put("text", msgMap);
sendMessage(obj, authorizer_access_token);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 发送客服消息
* @param obj
* @param ACCESS_TOKEN
* @return
*/
void sendMessage(Map<String,Object> obj,String ACCESS_TOKEN){
JSONObject json = JSONObject.fromObject(obj);
logger.warn("--------发送客服消息---------json-----"+json.toString());
// 调用接口获取access_token
JSONObject jsonObject = HttpTool.httpRequest("https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token="+ACCESS_TOKEN, "POST", json.toString());
logger.warn("--------发送客服消息结果--"+jsonObject.toString());
}
public JSONObject getApiQueryAuthInfo(String component_appid,String authorization_code,String component_access_token) throws Exception{
Map<String,String> mp = new HashMap<String,String>();
mp.put("component_appid", component_appid);
mp.put("authorization_code", authorization_code);
JSONObject obj = JSONObject.fromObject(mp);
logger.warn(obj.toString());
logger.warn("-------------------3、使用授权码换取公众号的授权信息---requestUrl------------------------");
JSONObject result=HttpTool.httpRequest("https://api.weixin.qq.com/cgi-bin/component/api_query_auth?component_access_token="+component_access_token,"POST", obj.toString());
logger.warn(result.toString());
if (result.has("errcode")) {
logger.error("获取第三方平台access_token!errcode=" + result.getString("errcode") + ",errmsg = " + result.getString("errmsg"));
}
return result;
}
/**
* 回复微信服务器"文本消息"
* @param request
* @param response
* @param content
* @param toUserName
* @param fromUserName
* @throws Exception
*/
public void replyTextMessage(HttpServletRequest request, HttpServletResponse response, String content, String toUserName, String fromUserName) throws Exception {
Long createTime = Calendar.getInstance().getTimeInMillis() / 1000;
StringBuffer sb = new StringBuffer();
sb.append("<xml>");
sb.append("<ToUserName><![CDATA["+fromUserName+"]]></ToUserName>");
sb.append("<FromUserName><![CDATA["+toUserName+"]]></FromUserName>");
sb.append("<CreateTime>"+createTime+"</CreateTime>");
sb.append("<MsgType><![CDATA[text]]></MsgType>");
sb.append("<Content><![CDATA["+content+"]]></Content>");
sb.append("</xml>");
String replyMsg = sb.toString();
String returnvaleue = "";
try {
WeixinAuthorizer weixinAuthorizer= weixinAuthorizerService.getObjectById(WeixinAuthorizer.class, 1);
WXBizMsgCrypt pc=new WXBizMsgCrypt(weixinAuthorizer.getComponent_token(),weixinAuthorizer.getComponent_key(),weixinAuthorizer.getComponent_appid());
returnvaleue = pc.encryptMsg(replyMsg, createTime.toString(), "easemob");
logger.warn("------------------加密后的返回内容 returnvaleue: "+returnvaleue);
} catch (AesException e) {
e.printStackTrace();
}
output(response, returnvaleue);
}
/**
* 工具类:回复微信服务器"文本消息"
* @param response
* @param returnvaleue
*/
public void output(HttpServletResponse response,String returnvaleue){
try {
PrintWriter pw = response.getWriter();
pw.write(returnvaleue);
pw.flush();
} catch (IOException e) {
e.printStackTrace();
}
}