文章目录
- 一、前提
- 1-1、接收对方的消息
- 1-2、发送消息给对方
- 1-3、消息推送机制
- 二、直接后台(单个服务)
- 2-1、业务图
- 三、直接后台(多个服务)
- 3-1、业务图
- 四、转接后台(单个服务)
- 4-1、业务图
- 五、转接后台(多个服务)
- 5-1、业务图
- 六、其它
一、前提
消息的对话是由两部分组成一个发送消息给对方,一个接收到对方的消息
1-1、接收对方的消息
在开发之前,我们需要给微信提供接口,这个接口支持Get和Post请求,以后微信后台和我们服务就是通过这个接口去沟通的。
在填写接口的时候,微信会去调用你接口的Get方法验证: 因为可能有伪造请求,所以每次你都要在业务进行前进行验证,这个请求是否合法,具体参考这里:https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Access_Overview.html
代码如下:
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/portal")
public class WxHandler {
@GetMapping(produces = "text/plain;charset=utf-8")
public String authGet(
@RequestParam(name = "signature", required = false) String signature,
@RequestParam(name = "timestamp", required = false) String timestamp,
@RequestParam(name = "nonce", required = false) String nonce,
@RequestParam(name = "echostr", required = false) String echostr) {
// 1、对数据进行进行校验
return echostr;
}
@PostMapping(produces = "application/xml; charset=UTF-8")
public String post(@RequestBody String requestBody,
@RequestParam("signature") String signature, @RequestParam("timestamp") String timestamp,
@RequestParam("nonce") String nonce, @RequestParam("openid") String openid,
@RequestParam(name = "encrypt_type", required = false) String encType,
@RequestParam(name = "msg_signature", required = false) String msgSignature) throws InterruptedException {
// 1、对数据进行进行校验
// 2、业务处理
// 3、注意如果在5s内没有收到回复,会重试三次,还是失败后就会告知用户,该公众号服务中断
return "";
}
}
注意如果在5s内没有收到回复,会重试三次,还是失败后就会告知用户,该公众号服务中断
上面post请求里面的requestBody就包含了用户的消息内容和用户信息,我们就可以进行业务处理了。
我们提供的这个接口需要外网,我们可以借助:ngrok
不过现在正式公众号好像屏蔽了这个,测试公众号还可以用
1-2、发送消息给对方
自定义客服是基于微信提供的回复用户消息接口触发的,也就是用户触发了某个动作后,48小时内我们可以对这个消息进行回复。
目前支持的动作
- 用户发送信息
- 点击自定义菜单(仅有点击推事件、扫码推事件、扫码推事件且弹出“消息接收中”提示框这3种菜单类型是会触发客服接口的)
- 关注公众号
- 扫描二维码
- 支付成功
然后我们就可以多次调用发消息接口进行消息发送了,目前限制一日50w次调用,每个月可以有10次清空的机会。
全部类型消息接口地址
这里有一个基于微信操作封装好的框架,比如上面的发消息,如果使用了这个框架就可以这样写
@GetMapping("/fun")
public boolean String() throws WxErrorException {
WxMpKefuMessage message = new WxMpKefuMessage();
message.setToUser("o2tmFv6nFgxPzbYt4fqlgvzyaL8s");
message.setMsgType("text");
message.setContent("等待客服接入");
return weixinService.getKefuService().sendKefuMessage(message);
}
这个框架封装的很好,功能很强大,文档地址:https://github.com/Wechat-Group/WxJava
1-3、消息推送机制
下面的业务实现都是基于WebSocket技术进行数据的交互,不懂的可以先去看看。
基于WebSocket实现Web端聊天系统
二、直接后台(单个服务)
2-1、业务图
当用户消息来了之后,指定一个客服和这个用户建立连接,客服和客户的连接session全部都在一个服务器上面,直接业务处理就好了。
三、直接后台(多个服务)
3-1、业务图
四、转接后台(单个服务)
可能有的人不太理解什么是转接后台,比如我现在所做的业务,微信公众号直接后台(我们称之为微厅),我们的微厅只提供缴费、留言、办理业务等事情。
我们有一个专门的客服工单系统,有专门的客服去提供对客户的支持,所以我们的业务微信聊天功能当然也是应该做在这个地方。
但是因为微信后台地址只能绑定一个(这个也很好理解),所以我们的微厅接收到消息之后要把消息推送到我们的客服工单系统,我称之为转接后台。
4-1、业务图
五、转接后台(多个服务)
5-1、业务图
除去微信和前端,我们主要是两种服务(微厅和客服工单都是分布式的),其中的难点是消息的消费,有两种做法:
- 微厅做,微厅可以实现每个消息精准的投放到对应的服务器(使用redis分布式缓存,数据共享,可以知道每个客服与哪个机器建立连接)
- 工单做,已经建立连接的消息使用广播消费,这样微厅就不需要判断了。
集群消费:当使用集群消费模式时,MQ 认为任意一条消息只需要被集群内的任意一个消费者处理即可。
广播消费:当使用广播消费模式时,MQ 会将每条消息推送给集群内所有注册过的客户端,保证消息至少被每台机器消费一次。
六、其它
至于客户怎么和客服建立连接,这个就要看具体的业务逻辑了,当然了总的来说是要均摊的。