微信开发文档:

客服接口-发消息

接口调用请求说明

http请求方式: POST
https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=ACCESS_TOKEN

各消息类型所需的JSON数据包如下:

发送文本消息

{"touser":"OPENID","msgtype":"text","text":{"content":"Hello World"}
}

创建封装实体类:

import java.util.Map;/*** 客户接口消息发送实体** @author * @date 2018-2-6 11:00:30*/
public class TestMessage {//openidprivate String touser;//消息类型private String msgtype;//消息内容private Map<String,Object> text ;public String getTouser() {return touser;}public void setTouser(String touser) {this.touser = touser;}public String getMsgtype() {return msgtype;}public void setMsgtype(String msgtype) {this.msgtype = msgtype;}public Map<String, Object> getText() {return text;}public void setText(Map<String, Object> text) {this.text = text;}
}

后台controller代码:

 
 
/*** 状态修改为测试中** @param id 要测试的ID* @param request* @return 内容展示页面*/
@ResponseBody
@RequestMapping(value = "/service/test", method = RequestMethod.PUT)
public ResponseVO ContentTest(Long id, HttpServletRequest request) {ResponseVO vo=new ResponseVO();if(id!=null){//根据接收的ID查询相应的内容实体WeixinContent weixinContent = weixinContentService.selectById(id);//判断查询到的对象的合法性if (weixinContent!=null&&(weixinContent.getState() == 1||weixinContent.getState()==4)) {//修改内容实体状态为测试中weixinContent.setState(2);//将内容实体进行保存操作weixinContentService.updateById(weixinContent);//获得内容静态页面的访问路径String templatesUrl= weixinContent.getTemplatesUrl();//拼接访问的完整路径String saveUrl =fileuploadPrefix + "/" + templatesUrl;//获得内容信息标题String title = weixinContent.getTitle();//拼接发送的消息内容String content="你好!标题("+title+")<a href='"+saveUrl+"'>点我测试</a>";//创建微信用户查询条件Wrapper<WeixinUser> wrapper=new EntityWrapper<>();wrapper.where("tagid_list={0}","[101]");//获得满足条件的集合List<WeixinUser> weixinUsers = weixinUserService.selectList(wrapper);//遍历用户集合调用业务层进行消息发送for (WeixinUser weixinUser : weixinUsers) {String openid = weixinUser.getOpenid();//调用业务层进行发送消息wxContentTextService.contentTest(openid,content);}vo.setSuccess(true);} else {//不是未测试状态所以不能进行状态修改vo.setSuccess(false);}}return vo;
}

后台service代码:

 
/*** <p>* 菜单信息 服务实现类* </p>** @author * @date 2018/01/15*/
@Service
public class WxContentTextService {private static Logger log = LoggerFactory.getLogger(WxContentTextService.class);/*** 客服接口给用户发送消息接口*/public static String  content_openid="https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=ACCESS_TOKEN";@Autowiredprivate TokenFeignService tokenFeignService;@Autowiredprivate WeixinPortalService weixinPortalService;/**** @param openid   openid* @param saveUrl   静态页面访问地址* @return*/public ResponseVO contentTest(String openid,String saveUrl){//获得令牌String accessToken = tokenFeignService.getToken();//创建返回实体对象ResponseVO vo = new ResponseVO();//替换tokenString url=content_openid.replace("ACCESS_TOKEN", accessToken);TestMessage testMessage=new TestMessage();//设置消息的类型testMessage.setMsgtype("text");//设置要发送的openid集合testMessage.setTouser(openid);//创建集合Map<String,Object> map=new HashMap<>();//设置发送内容map.put("content",saveUrl);testMessage.setText(map);//将测试消息对象转成jsonString jsonTestMessage = JSONObject.toJSONString(testMessage);//调用接口进行发送JSONObject jsonObject = httpRequest(url, "POST", jsonTestMessage);log.error("分组群发消息失败 errcode:{" + jsonObject.getInteger("errcode")+"} " +"errmsg:{"+jsonObject.getString("errmsg")+"} ");Integer errcode = jsonObject.getInteger("errcode");String errorCodeText = ErrorCodeText.errorMsg(errcode);if (errcode == 0){vo.setSuccess(true);}else{vo.setSuccess(false);}vo.setCode(errcode);vo.setText(errorCodeText);return vo;}
}

获取token的业务层:

import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;/*** 进行请求分发**/
@FeignClient(value = "weixin-2")
public interface TokenFeignService {/*** 进行token请求* @param* @return*/@RequestMapping(value = "/getToken",method = RequestMethod.GET)String getToken();
}

微信请求工具类utils

 
public class WeixinHttpUtil {private static Logger log = LoggerFactory.getLogger(WeixinHttpUtil.class);/*** 描述:  发起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;}
}
 

应网友要求贴出获取token部分代码,首先要配置公众号相关配置

1.IP白名单

2.配置开发模式

3.在自己配置的白名单服务器就可以获取token,根据自己配置的服务器接口就可以监听所有公众号的操作,从而得到操作用户信息和具体操作内容

3.1这个就是通过springCloud远程调用获取token接口

@Controller
@RequestMapping("")
public class WeixinTokenController {@Autowiredprivate WeixinAccessTokenTask weixinAccessTokenTask;@RequestMapping("getToken")@ResponseBodypublic String getToken(){AccessToken token = weixinAccessTokenTask.getLastAccessToken();return token.getAccessToken();}}

3.2具体获取token业务

@Component
public class WeixinAccessTokenTask implements ApplicationListener {protected final static Logger logger = LoggerFactory.getLogger(WeixinAccessTokenTask.class);private static boolean isStart = false;/*** 微信Access_Token刷新地址*/private String uri = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";/*** 存放Access_Token的标识符*/private String tokenKey = "WEIXIN_ACCESS_TOKEN";/***  最近一次的Access_Token*/private AccessToken lastAccessToken;/*** 微信分配的appID*/@Value("${app.id}")private String appID;/*** 微信分配的appsecret*/@Value("${app.secrect}")private String appsecrect;private long lastRunTime;/*** 刷新Access_Token* @return boolean 刷新是否成功*/@Scheduled(cron="0 0/5 * * * ?")public boolean refresh(){boolean refresh = this.refresh(false);//重置最后一次定时器运行时间lastRunTime = System.currentTimeMillis();return refresh;}/*** 刷新Access_Token* @param forced 是否强制* @return boolean 刷新是否成功*/public boolean refresh(boolean forced){if(!(forced || this.isNeedRefresh())){return false;}try {AccessToken token = this.getWeixinAccessToken();//把token存入lastAccessToken,便于下次检验token是否有效lastAccessToken = token;return true;} catch (IOException e){e.printStackTrace();}return false;}/*** 请求微信接口获取最新的access_token信息* @return AccessToken*/public AccessToken getWeixinAccessToken() throws IOException{String uri = this.uri.replace("APPID",this.getAppID()).replace("APPSECRET",this.getAppsecrect());URL url = new URL(uri);HttpURLConnection conn = null;BufferedReader reader = null;StringBuffer buffer = new StringBuffer();try{conn = (HttpURLConnection) url.openConnection();conn.setRequestMethod("GET");conn.connect();reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));String line;while ((line = reader.readLine()) != null) {buffer.append(line);}}finally {if(reader != null){reader.close();}if(conn != null){conn.disconnect();}}//返回的参数是json格式JSONObject jsonObject = JSONObject.parseObject(buffer.toString());AccessToken token = new AccessToken();if (!jsonObject.containsKey("access_token")) {//如果没拿到token,肯定发生了问题,打印错误日志logger.info(jsonObject.toJSONString());}String accessToken = jsonObject.getString("access_token");String expiresInStr = jsonObject.getString("expires_in");int expiresIn = Integer.parseInt(expiresInStr);token.setAccessToken(accessToken);token.setExpiresIn(expiresIn);//设置token的更新时间token.setUpdateTime(new Date());logger.info("最新的token>>>> "+ AesUtil.aesEncrypt(accessToken));return token;}/***  是否需要刷新**  @return boolean 判断是否需要刷新*/private boolean isNeedRefresh(){AccessToken token = this.getLastAccessToken();/*如果上次会话不存在,肯定是需要刷新缓存的*/if(null == token){return true;}//当前系统时间long now = System.currentTimeMillis();//此次运行和上次运行的时间间隔,5minlong interval = now - this.lastRunTime;//上次token的更新时间long lastTimeMillis = this.getLastTimeMillis();//此处在微信规定7200秒的基础上减去1800秒,即度过1h30m的时间,就认为token已失效,以此保证token的有效性int expiresIn = 5400*1000;/*如果时间间隔不足以支撑到下次运算时的超时时间,则会话会在本次被刷新*/
//        logger.info("判断是否需要刷新开始---------");
//        logger.info("                   此时此刻 now            ---------" + now);
//        logger.info("此次运行和上次运行的时间间隔 interval       ---------" + interval);
//        logger.info("        上次token的更新时间 lastTimeMillis ---------" + lastTimeMillis);
//        logger.info("               token有效期  expiresIn      ---------" + expiresIn);
//        logger.info("计算表达式(lastTimeMillis + expiresIn) <= (now + interval)---------" + ((lastTimeMillis + expiresIn) <= (now + interval)));if((lastTimeMillis + expiresIn) <= (now + interval)){return true;}return false;}private String getAppID() {return appID;}public void setAppID(String appID) {this.appID = appID;}private String getAppsecrect() {return appsecrect;}public void setAppsecrect(String appsecrect) {this.appsecrect = appsecrect;}public AccessToken getLastAccessToken(){if(this.lastAccessToken == null){return null;}return this.lastAccessToken;}//获得token有效期的时间戳private long getLastTimeMillis(){AccessToken token = this.getLastAccessToken();Date updateTime = token.getUpdateTime();if(updateTime == null){return 0L;}long millis = updateTime.getTime();return millis;}@Overridepublic void onApplicationEvent(ApplicationEvent applicationEvent) {if (!isStart) {isStart = true;logger.info("启动token刷新服务..........");this.refresh();}}
}

微信公众号客服接口给指定用户openid发送消息相关推荐

  1. php 公众号指定人发消息,微信公众号客服接口给指定用户openid发送消息

    微信公众号客服接口给指定用户openid发送消息 2018-09-23 微信开发文档: 客服接口-发消息 接口调用请求说明 http请求方式: POSThttps://api.weixin.qq.co ...

  2. java微信的客服接口开发,微信公众号 客服接口的开发实例详解

    微信平台更新之后,发现客服接口不错.研究了下 和大家分享下. 按照官方文档,是向客服接口发送规定的JSon 就可以了. 首先先封装下 JSon 的类: package com.lwz.wx.bean. ...

  3. h5 修改title 微信_微信公众号客服消息不限次数推送如何设置?

    在公众平台发送客服消息,只能通过消息管理功能实现,仅支持一个个粉丝单独发送文本信息,如果想要实现更多功能效果,可以使用微号帮平台的48小时信息推送功能实现,或者通过公众号平台的接口编程开发实现功能,都 ...

  4. Java实现微信公众号客服功能和本地联调

    Java实现微信公众号客服功能 微信公众平台设置 生产环境 公众号 设置 [开发]–> [基本配置]–> [服务器配置] 注: a.服务器地址(URL) 是开发者用来接收微信消息和事件的接 ...

  5. 自助微信公众号客服提醒功能开发的实现

    本周我公司的技术人员做了一个有技术含量的一个新功能:客服功能.此功能主要用于微信公众号客服提醒,比如客户的商家认证审核通过,用户购买商品成功等功能提醒,可以有效减少网站项目开发所必要的资金节约. 1. ...

  6. 微信公众号客服系统消息能即时提醒吗?

    微信公众号的客服系统,当有用户在后台留言的时候,网页版客服系统只能通过提示声音来判断,不会弹出消息提醒.所以只能采用戴耳机安音响这种方式了嘛?当然不是,你需要的是一款可以消息即时提醒的微信公众号客服系 ...

  7. 怎么在一台电脑登录多个微信公众号客服-微信公众号使用教程25

    微信公众号可以设置100个微信客服人员, 如果每台电脑只登录一个客服人员, 就需要100台电脑, 无疑这样极大的提高了公司的人力成本和物资成本! 那么有没有什么方法, 可以在一台电脑上登录多个微信客服 ...

  8. 微信公众号客服系统怎么生成能追踪效果的二维码?

    想要做好微信公众号的运营,专业的技能少不了,但是也要具有善于使用工具的能力,正所谓"工欲善其事必先利其器",一款好的客服系统,不但可以方便我们进行客户接待,还能帮助我们生分析公众号 ...

  9. 微信公众号客服功能如何开通?

    微信公众号客服功能如何使用,很多人想要通过公众号推广自己的产品,但是不知道该如何使用客服功能,其实很简单,在公众号后台就可以设置 首先登陆微信公众号进入公众号后台 然后点击"添加功能插件&q ...

最新文章

  1. SVN版本管理系统的安装 CentOS + Subversion + Apache + Jsvnadmin
  2. 感谢有你们,架构师修行之路!
  3. Linux diffstat命令
  4. 1亿以内素数的个数_算法|找出给定范围的所有素数
  5. activiti报错ProcessEngines.getDefaultProcessEngine()为null
  6. ipsec穿越NAT功能的配置
  7. python贝叶斯网络预测模型_概率图模型之:贝叶斯网络
  8. python编辑数学公式_最好用的文字与公式编辑器,这套数学笔记神器送给你
  9. 电机控制进阶3——PID串级控制(附全套代码下载)
  10. dorado 7 注意总结
  11. #微积分#正项级数收敛性判别方法
  12. 解密为何 Golang 能从众多语言中脱颖而出
  13. 计算机考研方向哪个好考,2022考研:计算机专业考研选择哪个方向比较好就业?...
  14. A feature-supervised generative adversarial network for environmental monitoring during hazy days
  15. ARCGIS 栅格转点操作步骤
  16. 电子书搜索引擎,快速寻找和下载电子书,搞定99.9%的电子书资源!
  17. Python手撸机器学习系列(十五):简单神经网络
  18. OBS美颜滤镜插件,美白、瘦脸....
  19. VR市场巨头云集,这家公司异军突起成头号玩家
  20. 高可用集群(HAC)

热门文章

  1. centOS 使用 yum 安装 Redis
  2. 处事22计、心态决定你的人生(每天必读)、伤心时要读的50句话和人的基本礼仪(保证你能学到不少东西)
  3. xp系统如何运行服务器,全面理解应用Windows XP系统的自动运行
  4. NOMA上下行如何解码
  5. 【Python成长之路】破解Boss直聘网站滑块验证
  6. Java中使用for循环打印直角三角形,倒立直角三角形,等腰三角形,平行四边形,菱形等
  7. A、diagrams
  8. 在Mac中PDF转图片自动化操作步骤
  9. 微型计算机 移动硬盘,超跑俱乐部 USB 3.0移动硬盘横向评测
  10. My+first+project—ZBG(zoomeye+batch+gather)