From c699ba6c16e4435f5649a9379a7c9c657b672481 Mon Sep 17 00:00:00 2001 From: yaozm Date: Thu, 18 Jan 2024 12:10:54 +0800 Subject: [PATCH] wip LarkGroupBot --- src/Foundation/HttpMessage.php | 39 ++++++++++++++++ src/LarkGroupBot/Client.php | 24 ++++++++++ src/LarkGroupBot/Credential.php | 57 +++++++++++++++++++++++ src/LarkGroupBot/Messages/TextMessage.php | 50 ++++++++++++++++++++ src/XiZhi/Messages/SingleMessage.php | 43 +---------------- 5 files changed, 172 insertions(+), 41 deletions(-) create mode 100644 src/LarkGroupBot/Client.php create mode 100644 src/LarkGroupBot/Credential.php create mode 100644 src/LarkGroupBot/Messages/TextMessage.php diff --git a/src/Foundation/HttpMessage.php b/src/Foundation/HttpMessage.php index 5016131c..e6836ceb 100644 --- a/src/Foundation/HttpMessage.php +++ b/src/Foundation/HttpMessage.php @@ -14,7 +14,9 @@ use Http\Discovery\Psr17FactoryDiscovery; use Psr\Http\Message\RequestFactoryInterface; +use Psr\Http\Message\RequestInterface; use Psr\Http\Message\StreamFactoryInterface; +use Psr\Http\Message\StreamInterface; use Psr\Http\Message\UploadedFileFactoryInterface; use Psr\Http\Message\UriFactoryInterface; @@ -34,11 +36,48 @@ public function __construct(array $options = []) $this->uriFactory = Psr17FactoryDiscovery::findUriFactory(); } + public function toRequest(): RequestInterface + { + $request = $this->requestFactory->createRequest($this->method(), $this->uri()); + $protocolVersion = $this->protocolVersion(); + if ($protocolVersion) { + $request->withProtocolVersion($protocolVersion); + } + + $body = $this->body(); + if ($body) { + $request = $request->withBody($this->body()); + } + + foreach ($this->headers() as $key => $value) { + $request = $request->withHeader($key, $value); + } + + return $request; + } + public function toQuery(): string { return http_build_query($this->options); } + protected function protocolVersion(): string + { + return '1.1'; + } + + protected function headers(): array + { + return [ + 'Content-Type' => 'application/json', + ]; + } + + protected function body(): ?StreamInterface + { + return $this->streamFactory->createStream((string) $this); + } + abstract protected function method(): string; abstract protected function uri(): string; diff --git a/src/LarkGroupBot/Client.php b/src/LarkGroupBot/Client.php new file mode 100644 index 00000000..fa0a4f0c --- /dev/null +++ b/src/LarkGroupBot/Client.php @@ -0,0 +1,24 @@ + + * + * This source file is subject to the MIT license that is bundled. + */ + +namespace Guanguans\Notify\LarkGroupBot; + +use Guanguans\Notify\Foundation\HttpClient; +use Psr\Http\Client\ClientInterface; + +class Client extends HttpClient +{ + public function __construct(Credential $credential, ClientInterface $httpClient = null) + { + parent::__construct($credential, $httpClient); + } +} diff --git a/src/LarkGroupBot/Credential.php b/src/LarkGroupBot/Credential.php new file mode 100644 index 00000000..4798d5da --- /dev/null +++ b/src/LarkGroupBot/Credential.php @@ -0,0 +1,57 @@ + + * + * This source file is subject to the MIT license that is bundled. + */ + +namespace Guanguans\Notify\LarkGroupBot; + +use Http\Discovery\Psr17FactoryDiscovery; +use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\StreamFactoryInterface; + +class Credential implements \Guanguans\Notify\Foundation\Contracts\Credential +{ + private string $accessToken; + private ?string $secret; + private StreamFactoryInterface $streamFactory; + + public function __construct(string $accessToken, ?string $secret = null) + { + $this->accessToken = $accessToken; + $this->secret = $secret; + $this->streamFactory = Psr17FactoryDiscovery::findStreamFactory(); + } + + /** + * @noinspection JsonEncodingApiUsageInspection + */ + public function applyToRequest(RequestInterface $request): RequestInterface + { + $request = $request->withUri( + $request->getUri()->withPath(str_replace('token', $this->accessToken, $request->getUri()->getPath())) + ); + + if ($this->secret) { + $body = [ + 'timestamp' => $timestamp = time(), + 'sign' => $this->sign($this->secret, $timestamp), + ] + json_decode($request->getBody()->getContents(), true); + + $request = $request->withBody($this->streamFactory->createStream(json_encode($body))); + } + + return $request; + } + + private function sign(string $secret, int $timestamp): string + { + return base64_encode(hash_hmac('sha256', '', sprintf("%s\n%s", $timestamp, $secret), true)); + } +} diff --git a/src/LarkGroupBot/Messages/TextMessage.php b/src/LarkGroupBot/Messages/TextMessage.php new file mode 100644 index 00000000..fe510c82 --- /dev/null +++ b/src/LarkGroupBot/Messages/TextMessage.php @@ -0,0 +1,50 @@ + + * + * This source file is subject to the MIT license that is bundled. + */ + +namespace Guanguans\Notify\LarkGroupBot\Messages; + +use Guanguans\Notify\Foundation\HttpMessage; + +class TextMessage extends HttpMessage +{ + protected string $type = 'text'; + + protected array $defined = [ + 'text', + ]; + + public function __construct(string $text) + { + parent::__construct(['text' => $text]); + } + + /** + * @noinspection JsonEncodingApiUsageInspection + */ + public function __toString(): string + { + return json_encode([ + 'msg_type' => $this->type, + 'content' => $this->options, + ]); + } + + protected function method(): string + { + return 'POST'; + } + + protected function uri(): string + { + return 'https://open.feishu.cn/open-apis/bot/v2/hook/token'; + } +} diff --git a/src/XiZhi/Messages/SingleMessage.php b/src/XiZhi/Messages/SingleMessage.php index 7ef21c08..c09f6156 100644 --- a/src/XiZhi/Messages/SingleMessage.php +++ b/src/XiZhi/Messages/SingleMessage.php @@ -13,8 +13,6 @@ namespace Guanguans\Notify\XiZhi\Messages; use Guanguans\Notify\Foundation\HttpMessage; -use Psr\Http\Message\RequestInterface; -use Psr\Http\Message\StreamInterface; class SingleMessage extends HttpMessage { @@ -31,50 +29,13 @@ public function __construct(string $title, ?string $content = null) ]); } - public function toRequest(): RequestInterface - { - $request = $this->requestFactory->createRequest($this->method(), $this->uri()); - $protocolVersion = $this->protocolVersion(); - if ($protocolVersion) { - $request->withProtocolVersion($protocolVersion); - } - - $body = $this->body(); - if ($body) { - $request = $request->withBody($this->body()); - } - - foreach ($this->headers() as $key => $value) { - $request = $request->withHeader($key, $value); - } - - return $request; - } - - protected function protocolVersion(): string - { - return '1.1'; - } - - protected function uri(): string - { - return 'https://xizhi.qqoq.net/token.send'; - } - protected function method(): string { return 'POST'; } - protected function headers(): array - { - return [ - 'Content-Type' => 'application/json', - ]; - } - - protected function body(): ?StreamInterface + protected function uri(): string { - return $this->streamFactory->createStream((string) $this); + return 'https://xizhi.qqoq.net/token.send'; } }