• 微信公众平台开发介绍(四)


    上一节中,介绍了如何处理消息和回复消息。这一节我们主要介绍下如何基于规则进行回复。

    为了尽可能简单,把规则直接写入到配置文件中,通过读写配置文件来获取规则。

    本节结束的自动回复是基于文本消息进行触发的,其他的消息类型咱不考虑。

    首先定义规则类,规则包含三个属性:
    关键词;
    规则类型,比如是精确匹配,模糊匹配,还是正则匹配等;
    回复消息内容,规则匹配之后,回复的消息内容。

    Rule具体属性如下:

      /**
         * 精确匹配
         */
        const TYPE_EXACT_MATCH = 1;
    
        /**
         * 模糊匹配
         */
        const TYPE_FUZZY_MATCH = 2;
    
        public $keyword;
    
        public $type;
    
        public $messageInfo;
    
        public $messageid;
    
        public $allRules; 


    我们的消息内容定义在MessageInfo中,两者是通过messageid来关联的。messageid是根据消息数量来自增长实现的。
    MessageInfo主要属性如下:

      /**
         * 消息类型:文本
         */
        const MESSAGE_TYPE_TEXT = "text";
       
        /**
         * 消息类型:图文
         */
        const MESSAGE_TYPE_NEWS = "news";
        /**
         * messageid
         * 回复消息的id
         */
        public $messageid;
    
        /**
         * content
         * 回复消息的内容
         */
        public $content;
    
        /**
         * msgType
         * 回复消息的类型
         */
        public $msgType;

     

    msgType标识出调用哪种消息类型来发送回复消息。接口为responseMsg。content是具体的消息内容。

    通过RuleConfig类来实现增加规则,写入配置文件,从配置文件中读取规则。

    配置文件举例:

    Array
    (
        [rules] => Array
            (
                [0] => Array
                    (
                        [keyword] => test
                        [type] => 1
                        [messageid] => 1
                    )
    
                [1] => Array
                    (
                        [keyword] => test1
                        [type] => 1
                        [messageid] => 2
                    )
    
            )
    
        [messageInfos] => Array
            (
                [0] => Array
                    (
                        [messageid] => 1
                        [msgType] => text
                        [content] => this is a test
                    )
    
                [1] => Array
                    (
                        [messageid] => 2
                        [msgType] => text
                        [content] => this is a other test
                    )
    
            )
    
    )



    测试代码如下:

     public function testAddRule() {
    
            $msgInfo = new MessageInfo();
            $msgInfo->msgType = MessageInfo::MESSAGE_TYPE_TEXT;
            $msgInfo->content = 'this is a other test';
    
            $rule = new Rule();
            $rule->keyword = 'test1';
            $rule->type = Rule::TYPE_EXACT_MATCH;
            $rule->messageInfo = $msgInfo;
    
            $ruleConfig = new RuleConfig('wxid');
            $ruleConfig->addRule($rule);
        }



    我们把规则写入到配置中后,就考虑集成到我们项目中。


    时序图中,RuleController是自动回复的入口,在初始化,会注册所有的回复策略,在本例中,我们只有一个基于配置的回复策略。然后,每个回复策略去处理用户的发的消息。如果匹配了规则,就会发送相应的消息,否则交给TextMsg继续处理消息。

    ConfigReplyTactic对外只有一个reply接口,接口返回bool用于表示,是否匹配了规则。回复策略从RuleConfig获取规则。但是,我们可以写的更灵活,从不同的规则源获取。
    具体代码如下:

    <?php
    require ROOT_PATH . '/src/RuleConfig.php';
    
    /**
     * ConfigReplyTactic
     * 基于配置的回复策略
     *
     * @package
     * @version $id$
     * @copyright 1997-2005 The PHP Group
     * @author Tobias Schlitt <toby@php.net>
     * @license PHP Version 3.0 {@link http://www.php.net/license/3_0.txt}
     */
    class ConfigReplyTactic {
    
        private $_rules;
        public function reply($postObj) {
    
            $rule = $this->matchRule($postObj);
    
            // 没找到规则,直接返回
            if (!$rule) {
                return false;
            }
    
            return $this->sendReplyMsg($rule, $postObj);
        }
    
        /**
         * matchRule
         * 查找匹配规则
         *
         * @param mixed $postObj
         * @access public
         * @return void
         */
        public function matchRule($postObj) {
    
            $content = $postObj->Content;
           
            $rules = $this->getRules;
    
            foreach ($rules['rules'] as $rule) {
    
                if ($rule['type'] == Rule::TYPE_EXACT_MATCH) {
    
                    // 如果是精确匹配
                    if ($content == $rule['keyword']) {
                        return $rule;
                    }
                } else if ($rule['type'] == Rule::TYPE_FUZZY_MATCH) {
               
                    // 如果是模糊匹配
                    if (strpos($content, $rule['keyword']) !== false) {
                        return $rule;
                    }
                }
            }
    
            return false;
    
        }
    
        public function getRules() {
    
            // WEIXINID:config配置里的,当前商家的微信ID
            $config = new RuleConfig(WEIXINID);
    
            $this->_rules = $config->readConfig();
    
            return $this->_rules;
        }
    
        /**
         * sendReplyMsg
         * 根据匹配到的规则进行回复消息
         *
         * @param mixed $rule
         * @param mixed $postObj
         * @access public
         * @return void
         */
        public function sendReplyMsg($rule, $postObj) {
           
            foreach ($this->_rules['messageInfos'] as $msgInfo) {
                if ($msgInfo['messageid'] == $rule['messageid']) {
    
                    // 具体的消息发送
                    $msgClass = MsgController::factory($msgInfo['msgType']);
                    if ($msgClass) {
                        $msgClass->responseMsg($postObj, $msgInfo['content']);
                        return true;
                    }
               
                }
            }
    
            Logger::error("not find messageid:{$rule['messageid']}");
            return false;
        }
    }


    ====================
    代码参考:https://github.com/bruceding/MPDemo 

    欢迎关注个人公众号

    微信号:gz_bruceding

    个人博客地址:http://dj.80lifes.com/blog
     
  • 相关阅读:
    模板、中间件以及MVC与MTV
    Cookie与Session
    分页与网页攻击
    Django一对一查询,列类型及参数
    Django ORM 查询
    Django中ORM多对多表的操作
    Django中的ORM
    一、Vue简介
    三、路由层(urls.py)
    二、django简介
  • 原文地址:https://www.cnblogs.com/dingjing/p/3439851.html
Copyright © 2020-2023  润新知