Detailed Explanation of WeChat Mini Program Customer Service Message Server Sending Operation Function

1 Introduction

In order to enrich the service capabilities of Mini Programs and improve service quality, WeChat provides customer service messaging capabilities for Mini Programs, so that Mini Program users can communicate with Mini Program service providers conveniently and quickly.

2. Function introduction

Users can use the Mini Program's customer service message function to communicate with the Mini Program's customer service personnel.

There are two customer service message session entries:

1. In the applet: the developer adds a customer service message button component in the applet , and the user can call up the customer service session page in the applet and send a message to the applet;

2. The used Mini Program customer service messages will be aggregated and displayed in the WeChat session "Mini Program Customer Service Message" box. Users can view historical customer service messages outside the Mini Program and send messages to the Mini Program.

Conditions for sending customer service messages: the Mini Program user initiates a customer service session in the Mini Program or the user sends a message to the Mini Program customer service. For the specific sending time, validity period and limit on the number of messages, please refer to the Conditions for Sending Customer Service Messages

Customer service message type: currently supports text, picture, and mini program card type messages.

In order to meet the needs of Mini Program developers as much as possible, the Mini Program can send customer service messages in the following three ways: 1. Call the interface for sending customer service messages; 2. Use the customer service tools on the web; program.

3. Issuing condition description

When the user interacts with the Mini Program customer service with a specific action (see the description below for the specific action list), the Mini Program can send a customer service message to the user.

The list of currently allowed actions is as follows. After different actions are triggered, the number of messages allowed to be sent and the time limit for sending them are different. When the number of sent threads reaches the upper limit, an error code will be returned.

user action

Limit on the number of threads allowed

Release time limit

User sends message

5 pieces

48 hours

The number of customer service messages that can be sent is not accumulated. The above user actions will trigger the update of the number of messages that can be sent and the time limit for delivery. The limit is also updated with the maximum valid time.

4. Call the customer service message interface to send customer service messages

When the user sends a message to the Mini Program customer service, the WeChat server will POST the message (or event) data package (JSON or XML format) to the URL filled in by the developer. After receiving the request, the developer can call the interface for asynchronous reply.

If the customer service message permission set of the Mini Program has been authorized to the third-party platform, all customer service messages will be pushed to the server of the third-party platform, and will no longer be pushed to the developer's server or to the web version of the customer service tool

Fill in the message push configuration

Log in to the applet, enable the message push function in "Settings-Development Settings-Message Push" and complete the configuration of relevant information (including server address, Token, and encryption method, etc.).

After enabling and setting the server configuration, messages sent by users and event pushes required by developers will be forwarded by WeChat to the developer URL.

interface call

Mini Program Customer Service Message API Documentation

5. Case presentation

Related website:
Send customer service message: https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/kf-mgnt/kf-message/sendCustomMessage.html
Customer service function guide: https://developers.weixin.qq. com/miniprogram/introduction/custom.htmlServer
-mini program customer service news: https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/#%E5%B0%8F%E7%A8%8B%E5 %BA%8F%E5%AE%A2%E6%9C%8D
Applet message sdk: Link: https://pan.baidu.com/s/1ekDtfwfnegRngKOOGzMK1g Extraction code: n1tr
The framework uses yii2 as a case
<?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;
    }
}

Guess you like

Origin blog.csdn.net/zhoupenghui168/article/details/130198851