easywechat php例子,thinkphp6使用easywechat笔记!

公众号端基本配置

8d14f20f4aed

image.png

公众号端设置

8d14f20f4aed

image.png

域名要备案,文件下载上传至tp6的public目录下

8d14f20f4aed

image.png

composer require overtrue/wechat -vvv

微信相关路由配置

//微信

Route::group('wechat', function () use($version){

Route::get('',"{$version}.Wechat/index");//微信首页

Route::any('me',"{$version}.Wechat/me");//微信首页

Route::any('oauth_callback',"{$version}.Wechat/oauth_callback");//微信首页

Route::get('test',"{$version}.Wechat/test");//微信首页

Route::get('menu',"{$version}.Wechat/menuList");//微信菜单列表

Route::post('menu',"{$version}.Wechat/menuAdd");//微信菜单添加

Route::get('resource',"{$version}.Wechat/resource");//资源

});

config/wechat.php配置文件

return [

/**

* 账号基本信息,请从微信公众平台/开放平台获取

*/

'app_id' => env('WECHAT_OFFICIAL_ACCOUNT_APPID', ''), // AppID

'secret' => env('WECHAT_OFFICIAL_ACCOUNT_SECRET', ''), // AppSecret

'token' => env('WECHAT_OFFICIAL_ACCOUNT_TOKEN', ''), // Token

'aes_key' => env('WECHAT_OFFICIAL_ACCOUNT_AES_KEY', '

'), // EncodingAESKey

/**

* 指定 API 调用返回结果的类型:array(default)/collection/object/raw/自定义类名

* 使用自定义类名时,构造函数将会接收一个 `EasyWeChat\Kernel\Http\Response` 实例

*/

'response_type' => 'array',

/**

* 日志配置

*

* level: 日志级别, 可选为:

* debug/info/notice/warning/error/critical/alert/emergency

* path:日志文件位置(绝对路径!!!),要求可写权限

*/

'log' => [

'default' => 'dev', // 默认使用的 channel,生产环境可以改为下面的 prod

'channels' => [

// 测试环境

'dev' => [

'driver' => 'single',

'path' => ROOT_PATH.'logs/'.date('Y-m-d').'/easywechat.log',

'level' => 'debug',

],

// 生产环境

'prod' => [

'driver' => 'daily',

'path' => ROOT_PATH.'logs/'.date('Y-m-d').'/easywechat.log',

'level' => 'info',

],

],

],

/**

* 接口请求相关配置,超时时间等,具体可用参数请参考:

* http://docs.guzzlephp.org/en/stable/request-config.html

*

* - retries: 重试次数,默认 1,指定当 http 请求失败时重试的次数。

* - retry_delay: 重试延迟间隔(单位:ms),默认 500

* - log_template: 指定 HTTP 日志模板,请参考:https://github.com/guzzle/guzzle/blob/master/src/MessageFormatter.php

*/

'http' => [

'max_retries' => 1,

'retry_delay' => 500,

'timeout' => 5.0,

// 'base_uri' => 'https://api.weixin.qq.com/', // 如果你在国外想要覆盖默认的 url 的时候才使用,根据不同的模块配置不同的 uri

],

/**

* OAuth 配置

*

* scopes:公众平台(snsapi_userinfo / snsapi_base),开放平台:snsapi_login

* callback:OAuth授权完成后的回调页地址

*/

'oauth' => [

'scopes' => ['snsapi_userinfo'],

'callback' => '/api/wechat/oauth_callback',

],

];

// +----------------------------------------------------------------------

// | 微信逻辑【业务层】

// +----------------------------------------------------------------------

// | Author: DragonersLi<865196792@qq.com>

// +----------------------------------------------------------------------

// | Date: 2020/07/23

// +----------------------------------------------------------------------

namespace app\common\logic;

use EasyWeChat\OpenPlatform\Server\Guard;

use EasyWeChat\Factory;

use EasyWeChat\Kernel\Messages\Text;

use EasyWeChat\Kernel\Messages\Image;

use EasyWeChat\Kernel\Messages\Video;

use EasyWeChat\Kernel\Messages\Voice;

use EasyWeChat\Kernel\Messages\News;

use EasyWeChat\Kernel\Messages\NewsItem;

use EasyWeChat\Kernel\Messages\Article;

use app\common\service\RedisService;

use app\common\model\UserWeixin;

use app\common\model\Keyword;

use app\common\model\Notice;

use think\facade\Log;

class WechatLogic extends BaseLogic

{

public function initialize()

{

parent::initialize();

}

public function __construct()

{

$this->app = Factory::officialAccount(config('wechat'));

}

/**

* 微信首页

* @return array

* @throws \think\db\exception\DataNotFoundException

* @throws \think\db\exception\DbException

* @throws \think\db\exception\ModelNotFoundException

*/

public function index(){

try{

$this->app->server->push(function ($message){

$user_openid = $message['FromUserName'];

switch ($message['MsgType']) {

case 'event':

$message['user'] = $this->app->user->get($user_openid);

return $result = $this->event($message);//处理点击事件

break;

case 'text':

return $this->text($message['Content']);//处理被动回复文本

break;

case 'image':

return $image = new Image($mediaId = '0b69zmxmX9VQ1WOyimslclMr3f2YbnNgrMkjS2KxWZM');

break;

case 'voice':

return $voice = new Voice($mediaId = 'Rwqz1xLYDNwFvTJ254fBstYU1rY3aKiN-z7aqEpiWic');

break;

case 'video':

return $video = new Video($mediaId = 'Rwqz1xLYDNwFvTJ254fBsmzRm-HXa-ilLRc028v-Ar0', [

'title' => $title = '标题',

'description' => '简介...',

]);

break;

case 'location'://收到坐标消息,微信目前不支持回复坐标消息

return $text = new Text("您好!openid:{$message['FromUserName']},{$message['MsgType']},收到坐标消息,微信目前不支持回复坐标消息");

break;

case 'link'://收到链接消息,微信目前不支持回复链接消息

return $text = new Text("您好!openid:{$message['FromUserName']},{$message['MsgType']},收到链接消息,微信目前不支持回复链接消息");

break;

case 'file':

return $text = new Text("您好!openid:{$message['FromUserName']},{$message['MsgType']},收到文件消息");

// ... 其它消息

default:

return '收到其它消息';

break;

}

});

}catch(\Exception $e){

dlog('wechat',$e->getMessage());

}

$response = $this->app->server->serve()->send();

}

/*

* 菜单列表

*/

public function menuList()

{

$list = $this->app->menu->list();//读取(查询)已设置菜单

$current = $this->app->menu->current();//获取当前菜单

return [

'list'=>$list,

'current'=>$current

];

}

/*

* 菜单创建

*/

public function menuAdd(){

$buttons = [

[

"type" => "view",

"name" => "下载APP",

"url" => config('system.api.url')."/download.html"

],

[

"type" => "view",

"name" => "个人中心",

"url" => config('system.api.url')."/h5"

]

];

return $this->app->menu->create($buttons);

}

/*

* $type 素材的类型,图片(image)、视频(video)、语音 (voice)、图文(news)

* $offset 从全部素材的该偏移位置开始返回,可选,默认 0,0 表示从第一个素材 返回

* $count 返回素材的数量,可选,默认 20, 取值在 1 到 20 之间

*/

public function resource($type = 'image'){

$user = $this->app->user->list($nextOpenId = null); // $nextOpenId 可选

$stats = $this->app->material->stats();//获取各类素材总数

//$item = $this->app->material->get($mediaId='');//获取单个素材

$resource = $this->app->material->list($type, $offset= 0, $count= 20);

// $this->app->material->delete($mediaId='');//删除素材

return [

'count'=>$stats,

'list'=>$resource,

'user'=>$user

];

}

/**

* 授权页面

* @return mixed

*/

public function me(){

if (!cookie('wechat_user')) {// 未登录

cookie('target_url',config('system.api.url').'/api/wechat/me');

return $this->app->oauth->redirect()->send();

}

$url = config('system.api.url').'/h5';

header('location:'. $url);

}

/**

* 回调页面

*/

public function oauth_callback(){

$user = $this->app->oauth->user(); // 获取 OAuth 授权结果用户信息

cookie('wechat_user',json_encode($user));

dlog('wechat_user',$user);

RedisService::redis()->set('weixin_user:'.$user->id,json_encode([

'openid'=>$user->id,

'nickname'=>$user->nickname,

'avatar'=>$user->avatar

]));

$url = cookie('target_url') ? cookie('target_url') : config('system.api.url').'/h5';

header('location:'. $url);

}

/**

* 回复事件

* @param array $message

* @return Image|string

*/

private function event($message = []){

$user_openid = $message['user']['openid'];

switch ($message['Event']) {

case "subscribe"://关注微信用户表新增记录

return '欢迎关注派金花公众号,有疑问请联系在线客服!' ;

break;

case "unsubscribe"://取消关注时执行的操作,要把记录该用户从记录微信用户信息的表中删掉

$msg = "{$user_openid}:取消关注!清除微信信息:";

$msg.= UserWeixin::destroy(function($query) use($user_openid){

$query->where(['wxOpenid'=>$user_openid]);

}) ? 'success' : 'failed';

dlog('wechat',$msg);//取消关注时执行的操作,要把记录该用户从记录微信用户信息的表中删掉

break;

case "CLICK":

switch ($message['EventKey']) {

case "V1000":

break;

case "V1001":

default:

return $image = new Image($mediaId = 'Rwqz1xLYDNwFvTJ254fBspGO-4KAaoUILJIKRzwUBrE');

break;

}

break;

case "SCAN":

case "LOCATION":

case "VIEW":

default:

break;

}

}

/**

* 回复文本

* @param string $content

* @return Image|News|Text|Video|Voice

*/

private function text($content = ''){

$result = config('wechatreply.keywords');

if(empty($result[$content])){ //关键词匹配失败

$other = config('wechatreply.other');

if(empty($other[$content])){//其它关键词也匹配失败,则返回关键词列表

$content = "输入序号快捷获取回复!\n";

foreach($result as $k=>$v){

$content .= "【{$k}】{$v['title']}\n";

}

return $text = new Text($content);

}else{ //匹配其它关键词

$result = $other;

}

}

switch ($result[$content]['type']){

case 'image'://图片

return $image = new Image($result[$content]['content']);

break;

case 'video'://视频

return $video = new Video($mediaId = $result[$content]['content'], [

'title' => $result[$content]['title'],

'description' => '视频描述...',

// 'thumb_media_id'=>'Rwqz1xLYDNwFvTJ254fBsiuqJw5ZV9dZF2jNu34_bPU' // 封面资源 ID

]);

break;

case 'voice'://声音

return $voice = new Voice($mediaId = $result[$content]['content']);

break;

case 'news'://资讯

$data = Notice::where(['id'=>$result[$content]['content']])->field('id,title,content')->find();

return $news = new News([

new NewsItem([

'title' => $result[$content]['title'],

'description' =>$result[$content]['content'],

'url' =>$result[$content]['id'],

//'image' => 'https://www.easywechat.com/img/logo-black.svg',

// ...

]),

]);

break;

case 'text'://文本

default:

$result[$content]['content'] = htmlspecialchars_decode($result[$content]['content']);

$result[$content]['content'] = str_replace('

','',$result[$content]['content']);

$result[$content]['content'] = str_replace('

',"\r",$result[$content]['content']);

$result[$content]['content'] = str_replace('
',"\r",$result[$content]['content']);

return $text = new Text($result[$content]['content']);

break;

}

}

/**

* 发送模板消息[静态方法方便调用]

* @param array $data

* @return mixed

*/

public static function tpl($data = []){

// $data['openid'] = 'o9soys5-em4VBQD78uy4_dyZx_Pg';

// $data['type'] = 'test';

// $data['url'] = config('system.api.url').'/h5';

// $data['data'] =[

// 'first'=>'hello,world',

// 'keyword1' => '220.30元',

// 'keyword2' => '荣事达旗舰店',

// 'keyword3' => '2014年7月21日 18:36',

// ];

// $this->tpl($data);

$result = Factory::officialAccount(config('wechat'))->template_message->send([

'touser'=>$data['openid'],

'template_id'=>config("system.wechat_tpl.{$data['type']}"),

'url' => $data['url'],

'data' => $data['data'],

]);

if(!$result['errcode']){//发送成功

return ['code'=>1,'msg'=>$result['errmsg'],'data'=>['msgid'=>$result['msgid']]];

}else{//发送失败记录日志

dlog('wechat_tpl',['data'=>$data,'result'=>$result]);

return ['code'=>0,'msg'=>$result['errmsg'],'data'=>['result'=>$result]];

}

}

}

开通模版消息,配置模版ID

//微信模板ID

'wechat_tpl'=>[

'test'=>'tGy9UXpXz97cv7SygOnVR6S-kqOZtnEDblTnN5QwkJs',//测试

'register'=>'pxIIRpFWFZu-02103RmVIxCmqS-LdyDJIpPcNbwVupo',//注册模板ID

],

完全按官网demo接入,菜单资源等接口都能正常运作,自动回复却提示:该公众号暂时无法提供服务,请稍后再试

tail -f tp6.xxx.com.log查看日志,看到是post请求,返回错误404 Not Found!

排查结果:路由请求方式由get改成any解决!

223.166.222.120 - - [22/Aug/2020:14:12:37 +0800] "POST /api/wechat?signature=acd16cbad48ae6bad1df96b27e302d979eb454cd&timestamp=1598076757&nonce=1560311832&openid=o9soys5-em4VBQD78uy4_dyZx_Pg&encrypt_type=aes&msg_signature=26a0a9c431a2a56fca7e5e0db794e4a98e7b4617 HTTP/1.1" 404 21487 "-" "Mozilla/4.0"

laraval下请求方式错误返回405 Method Not Allowed

"The POST method is not supported for this route. Supported methods: GET, HEAD."

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值