微信小程序客服消息服务端发送操作功能详解

2 篇文章 0 订阅

1.简介

为丰富小程序的服务能力,提高服务质量,微信为小程序提供客服消息能力,以便小程序用户可以方便快捷地与小程序服务提供方进行沟通。

2.功能介绍

用户可使用小程序客服消息功能,与小程序的客服人员进行沟通。

客服消息会话入口有两个:

1、小程序内:开发者在小程序内添加客服消息按钮组件,用户可在小程序内唤起客服会话页面,给小程序发消息;

2、已使用过的小程序客服消息会聚合显示在微信会话「小程序客服消息」盒子内,用户可以在小程序外查看历史客服消息,并给小程序发送消息。

客服消息下发条件:小程序用户在小程序内唤起客服会话或用户给小程序客服发送消息,具体下发时间有效期及消息条数限制见客服消息下发条件说明

客服消息类型:目前支持文本、图片、小程序卡片类型消息。

为尽量满足小程序开发者的需求,小程序可通过以下3种方式下发客服消息:1. 调用发送客服消息接口;2. 使用网页端客服工具;3. 使用移动端「客服小助手」小程序。

3.下发条件说明

当用户和小程序客服产生特定动作的交互时(具体动作列表请见下方说明),小程序可向用户下发客服消息。

目前允许的动作列表如下,不同动作触发后,允许下发消息条数和下发时限不同。下发条数达到上限后,会返回错误码。

用户动作

允许下发条数限制

下发时限

用户发送信息

5条

48小时

可发送客服消息条数不累加,上述用户动作会触发可下发条数及可下发时限的更新,可下发消息条数更新为当前可下发条数限制的最大值,有效下发时间限制也更新为最长有效时间。

4.调用客服消息接口发送客服消息

当用户给小程序客服发消息,微信服务器会将消息(或事件)的数据包(JSON或者XML格式)POST到开发者填写的URL。开发者收到请求后可以调用接口进行异步回复。

如小程序的客服消息权限集已授权给第三方平台,则所有的客服消息将推送到第三方平台的服务器,不再推送到开发者的服务器或推送到网页版客服工具

填写消息推送配置

登录小程序,在“设置-开发设置-消息推送”启用消息推送功能并完成相关信息配置(包括服务器地址、Token、及加密方式等)。

启用并设置服务器配置后,用户发送的消息以及开发者需要的事件推送,都将被微信转发至开发者URL中。

接口调用

小程序客服消息API文档

5.案例演示

相关网站:
发送客服消息: https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/kf-mgnt/kf-message/sendCustomMessage.html
客服功能指南: https://developers.weixin.qq.com/miniprogram/introduction/custom.html
服务端-小程序客服消息: https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/#%E5%B0%8F%E7%A8%8B%E5%BA%8F%E5%AE%A2%E6%9C%8D
小程序消息sdk:链接: https://pan.baidu.com/s/1ekDtfwfnegRngKOOGzMK1g 提取码: n1tr
框架以yii2为案例
<?php
/**
 * 微信消息回复
 */

namespace frontend\controllers;

use Yii;

/**
 * Class WxMsgController
 * @package frontend\controllers
 */
class WxMsgController extends BaseController
{
    /**
     * 入口
     * @throws \Exception
     */
    public function actionIndex()
    {
        //校验服务器地址URL
        if (isset($_GET['echostr'])) {
            $this->valid();
        } else {
            $this->responseMsg();
        }
    }

    /**
     * 校验
     */
    public function valid()
    {
        $echoStr = $_GET["echostr"];
        if ($this->checkSignature()) {
            header('content-type:text');
            echo $echoStr;
            exit;
        } else {
            echo $echoStr . '+++' . Yii::$app->params['payment.wx']['token'];
            exit;
        }
    }

    private function checkSignature()
    {
        $signature = $_GET["signature"];
        $timestamp = $_GET["timestamp"];
        $nonce = $_GET["nonce"];

        $token = Yii::$app->params['wx']['token']; // 小程序消息通知token
        $tmpArr = array($token, $timestamp, $nonce);
        sort($tmpArr, SORT_STRING);
        $tmpStr = implode($tmpArr);
        $tmpStr = sha1($tmpStr);

        if ($tmpStr == $signature) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 接受消息和事件:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/customer-message/receive.html
     * 发送消息:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/customer-message/customerServiceMessage.send.html
     * @throws \Exception
     */
    public function responseMsg()
    {
        //小程序相关sdk
        $dir = Yii::getAlias('@common/lib/wx-applet-service-crypto-php');
        require_once $dir . '/wxBizMsgCrypt.php';

        //获取微信服务端发送请求
        $postStr = file_get_contents('php://input');
        $timeStamp = $_GET["timestamp"];
        $msgSignature = $_GET["msg_signature"];
        $nonce = $_GET["nonce"];

        //微信相关配置
        $config = Yii::$app->params['wx'];
        //小程序应用ID
        $appId = $config['app_id'];
        //小程序消息通知 消息加密密钥
        $encodingAesKey = $config['encodingAESKey'];
        //小程序消息通知token
        $token = $config['token'];

        try {
            $pc = new \WXBizMsgCrypt($token, $encodingAesKey, $appId);
            // 第三方收到公众号平台发送的消息
            $msg = '';
            //校验
            $errCode = $pc->decryptMsg($msgSignature, $timeStamp, $nonce, $postStr, $msg);

            if ($errCode != 0) {
                throw new \Exception('in errCode: ' . $errCode);
            }

            $postObj = simplexml_load_string($msg, 'SimpleXMLElement', LIBXML_NOCDATA);
            if (!empty($msg) && is_object($postObj)) {
                $fromUsername = (string)$postObj->FromUserName;
                $createTime = (string)$postObj->CreateTime;
                $msgType = (string)$postObj->MsgType;
                $event = (string)$postObj->Event;
                if (!empty($msgType) && $msgType == 'text') {   //发送文本消息
                    // 发送文案
                    $content = '扫码,加我,咨询';
                    $data = array(
                        "touser" => $fromUsername,
                        "msgtype" => "text",
                        "text" => array("content" => $content)
                    );

                    $json = json_encode($data, JSON_UNESCAPED_UNICODE);  //php5.4+
                    $this->requestAPI($json);
                } elseif (!empty($msgType) && $msgType == 'image') {   //发送图片消息
                    // 发送图片
                    $imgurl = '/images/service_code.png'; //二维码,相对路径,修改为自己的
                    $media_id = $this->getMediaId($imgurl);  // 输入想要回复的图片消息的media_id
                    $data = array(
                        "touser" => $fromUsername,
                        "msgtype" => "image",
                        "image" => array("media_id" => $media_id)
                    );
                    $param = json_encode($data, JSON_UNESCAPED_UNICODE);  //php5.4以上版本才可使用
                    $this->requestAPI($param);
                } elseif (!empty($msgType) && $msgType == 'link') {   //用户发送图文链接
                    //构建向微信客服发送的参数
                    $text = [
                        'url' => "www.xxx.com",
                        'thumb_url' => 'thumb_url',
                        'title' => "测试",
                        'description' => "测试des",
                    ];
                    // 发送图文链接
                    $data = array(
                        "touser" => $fromUsername,
                        "msgtype" => "link",
                        "text" => $text
                    );

                    $json = json_encode($data, JSON_UNESCAPED_UNICODE);  //php5.4+
                    $this->requestAPI($json);
                } elseif (!empty($msgType) && $msgType == 'miniprogrampage') { //用户发送小程序卡片
                    //逻辑代码
                } elseif ($msgType == 'event' && $event == 'user_enter_tempsession') { //用户发送小程序卡片
                    //解决接收用户消息重复发送:腾讯那边迟迟接不到回音,就会重复请求,这样就会重复发三次客服消息
                    $key = sprintf("service_msg:%s:%s", $fromUsername, $createTime);
                    //判断redis中key是否存在
                    $redisUser = Yii::$app->redis_user;
                    if ($redisUser->exists($key)) {
                        exit;
                    }
                    $redisUser->set($key, 1);
                    $redisUser->expire($key, 15);
                    //逻辑代码
                }
            } else {
                throw new \Exception('in  empty msgType: ' . $msg);
                exit;
            }
        } catch (\Exception $e) {
            // 发送error文案
            $content = $e->getMessage();
            $data = array(
                "touser" => $fromUsername,
                "msgtype" => "text",
                "text" => array("content" => $content)
            );

            $json = json_encode($data, JSON_UNESCAPED_UNICODE);  //php5.4+
            $this->requestAPI($json);
            throw $e;
        }
    }

    /**
     * @param $param
     */
    public function requestApi($param, $type = 'json')
    {
        $access_token = $this->get_accessToken();
        /*
         * POST发送https请求客服接口api
         */
        $url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=" . $access_token;

        if ($type == 'xml') {
            //以'xml'格式发送post的https请求
            $header[] = "Content-type: text/xml";
            $curl = curl_init();
            curl_setopt($curl, CURLOPT_URL, $url);
            curl_setopt($curl, CURLOPT_POST, 1);
            if (!empty($param)) {
                curl_setopt($curl, CURLOPT_POSTFIELDS, $param);
            }
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
            $output = curl_exec($curl);
            if (curl_errno($curl)) {
                echo 'Errno' . curl_error($curl);//捕抓异常
            }
            curl_close($curl);
            if ($output == 0) {
                echo 'success';
            }
        } else {
            //以'json'格式发送post的https请求
            $curl = curl_init();
            curl_setopt($curl, CURLOPT_URL, $url);
            curl_setopt($curl, CURLOPT_POST, 1); // 发送一个常规的Post请求
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
            if (!empty($param)) {
                curl_setopt($curl, CURLOPT_POSTFIELDS, $param);
            }
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
            //curl_setopt($curl, CURLOPT_HTTPHEADER, $headers );
            $output = curl_exec($curl);
            if (curl_errno($curl)) {
                echo 'Errno' . curl_error($curl);//捕抓异常
            }
            curl_close($curl);
            if ($output == 0) {
                echo 'success';
            }
        }
    }

    /**
     * 获取上传图片的media_id
     * @param $imgurl
     * @return null
     */
    public function getMediaId($imgurl)
    {
        $mediaKey = 'media_key';
        $mediaId = Yii::$app->cache->get($mediaKey);
        if ($mediaId) {
            return $mediaId;
        }

        $token = $this->get_accessToken();
        $url = "https://api.weixin.qq.com/cgi-bin/media/upload?access_token={$token}&type=image";
        $ch1 = curl_init();
        $timeout = 10;
        $real_path = "{$_SERVER['DOCUMENT_ROOT']}$imgurl";//自动转成图片文件绝对路径,如果图片发送失败,检查PHP的$_SERVER['DOCUMENT_ROOT'的配置
        $data = array("media" => new \CURLFile("{$real_path}"));//php5.6(含)以上版本使用此方法
        curl_setopt($ch1, CURLOPT_URL, $url);
        curl_setopt($ch1, CURLOPT_POST, 1);
        curl_setopt($ch1, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch1, CURLOPT_CONNECTTIMEOUT, $timeout);
        curl_setopt($ch1, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch1, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch1, CURLOPT_POSTFIELDS, $data);
        $result = curl_exec($ch1);
        // echo $result;
        curl_close($ch1);
        if ($result) {
            $result = json_decode($result, true);
            Yii::$app->cache->set($mediaKey, $result['media_id'], 3600 * 21 * 3);

            return $result['media_id'];
        } else {
            return null;
        }
    }

    /**
     * 调用微信api,获取access_token,有效期7200s -xzz0704
     * @return mixed
     */
    public function get_accessToken()
    {
        //微信配置
        $config = Yii::$app->params['wx'];
        //小程序应用ID
        $appId = $config['app_id'];
        //小程序应用秘钥
        $secret = $config['applet_secret'];
        $tokenKey = "access_token";
        $access_token = Yii::$app->cache->get($tokenKey);
        if (!$access_token) {
            $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appId&secret=$secret";
            $res = json_decode($this->httpGet($url));
            $access_token = $res->access_token;
            if ($access_token) {
                Yii::$app->cache->set($tokenKey, $access_token, 7000);
            }
        }

        return $access_token;
    }

    private function httpGet($url)
    {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_TIMEOUT, 500);
        // 为保证第三方服务器与微信服务器之间数据传输的安全性,所有微信接口采用https方式调用,必须使用下面2行代码打开ssl安全校验。
        // 如果在部署过程中代码在此处验证失败,请到 http://curl.haxx.se/ca/cacert.pem 下载新的证书判别文件。
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, true);
        curl_setopt($curl, CURLOPT_URL, $url);

        $res = curl_exec($curl);
        curl_close($curl);

        return $res;
    }
}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值