Laravel + EasyWechat開發公眾號,常用功能記錄,入口程式碼優化,希望小夥伴提出更好的解決方案和思路。

赤三禾發表於2022-07-12

使用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公眾號";
    }
}

寫的有點多,有點亂,各位小夥伴湊合看吧,如果有更好的方案可以留言。一起學習進步。

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章