1、客服消息功能概述在頁面中使用 contact-button/ 可以顯示進入客服會話按鈕。當用戶在客服會話發送消息(或進行某些特定的用戶操作引發的事件推送時),微信服務器會將消息(或事件 ...
在頁面中使用 <contact-button/> 可以顯示進入客服會話按鈕。
當用戶在客服會話發送消息(或進行某些特定的用戶操作引發的事件推送時),微信服務器會將消息(或事件)的數據包(JSON或者XML格式)POST請求開發者填寫的URL。開發者收到請求后可以使用發送客服消息接口進行異步回復。
微信服務器在將用戶的消息發給小程序的開發者服務器地址(開發設置處配置)后,微信服務器在五秒內收不到響應會斷掉連接,并且重新發起請求,總共重試三次,如果在調試中,發現用戶無法收到響應的消息,可以檢查是否消息處理超時。關于重試的消息排重,有msgid的消息推薦使用msgid排重。事件類型消息推薦使用FromUserName + CreateTime 排重。
服務器收到請求必須做出下述回復,這樣微信服務器才不會對此作任何處理,并且不會發起重試,否則,將出現嚴重的錯誤提示。詳見下面說明:
1、直接回復success(推薦方式)
2、直接回復空串(指字節長度為0的空字符串,而不是結構體中content字段的內容為空)
一旦遇到以下情況,微信都會在小程序會話中,向用戶下發系統提示“該小程序客服暫時無法提供服務,請稍后再試”:
1、開發者在5秒內未回復任何內容
2、開發者回復了異常數據
具體可參考https://mp.weixin.qq.com/debug/wxadoc/introduction/custom.html#網頁版客服工具
登錄https://mp.weixin.qq.com
開發者提交信息后,微信服務器將發送GET請求到填寫的服務器地址URL上,GET請求攜帶參數如下表所示:
/**
* 檢驗signature對請求進行校驗
*/
function checkSignature(params){
//token 就是自己填寫的令牌
var key=[token, params.timestamp, params.nonce].sort().join('');
//將token (自己設置的) 、timestamp(時間戳)、nonce(隨機數)三個參數進行字典排序
var sha1 = crypto.createHash('sha1');
//將上面三個字符串拼接成一個字符串再進行sha1加密
sha1.update(key);
return sha1.digest('hex') === params.signature;
//將加密后的字符串與signature進行對比,若成功,返回echostr
}
<!--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>
請參考手把手教你開發微信小程序之模版消息中獲取 access_token
當用戶和小程序客服產生特定動作的交互時(具體動作列表請見下方說明),微信將會把消息數據推送給開發者,開發者可以在一段時間內(目前修改為48小時)調用客服接口,通過POST一個JSON數據包來發送消息給普通用戶。此接口主要用于客服等有人工消息處理環節的功能,方便開發者為用戶提供更加優質的服務。
目前允許的動作列表如下,不同動作觸發后,允許的客服接口下發消息條數和下發時限不同。下發條數達到上限后,會收到錯誤返回碼,具體請見返回碼說明頁:
接口調用請求說明:
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"
}
}
發送圖片消息
{
"touser":"OPENID",
"msgtype":"image",
"image":
{
"media_id":"MEDIA_ID"
}
}
參數說明
返回碼說明
<!-- 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) {
//這個access_token需要自己維護
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': {//用戶在客服會話中發送文本消息
await sendTextMessage("我知道了", data, access_token);
break;
}
case 'image': { //用戶在客服會話中發送圖片消息
await sendImageMessage(data.MediaId, data, access_token);
break;
}
case 'event': {
console.log('event');
var content = '';
if (data.Event == 'user_enter_tempsession'){ //用戶在小程序“客服會話按鈕”進入客服會話,在聊天框進入不會有此事件
await sendTextMessage("您有什么問題嗎?", data, access_token);
}else if (data.Event == 'kf_create_session'){ //網頁客服進入回話
console.log('網頁客服進入回話');
}
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);
}
});
}