手把手教你用uniCloud云函数开发微信客服消息机器人

2022-03-03 12:20:34 浏览数 (1)

消息推送配置

首先打开微信小程序的管理后台,在侧边栏找到开发开发管理

在开发管理的开发设置标签里找到消息推送并开启它

开启后我们就可以看到消息推送的配置界面了

我们回到咱们的uniCloud项目,新建一个云函数,命名为xcxcontact(命名可以自己定)

创建好之后,云函数的默认代码如下,暂时我们什么都不写,直接上传部署

代码语言:javascript复制
'use strict';
exports.main = async (event, context) => {
  //event为客户端上传的参数
  console.log('event : ', event)
  
  //返回数据给客户端
  return event
};

上传成功之后,在uniCloud云函数的管理后台找到这个云函数,点击详情

在云函数URL化里点击编辑按钮,在Path的输入框里输入/xcxcontact,注意必须斜杠开头

点击保存,然后复制这个URL化后的云函数的路径,将其粘贴到客服消息推送配置的URL(服务器地址)中

代码语言:javascript复制
https://5ccdce58-43fd-4ebf-b4d1-73664467bc69.bspapp.com/xcxcontact

将推送配置设置成下面的样子

  • URL 开发者用来接收微信消息和事件的接口 URL。开发者所填写的URL 必须以 http:// 或 https:// 开头,分别支持 80 端口和 443 端口。
  • Token 可由开发者可以任意填写,用作生成签名(该 Token 会和接口 URL 中包含的 Token 进行比对,从而验证安全性)。
  • EncodingAESKey 由开发者手动填写或随机生成,将用作消息体加解密密钥。仅当消息加密方式选择安全模式时才需要。

设置好之后点击提交会发现提交失败,因为我们并没有按照要求返回验证消息。但这个时候我们可以查看一下云函数的日志,发现收到了一个请求。

在event的queryStringParameters里是微信服务器发过来的用于验证的信息。

通过验证

要提交,首先得要通过验证。

如果不在意消息来源的安全问题,可以在云函数的里直接返回event.queryStringParameters.echostr就可以通过校验

代码语言:javascript复制
'use strict';
exports.main = async (event, context) => {
  //event为客户端上传的参数
  console.log('event : ', event)
  
  //返回数据给客户端
  return event.queryStringParameters.echostr;
};

如果要校验这个信息,也很简单

  1. 将token、timestamp、nonce三个参数进行字典序排序
  2. 将三个参数字符串拼接成一个字符串进行sha1加密
  3. 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信

代码如下

代码语言:javascript复制
'use strict';
//npm install sha1
const sha1 = require("sha1");
const token = "123";

function verifyMSGSender(params){
  const mysignature = sha1([token,params.timestamp,params.nonce].sort().join(""));
  
  console.log(mysignature===params.signature?"校验通过":"校验失败");
  
  if(mysignature===params.signature)return true;
  else return false;
}

exports.main = async (event, context) => {
  //event为客户端上传的参数
  if(!verifyMSGSender(event.queryStringParameters))return "来源校验失败";
  //校验通过后,下面这行返回echostr的代码注释掉
  else return event.queryStringParameters.echostr;
  
  //返回数据给客户端
  return;
};

验证通过后,开发设置消息推送会变成这样(一个月只能改3次有点坑)

注意:验证通过之后,就不需要返回echostr了。

代码语言:javascript复制
//校验通过后,下面这行返回echostr的代码注释掉
else return event.queryStringParameters.echostr;

处理不同类型的消息

微信官方文档地址:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/customer-message/receive.html

当用户在小程序里发起客服消息时,云函数的日志呈现如下

消息的内容被转成json格式字符串塞到了POST请求的body中,我们解析后直接取就可以了

代码语言:javascript复制
const receiveMsg = JSON.parse(event.body);

根据用户的行为,会有以下几种不同的消息类型,下面仅展示JSON格式,并将重点参数做了注释

文本消息

用户在客服会话中发送文本消息时将产生如下数据包:

代码语言:javascript复制
{

  "ToUserName": "toUser",

  "FromUserName": "fromUser",//客服消息发起者的openid

  "CreateTime": 1482048670,

  "MsgType": "text",//该条消息类型

  "Content": "this is a test",

  "MsgId": 1234567890123456

}

图片消息

用户在客服会话中发送图片消息时将产生如下数据包:

代码语言:javascript复制
{

  "ToUserName": "toUser",

  "FromUserName": "fromUser",//客服消息发起者的openid

  "CreateTime": 1482048670,

  "MsgType": "image",//该条消息类型

  "PicUrl": "this is a url",

  "MediaId": "media_id",//微信媒体资源id

  "MsgId": 1234567890123456

}

小程序卡片消息

小程序端button参数

代码语言:javascript复制
<button 
  size="mini" 
  type="primary" 
  :plain="true" 
  open-type="contact" 
  :session-from="" 
  :show-message-card="true" 
  :send-message-title="title">
  查看
 </button>

用户在客服会话中发送小程序卡片消息时将产生如下数据包:

代码语言:javascript复制
{

  "ToUserName": "toUser",

  "FromUserName": "fromUser",//客服消息发起者的openid

  "CreateTime": 1482048670,

  "MsgType": "miniprogrampage",//该条消息类型

  "MsgId": 1234567890123456,

  "Title":"title",//小程序卡片标题

  "AppId":"appid",//小程序appid

  "PagePath":"path",//小程序卡片跳转页面

  "ThumbUrl":"",//小程序卡片缩略图

  "ThumbMediaId":""

}

进入会话事件

用户在小程序“客服会话按钮”进入客服会话时将产生如下数据包:

代码语言:javascript复制
{

  "ToUserName": "toUser",

  "FromUserName": "fromUser",//客服消息发起者的openid

  "CreateTime": 1482048670,

  "MsgType": "event",//该条消息类型

  "Event": "user_enter_tempsession",

  "SessionFrom": "sessionFrom"//开发者在客服会话按钮设置的 session-from 属性

}

回复客服消息

微信官方文档:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/customer-message/customerServiceMessage.send.html#method-http

代码语言:javascript复制
POST https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=ACCESS_TOKEN

那么首先我们要获取access_token

代码语言:javascript复制
const res1 = await uniCloud.httpclient.request("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" appId "&secret=" appSecret,{dataType:"json"});
//res.data.access_token

然后请求发送客服消息的接口

代码语言:javascript复制
const access_token = res1.data.access_token
const res2 = await uniCloud.httpclient.request("https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=" access_token,{
    method:"POST",
    headers:{
      "Content-Type":"application/json"
    },
    dataType:"json",
    data:{
      touser:touser,//接收此消息用户的openid
      msgtype:"text",//此消息的类型
      text:{
        content:"回复的文本内容",
      }
    }
});

回复的消息类型可以是以下几种

  • text
  • image
代码语言:javascript复制
msgtype:"image",//图片消息
image:{
  media_id:"媒体资源的id",//这个id需要通过媒体资源列表获得,或通过接口上传媒体资源时获得
}
  • link
代码语言:javascript复制
msgtype:"link",//图文消息,网页卡片消息
link:{
  title:"",
  description:"",
  url:"",
  thumb_url:""
}
  • miniprogrampage
代码语言:javascript复制
msgtype:"miniprogrampage",//小程序卡片消息
miniprogrampage:{
  title:"",
  pagepath:"",//小程序卡片页面路径
  thumb_media_id:""//这个id需要通过媒体资源列表获得,或通过接口上传媒体资源时获得
}

一个调皮的机器人

有了以上基础,我们现在来对接一下文本消息,并完成一个简单的客服消息机器人。

这是一个调皮的机器人,它会把所有用户发来的消息反转后再发回给用户

下面是本云函数的完整代码

代码语言:javascript复制
'use strict';

const sha1 = require("sha1");
const token = "123";

const appId = '';
const appSecret = '';

function verifyMSGSender(params){
  const mysignature = sha1([token,params.timestamp,params.nonce].sort().join(""));
  
  console.log(mysignature===params.signature?"校验通过":"校验失败");
  
  if(mysignature===params.signature)return true;
  else return false;
}

exports.main = async (event, context) => {
  //event为客户端上传的参数
  if(!verifyMSGSender(event.queryStringParameters))return "来源校验失败";
  //校验通过后,下面这行返回echostr的代码注释掉
  // else return event.queryStringParameters.echostr;
  
  const receiveMsg = JSON.parse(event.body);
  
  if(receiveMsg.MsgType==='text'){
    //一行代码反转文本
    var reply = receiveMsg.Content.split('').reverse().join('');
    
    const res1 = await uniCloud.httpclient.request("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" appId "&secret=" appSecret,{dataType:"json"});
    //res.data.access_token
    const access_token = res1.data.access_token
    const res2 = await uniCloud.httpclient.request("https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=" access_token,{
        method:"POST",
        headers:{
          "Content-Type":"application/json"
        },
        dataType:"json",
        data:{
          touser:receiveMsg.FromUserName,
          msgtype:"text",
          text:{
            content:reply,
          }
        }
    });
  }
  
  //返回数据给客户端
  return "success";
};


OK,这就是uniCloud云函数开发客服消息机器人的实战教程了,你可以在这个基础上对接比如天气预报查询接口,星座运势查询等等。

0 人点赞