Laravel + EasyWechat开发公众号,常用功能记录,入口代码优化,希望小伙伴提出更好的解决方案和思路。

Laravel框架
443
0
0
2022-11-09

使用Laravel + EasyWechat开发公众号、小程序效率不要太高,感谢大牛。使用前建议多看公众号官方文档;

一、微信公众号常用功能

1.接收普通消息

  • 用户给公众号发各种类型的消息,根据实际业务做出消息回复。
  • 常用的有文本、图片类型,回复主要是文本、图文(<=8篇);

2. 接收事件推送

  • 关注事件
  • 记录用户来源、存储用户、回复消息(例如,欢迎关注XXXX);
  • 取关事件
  • 更改用户关注状态;
  • 扫描带参数二维码事件
  • 常用于一些运营的活动,做数据记录;
  • CLICK事件的菜单
  • 用户回复文字、图文等消息;
  • 点击菜单跳转链接时的事件推送
  • 可用于菜单点击量统计;

3. 自定义菜单

  • 通过接口设置、修改、查看公众号菜单;

二、代码优化之旅

EasyWechat安装后,文档示例以下代码。上述提到的接收普通消息、接收事件推送,可在serve方法中处理;

namespace App\Http\Controllers;

use Log;

class WeChatController extends Controller
{
    public function serve()
    {
        $app = app('wechat.official_account');
        $app->server->push(function($message){
            return "欢迎关注 overtrue!";
        });
        return $app->server->serve();
    }
}

1. 早期封装的代码

处理不同消息类型依据:$message变量不同的MsgType参数

之前所有的消息类型代码都放到一个控制器中。随着业务需求,消息类型不断增多,代码变的难以维护,谁看谁头大。

class WeChatController extends Controller
{
    public function serve()
    {
        $app = app('wechat.official_account.default');
        $app->server->push(function($message){
            switch ($message['MsgType']) {
                //普通消息 -> 文本 
                case 'text':
                    $this->dealTextMsg($message);
                    break;

                //普通消息 -> 图片 
                case 'image';
                    $this->dealImageMsg($message);
                    break;
                break;

                //处理事件 
                case 'event':
                    $this->dealEventMsg($message);
                    break;
                //消息类型、类方法不断增多。。。。
            }
        });
        return $app->server->serve();
    }

    //处理普通消息 ->文本 
    public function delTextMsg($message)
    {
        //业务相关
    }

    //处理普通消息 ->图片 
    public function dealImageMsg($message)
    {
        //业务相关
    }

    //处理所有的事件 
    public function delEventMsg($message) {
        //处理关注、取关等一系列事件,见过在这个方法中写有上百行代码!
    }
}

2. 优化思路、上代码

2.1优化思路

接收普通消息、接收事件消息2种类型,创建2个Services;

NormalMsgServices.php 用于处理普通消息;

EventMsgServices.php 用于处理事件;

实际开发中可能用不到这么多的方法,所以需要加一层判断,判断类方法是否存在。

Services类方法规则:

一、普通消息MsgType:

  • 文本:text
  • 图片:image
  • 语音消息:voice
  • 暂定命名规则:dealText、dealImage、dealVoice

二、事件的MsgType统一是event,可以根据Event来区分,例如:

  • 关注事件 Event = subscribe
  • 取关事件 Event = unsubscribe
  • 扫描带参数二维码,未关注用户事件 Event = subscribe && EventKey(事件key值)
  • 点击菜单跳转链接时的事件推送 Event = VIEW

暂定命名规则:dealSubscribe、dealUnsubscribe、dealView

2.1 上代码

ChatController控制器

namespace App\Http\Controllers;

class WeChatController extends Controller
{
    public function serve()
    {
        $app = app('wechat.official_account.default')
        $app->server->push(function($message){

            //不同的消息类型,使用可变函数(变量函数),定义对应Services类的方法; 
            switch ($msgType = strtolower($message['MsgType'])) {
                case 'event': //事件消息方法 
                    $function = 'deal' . ucfirst($message['Event']);//dealSubscribe、dealUnsubscribe、dealView 
                break;

                default://普通消息方法 
                    $function = 'deal' . $msgType; //dealText、dealImage、dealVoice
            }

            //根据MsgType类型,动态调用Services(普通、事件) 
            $service = ($msgType === 'event' ? 'Event' : 'Normal');
            //仅处理需要的消息类型,加个判断类中是否有方法的判断。 
            if (method_exists('App\Services\Wechat\\' . $service . 'MsgServices', $function)) {
                return app('App\Services\Wechat\\' . $service . 'MsgServices')->$function($message);
            }
        });
        return $app->server->serve();
    }
}

普通消息处理Services示例

<?php

namespace App\Services\Wechat;

/**
 * 功能:处理普通消息
 * 文档:https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Receiving_standard_messages.html
 */
class NormalMsgServices
{
    public function dealText($aMessage)
    {
        //业务逻辑
    }
}

事件处理Services示例

<?php

namespace App\Services\Wechat;

/**
 * 功能:处理事件消息
 * 文档:https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Receiving_event_pushes.html
 */
class EventMsgServices
{
    /**
     * 关注、扫描带参数二维码(用户未关注)
     */ 
    public function dealSubscribe()
    {
        return "欢迎关注XXX公众号";
    }
}

写的有点多,有点乱,各位小伙伴凑合看吧,如果有更好的方案可以留言。一起学习进步。