前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >用微信来搞世界上最好的语言——消息收发SDK的实现

用微信来搞世界上最好的语言——消息收发SDK的实现

作者头像
一粒小麦
发布2019-07-18 17:09:08
8610
发布2019-07-18 17:09:08
举报
文章被收录于专栏:一Li小麦一Li小麦

在上一章中实现了一文本消息的互动。本章将在上一篇基础上完成开发。

微信的基础消息接口包括三个部分:接收普通消息、发送被动回复消息、接收事件消息

4.1 文本消息 <MsgType><![CDATA[text]]></MsgType>

一个公众号接收用户的文本消息包括

代码语言:javascript
复制
<xml>
    <ToUserName><![CDATA[接收方账号]]></ToUserName>
    <FromUserName><![CDATA[发送者的openid]]></FromUserName>
    <CreateTime>时间整型</CreateTime>
    <MsgType><![CDATA[text]]></MsgType>
    <Content><![CDATA[内容]></Content>
    <MsgId>消息id</MsgId> <!-消息64位 -->
</xml>

微信用户接收公众号的文本消息组织包括:

代码语言:javascript
复制
<xml>
    <ToUserName><![CDATA[接收方账号(收到的openid)]]></ToUserName>
    <FromUserName><![CDATA[发送者的openid]]></FromUserName>
    <CreateTime>时间整型</CreateTime>
    <MsgType><![CDATA[text]]></MsgType>
    <Content><![CDATA[我是内容]></Content>
    <MsgId>消息id</MsgId> <!-消息64位 -->
</xml>

4.2 图片消息

一个公众号接收用户的图片消息包括

代码语言:javascript
复制
<xml>
    <!-只列出不同-->
    <MsgType><![CDATA[image]]></MsgType>
    <PicUrl><![CDATA[http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token=10_5fQEan8J_3b09bXLjDaYFmjjKqjem8tD6om2oxyUF_zKIt5pEjp7xNU_KiCyWokEnN3QcklwVXWIEyh4qhN-7idad2TRsrHGVt9VBZCxeL7mhUapJ-iSE2owvuvBmOMk4gFwk_iVW0Qak9x9XJTiAIATFP&type=image]]></PicUrl>
    <MediaId><![CDATA[媒体id]]></MediaId>
</xml>

PicUrl就是图片地址。

媒体id可以从多媒体文件下载接口拉取。

一个公众号回复用户的图片消息包括:

代码语言:javascript
复制
<xml>
    <!-只列出不同-->
    <MsgType><![CDATA[image]]></MsgType>
    <Image>
        <MediaId><![CDATA[媒体id]]></MediaId>
    </Image>

    <MediaId><![CDATA[媒体id]]></MediaId>
</xml>

4.3 语音消息

语音消息的MsgType为:voice。

一个公众号接收用户的语音消息包括

代码语言:javascript
复制
<xml>
    <!-只列出不同-->
    <MsgType><![CDATA[voice]]></MsgType>
    <MediaId><![CDATA[xxxxxxxx]]></MediaId>
    <Format><![CDATA[amr/speex]]></Format>
    <Recognition><![CDAATA[]]></Recognition>

</xml>

一个公众号回复用户的语音消息包括:

代码语言:javascript
复制
<xml>
    <!-只列出不同-->
    <MsgType><![CDATA[voice]]></MsgType>
    <Voice>
        <MediaId><![CDATA[媒体id]]></MediaId>
    </Voice>


</xml>

4.4 视频消息

视频消息的MsgType为:video。

一个公众号接收用户的语音消息包括

代码语言:javascript
复制
<xml>
    <!-只列出不同-->
    <MsgType><![CDATA[video]]></MsgType>
    <MediaId><![CDATA[xxxxxxxx]]></MediaId>

    <ThumbMediaId><![CDATA[缩略图媒体id]]></ThumbMediaId> 

</xml>

一个公众号回复用户的语音消息包括:

代码语言:javascript
复制
<xml>
    <!-只列出不同-->
    <MsgType><![CDATA[video]]></MsgType>
    <Video>
        <MediaId><![CDATA[xxxx]]></MediaId>
        <ThumbMediaId><![CDATA[缩略图媒体id]]></ThumbMediaId>
        <Titile><![CDATA[标题]]></Titile>
        <Description><![CDATA[描述]]></Description>
    </Video>


</xml>

4.5 用户发送给公众号的地理位置消息

地理位置消息的MsgType为:location。

代码语言:javascript
复制
<xml>
    <!-只列出不同-->
    <MsgType><![CDATA[location]]></MsgType>
    <Location_X>纬度数字</Location_X>
    <Location_Y>经度数字</Location_Y>
    <Scale>放大倍数比如16</Scale>
    <Label><![CDATA[中国北京天安门]]></Label>

</xml>

4.6 用户发送给公众号的链接消息

链接消息的title为link

代码语言:javascript
复制
<xml>
    <!-只列出不同-->
    <MsgType><![CDATA[location]]></MsgType>
    <Titile><![CDATA[标题]]></Titile>
    <Description><![CDATA[描述]]></Description>
    <Url><![CDATA[url地址]]></Url>

</xml>

4.7 公众号发回用户的音乐消息

音乐消息的type为music。、

代码语言:javascript
复制
<xml>
    <!--只列出不同-->
    <MsgType><![CDATA[music]]></MsgType>
    <Music>
        <Title><![CDATA[最炫民族风]]></Title>
        <Description>
            <![CDATA[凤凰传奇]]>
        </Description>
        <!--音乐的一般链接和Hq(高品质)链接-->
        <MusicUrl><![CDATA[http://adasfasfasfwsgvwe.vas.vsdvs]]></MusicUrl>
        <HQMusicUrl><![CDATA[http://adasfasfasfwsgvwe.vas.vsdvs]]></HQMusicUrl>
    </Music>
</xml>

4.8 公众号发给用户的图文消息

图文可以分为单图文和多图文,显示方式基本是一样的。

代码语言:javascript
复制
<xml>
    <ToUserName><![CDATA[发送的微信账号]]></ToUserName>
    <FromUserName><![CDATA[收到的微信账号]]></FromUserName>
    <CreateTime>时间戳</CreateTime>
    <MsgType><![CDATA[news]]></MsgType>
    <Content><![CDATA[内容]]></Content>
    <ArticleCount>1</ArticleCount>

    <Articles>
        <item>
            <Title>标题</Title>
            <Description>摘要</Description>

            <PicUrl> <![CDATA[题图地址]]></PicUrl>
            <Url><![CDATA[链接地址]]></Url>
        </item>
        <!--如果是多图文,将有几个不同的item-->
    </Articles>
</xml>

4.9 接收事件

基础接口的事件只有两个,就是关注和取消关注。 msgType为event。

用户点击关注公众号->

代码语言:javascript
复制
<xml>
    <ToUserName><![CDATA[发送的微信账号]]></ToUserName>
    <FromUserName><![CDATA[收到的微信账号]]></FromUserName>
    <CreateTime>时间戳</CreateTime>
    <MsgType><![CDATA[event]]></MsgType>

    <Event><![CDATA[subscribe]]></Event><!--订阅-->
    <EventKey><![CDATA[]]></EventKey><!--为空-->

</xml>

用户取关->

代码语言:javascript
复制
<xml>
    <ToUserName><![CDATA[发送的微信账号]]></ToUserName>
    <FromUserName><![CDATA[收到的微信账号]]></FromUserName>
    <CreateTime>时间戳</CreateTime>
    <MsgType><![CDATA[event]]></MsgType>

     <Event><![CDATA[unsubscribe]]></Event><!--取消订阅-->
     <EventKey><![CDATA[]]></EventKey><!--为空-->
</xml>

4.10 写基础消息的SDK

【需求】根据之前的消息范例,写一个微信公众号的SDK。

4.10.1 消息流程

基础消息的SDK将前面章节的各种接收消息类型进行了处理,另外对被动发送消息类型进行了定义。

responseMsg()方法中,先提取消息类型 $postObj->MsgType,从而实现各种消息类型的分离。在类wechatCallbackapiTest中,为每种消息定型定义了接收方法函数。在每个方法里面,返回消息的主要特征值,组成文本信息作为内容回复。   

在接收到文本指令回复文本、图文(包括单图文和多图文)、音乐三种消息时,是使用直接构造相应消息类型实现的,而图片、语音、视频三种消息需要MediaId参数,在这里直接使用用户发送过来的消息中的MediaId,然后组装成响应消息回复。

由之前的原理可得:

用户发出消息=>校验=>判断消息类型,跳转不同业务逻辑=>根据不同消息类型,制定不同的消息。

和上一章一样,定义一个 wechatCallbackapiTest类:

代码语言:javascript
复制
<?php 
/**
 * 微信第一个SDK
 */

header('Content-type:text');
define('TOKEN','weixin');

$wechatObj=new wechatCallbackapiTest();

if(!isset($_GET['echostr'])){
    $wechatObj->responseMsg();
}else{
    $wechatObj->valid();
}

public wechatCallbackapiTest{
    // ...
}

?>
4.10.2 响应消息

收到消息,先判断MsgType。再根据类型转发到receiveXXX方法。

代码语言:javascript
复制
<?php

    // ...
    //响应消息
    public function responseMsg(){
        $postStr=$GLOBALS['HTTP_RAW_POST_DATA'];

        if(!empty($postStr)){
            // $this->logger("R \r\n.postStr");
            $postObj=simplexml_load_string($postStr,'SimpleXMLElement',LIBXML_NOCDATA);
            $RX_TYPE=trim($postObj->MsgType);

            //消息类型分类
            switch ($RX_TYPE) {
                case 'event': //事件
                    $result=$this->receiveEvent($postObj);
                    break;

                case 'text'://文本
                    $result=$this->receiveText($postObj);
                    break;

                case 'image'://图片
                    $result=$this->receiveImage($postObj);
                    break;

                case 'location'://位置
                    $result=$this->receiveLocation($postObj);
                    break;

                case 'voice'://语音
                    $result=$this->receiveVoice($postObj);
                    break;

                case 'video':
                case 'shortVideo'://视频
                    $result=$this->receiveVideo($postObj);
                    break;

                case 'link':
                    $result=$this->receiveLink($postObj);
                    break;

                default:
                    $result='未知的消息类型。';
                    break;

            }

            // $this->logger("T \r\n".$result);

            echo $result;
        }else{
            echo '';
        }

    }   


?>
4.10.3 receiveXXX处理流程

receiveXXX就是针对每种消息进行分类处理好大部分恢复内容后,进入组装流程(transmitXXX)。

代码语言:javascript
复制
4.10.4 组装消息流程(transmitXXX)
代码语言:javascript
复制
<?php 
    // 。。。
    / 回复文本消息

        private function transmitText($object,$content){
            if(!isset($content)||empty($content)){
                return "";
            }
                $xmlTpl="
                    <xml>
                        <ToUserName><![CDATA[%s]]></ToUserName>
                        <FromUserName><![CDATA[%s]]></FromUserName>
                        <CreateTime>%s</CreateTime>
                        <MsgType><![CDATA[text]]></MsgType>
                        <Content><![CDATA[%s]]></Content>
                    </xml>
                ";
                $result=sprintf($xmlTpl,$object->FromUserName,$object->ToUserName,time(),$content);

            return $result;
        }


    //回复图文消息
       private function transmitNews($object,$content){
        if(!is_array($content)){
            return "";
        }
        $itemTpl="
        <item>
            <Title><![CDATA[%s]]></Title>
            <Description><![CDATA[%s]]></Description>
            <PicUrl><![CDATA[%s]]></PicUrl>
            <Url><![CDATA[%s]]></Url>
        </item>
        ";
        $item_str="";
        foreach ($content as $item){
            $item_str.=sprintf($itemTpl, $item['Title'], $item['Description'], $item['PicUrl'], $item['Url']);
        }
        $xmlTpl = "<xml>
                    <ToUserName><![CDATA[%s]]></ToUserName>
                    <FromUserName><![CDATA[%s]]></FromUserName>
                    <CreateTime>%s</CreateTime>
                    <MsgType><![CDATA[news]]></MsgType>
                    <ArticleCount>%s</ArticleCount>
                    <Articles>
                        $item_str    
                    </Articles>
                </xml>";

        $result=sprintf($xmlTpl,$object->FromUserName,$object->ToUserName,time(),count($content));
        return $result;
    }



    //回复音乐消息
        private function transmitMusic($object,$content){
            if(!is_array($content)){
                return '';
            }
            $itemTpl="
                <Music>
                    <Title><![CDATA[%s]]></Title>
                    <Description>
                        <![CDATA[%s]]>
                    </Description>
                    <MusicUrl><![CDATA[%s]]></MusicUrl>
                    <HQMusicUrl><![CDATA[%s]]></HQMusicUrl>
                </Music>
            ";

            $item_str=sprintf($itemTpl,$content['Title'],$content['Description'],$content['MusicUrl'],$content['HQMusicUrl']);

            $xmlTpl="
                <xml>
                    <ToUserName><![CDATA[%s]]></ToUserName>
                    <FromUserName><![CDATA[%s]]></FromUserName>
                    <CreateTime>%s</CreateTime>
                    <MsgType><![CDATA[music]]></MsgType>

                    $item_str

                </xml>
            ";

            $result=sprintf($xmlTpl,$object->FromUserName,$object->ToUserName,time());

            return $result;
        }

     //回复图片消息
        private function transmitImage($object,$content){
            $itemTpl="
                <Image>
                    <MediaId><![CDATA[%s]]></MediaId>
                </Image>
            ";

            $item_str=sprintf($itemTpl,$content['MediaId']);

            $xmlTpl="
                <xml>
                    <ToUserName><![CDATA[%s]]></ToUserName>
                    <FromUserName><![CDATA[%s]]></FromUserName>
                    <CreateTime>%s</CreateTime>
                    <MsgType><![CDATA[image]]></MsgType>
                    $item_str
                </xml>
            ";



            $result=sprintf($xmlTpl,$object->FromUserName,$object->ToUserName,time());

            return $result;
        }

        //回复语音
        private function transmitVoice($object,$content){
            $itemTpl="
                <Voice>
                    <MediaId><![CDATA[%s]]></MediaId>
                </Voice>
            ";

            $item_str=sprintf($itemTpl,$content['MediaId']);

            $xmlTpl="
                <xml>
                    <ToUserName><![CDATA[%s]]></ToUserName>
                    <FromUserName><![CDATA[%s]]></FromUserName>
                    <CreateTime>%s</CreateTime>
                    <MsgType><![CDATA[voice]]></MsgType>

                    $item_str
                </xml>
            ";


            $result=sprintf($xmlTpl,$object->FromUserName,$object->ToUserName,time());

            return $result;
        }

    //回复视频消息
    private function transmitVideo($object, $videoArray)
    {
        $itemTpl = "<Video>
        <MediaId><![CDATA[%s]]></MediaId>
        <ThumbMediaId><![CDATA[%s]]></ThumbMediaId>
        <Title><![CDATA[%s]]></Title>
        <Description><![CDATA[%s]]></Description>
    </Video>";

        $item_str = sprintf($itemTpl, $videoArray['MediaId'], $videoArray['ThumbMediaId'], $videoArray['Title'], $videoArray['Description']);

        $xmlTpl = "<xml>
    <ToUserName><![CDATA[%s]]></ToUserName>
    <FromUserName><![CDATA[%s]]></FromUserName>
    <CreateTime>%s</CreateTime>
    <MsgType><![CDATA[video]]></MsgType>
    $item_str
</xml>";

        $result = sprintf($xmlTpl, $object->FromUserName, $object->ToUserName, time());
        return $result;
    }

    // 。。。

?>

自此,一个基础微信的SDJK就完成了。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-06-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 一Li小麦 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 4.1 文本消息 <MsgType><![CDATA[text]]></MsgType>
  • 4.2 图片消息
  • 4.3 语音消息
  • 4.4 视频消息
  • 4.5 用户发送给公众号的地理位置消息
  • 4.6 用户发送给公众号的链接消息
  • 4.7 公众号发回用户的音乐消息
  • 4.8 公众号发给用户的图文消息
  • 4.9 接收事件
  • 4.10 写基础消息的SDK
    • 4.10.1 消息流程
      • 4.10.2 响应消息
        • 4.10.3 receiveXXX处理流程
          • 4.10.4 组装消息流程(transmitXXX)
          相关产品与服务
          语音消息
          语音消息(Voice Message Service,VMS)通过腾讯云提供的语音专线,为客户提供语音告警、语音通知、语音验证码等服务。语音消息具有高到达率、超低延时、秒级触达的优势,致力于提供优质的语音消息服务。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档