easy-swoole / wechat

Wechat based on easyswoole.
82 stars 28 forks source link

开放平台可以代公众号实现消息发放,所以不能只返回 success 消息,这里继承父类的方法就可以了 #151

Closed browningweb closed 3 years ago

browningweb commented 3 years ago

https://github.com/easy-swoole/wechat/blob/cee56dd04f66109171ebf3009ccb52d5c177313d/src/OpenPlatform/Server/Guard.php#L33

开放平台可以代公众号实现消息发放,例如关键词消息,图文消息下发等,不能简单的回复 'success'。

XueSiLf commented 3 years ago

这一步是为了方便用户可以自行处理,我们默认只处理授权变更、验证票据等事件。

browningweb commented 3 years ago

WX20210909-070145

但是我们这边注册了消息处理器,处理器能正常返回处理后的数据,但公众号收不到任何消息,因为方法里面没有处理 消息处理器 返回的数据,直接返回 success 了。

XueSiLf commented 3 years ago

好的 我昨天理解错了

XueSiLf commented 3 years ago

这边重新看了下,您在使用代里公众号服务的时候,应该采用如下方式:

$officialAccount = $openPlatform->officialAccount('mock_officialAccount_app_id', 'mock_refresh_token');
/** @var \EasySwoole\WeChat\OfficialAccount\Server\Guard $officialAccountServer */
$officialAccountServer = $officialAccount->server;
// 公众号事件消息
$officialAccountServer->push(new EventMessageHandler(), Message::EVENT);
// 公众号图片消息
$officialAccountServer->push(new ImageMessageHandler(), Message::IMAGE);
// 公众号文本消息
$officialAccountServer->push(new TextMessageHandler(), Message::TEXT);
// 公众号媒体消息
$officialAccountServer->push(new MediaMessageHandler(), [Message::VOICE, Message::VIDEO, Message::SHORT_VIDEO]);

/** @var \Psr\Http\Message\ServerRequestInterface $psr7Request */
$psr7Request = $this->request();
try {
    $replyResponse = $officialAccountServer->serve($psr7Request);
} catch (\Exception $exception) {
    var_dump($exception->getMessage());
    return $this->response()->write('success');
}

$this->response()->withStatus($replyResponse->getStatusCode());

/** PSR-7 的 Header 并不是单纯的 k => v 结构 */
foreach ($replyResponse->getHeaders() as $name => $values) {
    $this->response()->withHeader($name, implode(", ", $values));
}

return $this->response()->write($replyResponse->getBody()->__toString());
XueSiLf commented 3 years ago

所以这里也是没有问题的

browningweb commented 3 years ago

这里如果是加密信息的话,解密时会报 Invalid appId.,看了一下,解密时,用的 appId 是公众号的,不是开放平台的appId,所以会导致解密失败。

protected function decryptMessage(array $message): ?string
    {
        return $this->app[ServiceProviders::Encryptor]->decrypt(
            $message['Encrypt'],
            $this->app[ServiceProviders::Config]->get("aesKey"),
            $this->app[ServiceProviders::Config]->get("appId")
        );
    }
XueSiLf commented 3 years ago

调用代码截图。或者和我联系 QQ 1592328848

browningweb commented 3 years ago

这里很明显的,$openPlatform->officialAccount 后,config 里面的 appId 是公众号的,app_id 是开放平台的,但是解密时,用的是 $this->app[ServiceProviders::Config]->get("appId"),这获取的是公众号的 appId,但其实应该用开放平台的 appIdaesKey。 解密前获取的 config 信息如下:

object(EasySwoole\WeChat\Kernel\Config)#315 (1) {
  ["attributes":protected]=>
  array(9) {
    ["appId"]=>
    string(18) "公众号appId"
    ["app_id"]=>
    string(18) "开放平台appId"
    ["appSecret"]=>
    string(32) "xxxxx"
    ["token"]=>
    string(17) "xxxxx"
    ["aesKey"]=>
    string(43) "xxxxx"
    ["cache"]=>
    array(1) {
      ["tempDir"]=>
      string(15) "/docker/app/Log"
    }
    ["componentAppId"]=>
    string(18) "开放平台appId"
    ["componentAppToken"]=>
    string(17) "xxxxxxxxx"
    ["refreshToken"]=>
    string(58) "xxxxxxxxx"
  }
}
browningweb commented 3 years ago

https://github.com/easy-swoole/wechat/blob/af961ede970cce348ff2c0fbacfe1b06b4ac6ffa/src/Kernel/ServerGuard.php#L141

加密这里也需要改一下。

XueSiLf commented 3 years ago

好的,麻烦把已经修复的issue关闭下。