手把手教你開(kāi)發(fā)微信小程序之客服消息

1、客服消息功能概述


  • 在頁(yè)面中使用 <contact-button/> 可以顯示進(jìn)入客服會(huì)話按鈕。

  • 當(dāng)用戶在客服會(huì)話發(fā)送消息(或進(jìn)行某些特定的用戶操作引發(fā)的事件推送時(shí)),微信服務(wù)器會(huì)將消息(或事件)的數(shù)據(jù)包(JSON或者XML格式)POST請(qǐng)求開(kāi)發(fā)者填寫的URL。開(kāi)發(fā)者收到請(qǐng)求后可以使用發(fā)送客服消息接口進(jìn)行異步回復(fù)。

  • 微信服務(wù)器在將用戶的消息發(fā)給小程序的開(kāi)發(fā)者服務(wù)器地址(開(kāi)發(fā)設(shè)置處配置)后,微信服務(wù)器在五秒內(nèi)收不到響應(yīng)會(huì)斷掉連接,并且重新發(fā)起請(qǐng)求,總共重試三次,如果在調(diào)試中,發(fā)現(xiàn)用戶無(wú)法收到響應(yīng)的消息,可以檢查是否消息處理超時(shí)。關(guān)于重試的消息排重,有msgid的消息推薦使用msgid排重。事件類型消息推薦使用FromUserName + CreateTime 排重。

  • 服務(wù)器收到請(qǐng)求必須做出下述回復(fù),這樣微信服務(wù)器才不會(huì)對(duì)此作任何處理,并且不會(huì)發(fā)起重試,否則,將出現(xiàn)嚴(yán)重的錯(cuò)誤提示。詳見(jiàn)下面說(shuō)明:

    1、直接回復(fù)success(推薦方式)
    2、直接回復(fù)空串(指字節(jié)長(zhǎng)度為0的空字符串,而不是結(jié)構(gòu)體中content字段的內(nèi)容為空)
    
  • 一旦遇到以下情況,微信都會(huì)在小程序會(huì)話中,向用戶下發(fā)系統(tǒng)提示“該小程序客服暫時(shí)無(wú)法提供服務(wù),請(qǐng)稍后再試”:

    1、開(kāi)發(fā)者在5秒內(nèi)未回復(fù)任何內(nèi)容
    2、開(kāi)發(fā)者回復(fù)了異常數(shù)據(jù)
    
  • 小程序客服消息界面效果展示


    小程序客服消息列表展示
點(diǎn)擊小程序客服消息進(jìn)入的界面
小程序客服消息聊天界面
小程序客服消息聊天界面右上角按鈕點(diǎn)擊
點(diǎn)擊自己小程序按鈕進(jìn)入的界面

2、網(wǎng)頁(yè)版客服工具

具體可參考https://mp.weixin.qq.com/debug/wxadoc/introduction/custom.html#網(wǎng)頁(yè)版客服工具

3、客服消息功能具體實(shí)現(xiàn)


  • 消息推送配置

  • 填寫服務(wù)器配置

登錄https://mp.weixin.qq.com

點(diǎn)擊設(shè)置

消息推送配置

消息推送配置

  • 驗(yàn)證消息的確來(lái)自微信服務(wù)器

開(kāi)發(fā)者提交信息后,微信服務(wù)器將發(fā)送GET請(qǐng)求到填寫的服務(wù)器地址URL上,GET請(qǐng)求攜帶參數(shù)如下表所示:


參數(shù)詳解
/**
 *  檢驗(yàn)signature對(duì)請(qǐng)求進(jìn)行校驗(yàn)
 */
function checkSignature(params){
    //token 就是自己填寫的令牌
    var key=[token, params.timestamp, params.nonce].sort().join('');
    //將token (自己設(shè)置的) 、timestamp(時(shí)間戳)、nonce(隨機(jī)數(shù))三個(gè)參數(shù)進(jìn)行字典排序
    var sha1 = crypto.createHash('sha1');
    //將上面三個(gè)字符串拼接成一個(gè)字符串再進(jìn)行sha1加密
    sha1.update(key);

    return sha1.digest('hex') === params.signature;
    //將加密后的字符串與signature進(jìn)行對(duì)比,若成功,返回echostr
}
  • 小程序界面實(shí)現(xiàn)

  • contact-button

客服會(huì)話按鈕,用于在頁(yè)面上顯示一個(gè)客服會(huì)話按鈕,用戶點(diǎn)擊該按鈕后會(huì)進(jìn)入客服會(huì)話。


屏幕快照 2017-03-27 下午4.45.51.png
<!--index.wxml-->
<view class="container">
  <view bindtap="bindViewTap" class="userinfo">
    <image class="userinfo-avatar" src="{{userInfo.avatarUrl}}" background-size="cover"></image>
    <text class="userinfo-nickname">{{userInfo.nickName}}</text>
  </view>
  <view class="user motto">
     <contact-button type="default-light" size="30" session-from="weapp" class="guest-button">
    </contact-button>
  </view>
</view>
  • contact-button只有2中類型:圖標(biāo)部分無(wú)法改變
default-light

default-dark
  • 服務(wù)器接收消息事件

  • 進(jìn)入會(huì)話事件

用戶在小程序“客服會(huì)話按鈕”進(jìn)入客服會(huì)話時(shí)將產(chǎn)生如下數(shù)據(jù)包:
{
"ToUserName": "toUser",
"FromUserName": "fromUser",
"CreateTime": 1482048670,
"MsgType": "event",
"Event": "user_enter_tempsession",
"SessionFrom": "sessionFrom"
}


參數(shù)說(shuō)明
  • 文本消息

用戶在客服會(huì)話中發(fā)送文本消息時(shí)將產(chǎn)生如下數(shù)據(jù)包:
{
"ToUserName": "toUser",
"FromUserName": "fromUser",
"CreateTime": 1482048670,
"MsgType": "text",
"Content": "this is a test",
"MsgId": 1234567890123456
}


參數(shù)說(shuō)明
  • 圖片消息

用戶在客服會(huì)話中發(fā)送圖片消息時(shí)將產(chǎn)生如下數(shù)據(jù)包:
{
"ToUserName": "toUser",
"FromUserName": "fromUser",
"CreateTime": 1482048670,
"MsgType": "image",
"PicUrl": "this is a url",
"MediaId": "media_id",
"MsgId": 1234567890123456
}


參數(shù)說(shuō)明
  • 網(wǎng)頁(yè)版客服工具進(jìn)入會(huì)話事件

用戶在小程序“客服會(huì)話按鈕”進(jìn)入客服會(huì)話時(shí)將產(chǎn)生如下數(shù)據(jù)包:
{
"ToUserName": "toUser",
"FromUserName": "fromUser",
"CreateTime": 1482048670,
"MsgType": "event",
"Event": "kf_create_session",
"KfAccount": "kf2001@gh_93228be5b792"
}

參數(shù)說(shuō)明
  • 獲取 access_token

請(qǐng)參考手把手教你開(kāi)發(fā)微信小程序之模版消息中獲取 access_token

  • 接收事件并回復(fù)消息

  • 功能概述

當(dāng)用戶和小程序客服產(chǎn)生特定動(dòng)作的交互時(shí)(具體動(dòng)作列表請(qǐng)見(jiàn)下方說(shuō)明),微信將會(huì)把消息數(shù)據(jù)推送給開(kāi)發(fā)者,開(kāi)發(fā)者可以在一段時(shí)間內(nèi)(目前修改為48小時(shí))調(diào)用客服接口,通過(guò)POST一個(gè)JSON數(shù)據(jù)包來(lái)發(fā)送消息給普通用戶。此接口主要用于客服等有人工消息處理環(huán)節(jié)的功能,方便開(kāi)發(fā)者為用戶提供更加優(yōu)質(zhì)的服務(wù)。

目前允許的動(dòng)作列表如下,不同動(dòng)作觸發(fā)后,允許的客服接口下發(fā)消息條數(shù)和下發(fā)時(shí)限不同。下發(fā)條數(shù)達(dá)到上限后,會(huì)收到錯(cuò)誤返回碼,具體請(qǐng)見(jiàn)返回碼說(shuō)明頁(yè):


屏幕快照 2017-03-27 下午5.42.15.png
  • 客服接口-發(fā)消息
  • 接口調(diào)用請(qǐng)求說(shuō)明:

    http請(qǐng)求方式: POST
    https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=ACCESS_TOKEN
    
  • 各消息類型所需的JSON數(shù)據(jù)包如下:
    發(fā)送文本消息

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

發(fā)送圖片消息

{
    "touser":"OPENID",
    "msgtype":"image",
    "image":
    {
      "media_id":"MEDIA_ID"
    }
}

參數(shù)說(shuō)明


參數(shù)說(shuō)明

返回碼說(shuō)明


返回碼說(shuō)明
  • 代碼實(shí)現(xiàn)
<!-- ih_request.js -->
const request = require('request');
var ih_request = {};
module.exports = ih_request;
ih_request.get = async function(option){
    var res = await req({
        url: option.url,
        method: 'get'
    });
    res.result?option.success(res.msg):option.error(res.msg);
}
<!-- wx_sendMessage.js -->
var router = require('koa-router')();
const request = require('../script/ih_request');
router.post('/', async function (ctx, next) {
    //這個(gè)access_token需要自己維護(hù)
    var access_token = 'gOyUImFWLoCWKZfssu9ompMQ7a4UR2npNx4ziHHMMzxjuQzD_XdCQu1UJwcxBQCbUl6owBdRqXk-QjagYzyA5Fb8bgCKuCkO63nKSPwy2ESSYwLoo1bInlg4UMOi2ToGLENaABAATC';
    var body = 'success';
    console.log(ctx.request.body);
    if (ctx.request.body.isCheck){
        var checkResult = checkSignature({
            'signature' : ctx.request.body.signature,
            'timestamp' : ctx.request.body.timestamp,
            'nonce' : ctx.request.body.nonce
        });
        body = checkResult?ctx.request.body.echostr :'err signature';
    }else {
        var data = JSON.parse(ctx.request.body.data);
        switch (data.MsgType){
            case 'text': {//用戶在客服會(huì)話中發(fā)送文本消息
                await sendTextMessage("我知道了", data, access_token);
                break;
            }
            case 'image': { //用戶在客服會(huì)話中發(fā)送圖片消息
                await sendImageMessage(data.MediaId, data, access_token);
                break;
            }
            case 'event': {
                console.log('event');
                var content = '';
                if (data.Event == 'user_enter_tempsession'){  //用戶在小程序“客服會(huì)話按鈕”進(jìn)入客服會(huì)話,在聊天框進(jìn)入不會(huì)有此事件
                    await sendTextMessage("您有什么問(wèn)題嗎?", data, access_token);
                }else if (data.Event == 'kf_create_session'){ //網(wǎng)頁(yè)客服進(jìn)入回話
                   console.log('網(wǎng)頁(yè)客服進(jìn)入回話');
                }
                break;
            }
        }
    }
    console.log('end');
    ctx.body = body;
});

async function sendTextMessage(content, data, access_token){
    await request.postJson({
        url: 'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token='+access_token,
        body: {
            touser:data.FromUserName,
            msgtype:"text",
            text:
            {
                content:content
            }
        },
        success: function(res){
            console.log(res);
        },
        error: function(err){
            console.log(err);
        }
    });
}

async function sendImageMessage(media_id, data, access_token){
    await request.postJson({
        url: 'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token='+access_token,
        body: {
            touser:data.FromUserName,
            msgtype:"image",
            image:
            {
                media_id:media_id
            }
        },
        success: function(res){
            console.log(res);
        },
        error: function(err){
            console.log(err);
        }
    });
}

4、最后


如何大家看了文章還有不懂或者其他問(wèn)題,歡迎私信我或者評(píng)論

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 1、開(kāi)啟公眾號(hào)開(kāi)發(fā)者模式 公眾平臺(tái)的技術(shù)文檔目的為了簡(jiǎn)明扼要的交代接口的使用,語(yǔ)句難免苦澀難懂,甚至對(duì)于不同的讀者...
    good7758閱讀 1,548評(píng)論 0 1
  • 結(jié)合之前的Python模擬登錄爬取Mysise學(xué)生管理系統(tǒng)的信息,在新浪SAE服務(wù)器上面做了一個(gè)獲取學(xué)生管理系統(tǒng)的...
    秋雨仲夏閱讀 1,940評(píng)論 0 1
  • 一、公眾號(hào)介紹 微信公眾號(hào)分類 訂閱號(hào):主要偏于為用戶傳達(dá)資訊(類似報(bào)紙雜志),認(rèn)證前后都是每天只可以群發(fā)一條消息...
    小花的胖次閱讀 6,589評(píng)論 3 37
  • 點(diǎn)擊查看原文 Web SDK 開(kāi)發(fā)手冊(cè) SDK 概述 網(wǎng)易云信 SDK 為 Web 應(yīng)用提供一個(gè)完善的 IM 系統(tǒng)...
    layjoy閱讀 13,946評(píng)論 0 15
  • “我八歲那年收到的唯一一份生日禮物是一串銅鈴,就是我現(xiàn)在書包上掛著的這串?!?“哦,然后呢?!?看著閨蜜漫不經(jīng)心的...
    絲絨小貓閱讀 438評(píng)論 0 2