From 8a20b86b17ac577cce17bd7e363a869950a36969 Mon Sep 17 00:00:00 2001 From: Alex Komarichev Date: Mon, 24 Jun 2024 20:21:41 +0300 Subject: [PATCH] Add templates interaction --- src/Bot/Client.php | 39 +- src/Bot/Model/Entity/Template/Template.php | 385 ++++++++++++++++++ .../Entity/Template/TemplateVariables.php | 88 ++++ src/Bot/Model/Request/TemplateSendRequest.php | 77 ++++ tests/Bot/Tests/TemplatesTest.php | 113 +++++ tests/Resources/templates.json | 56 +++ 6 files changed, 755 insertions(+), 3 deletions(-) create mode 100644 src/Bot/Model/Entity/Template/Template.php create mode 100644 src/Bot/Model/Entity/Template/TemplateVariables.php create mode 100644 src/Bot/Model/Request/TemplateSendRequest.php create mode 100644 tests/Bot/Tests/TemplatesTest.php create mode 100644 tests/Resources/templates.json diff --git a/src/Bot/Client.php b/src/Bot/Client.php index fe0b59d..9a0784d 100644 --- a/src/Bot/Client.php +++ b/src/Bot/Client.php @@ -11,9 +11,8 @@ namespace RetailCrm\Mg\Bot; use Psr\Http\Message\ResponseInterface; -use RetailCrm\Common\Url; use RetailCrm\Common\Serializer; -use RetailCrm\Mg\Bot\Model\ModelAdapter; +use RetailCrm\Common\Url; use RetailCrm\Mg\Bot\Model\Entity\Bot; use RetailCrm\Mg\Bot\Model\Entity\Channel\Channel; use RetailCrm\Mg\Bot\Model\Entity\Chat\Chat; @@ -22,13 +21,15 @@ use RetailCrm\Mg\Bot\Model\Entity\Command; use RetailCrm\Mg\Bot\Model\Entity\Customer; use RetailCrm\Mg\Bot\Model\Entity\Dialog; use RetailCrm\Mg\Bot\Model\Entity\Message\Message; +use RetailCrm\Mg\Bot\Model\Entity\Template\Template; use RetailCrm\Mg\Bot\Model\Entity\User; +use RetailCrm\Mg\Bot\Model\ModelAdapter; use RetailCrm\Mg\Bot\Model\Request\UploadFileByUrlRequest; use RetailCrm\Mg\Bot\Model\Response\AssignResponse; -use RetailCrm\Mg\Bot\Model\Response\UnassignResponse; use RetailCrm\Mg\Bot\Model\Response\ErrorOnlyResponse; use RetailCrm\Mg\Bot\Model\Response\FullFileResponse; use RetailCrm\Mg\Bot\Model\Response\MessageSendResponse; +use RetailCrm\Mg\Bot\Model\Response\UnassignResponse; use RetailCrm\Mg\Bot\Model\Response\UploadFileResponse; /** @@ -460,6 +461,38 @@ class Client return $adapter->getResponseModel($response); } + + /** + * Returns templates list + * + * @return array + * @throws \Exception + */ + public function templates() + { + $response = $this->client->makeRequest( + '/templates', + HttpClient::METHOD_GET + ); + + $adapter = new ModelAdapter(Template::class); + + return $adapter->getResponseList($response); + } + + public function templateSend(string $templateId, Model\Request\TemplateSendRequest $request) + { + $response = $this->client->makeRequest( + sprintf('/templates/%d/send', $templateId), + HttpClient::METHOD_POST, + $request + ); + + $adapter = new ModelAdapter(MessageSendResponse::class); + + return $adapter->getResponseModel($response); + } + /** * Returns filtered users list * diff --git a/src/Bot/Model/Entity/Template/Template.php b/src/Bot/Model/Entity/Template/Template.php new file mode 100644 index 0000000..c4ea038 --- /dev/null +++ b/src/Bot/Model/Entity/Template/Template.php @@ -0,0 +1,385 @@ +id; + } + + /** + * @param int $id + */ + public function setId(int $id): void + { + $this->id = $id; + } + + /** + * @return string|null + */ + public function getCode(): ?string + { + return $this->code; + } + + /** + * @param string $code + */ + public function setCode(string $code): void + { + $this->code = $code; + } + + /** + * @return int|null + */ + public function getChannelId(): ?int + { + return $this->channelId; + } + + /** + * @param int $channelId + */ + public function setChannelId(int $channelId): void + { + $this->channelId = $channelId; + } + + /** + * @return string|null + */ + public function getName(): ?string + { + return $this->name; + } + + /** + * @param string $name + */ + public function setName(string $name): void + { + $this->name = $name; + } + + /** + * @return bool|null + */ + public function getEnabled(): ?bool + { + return $this->enabled; + } + + /** + * @param bool $enabled + */ + public function setEnabled(bool $enabled): void + { + $this->enabled = $enabled; + } + + /** + * @return string|null + */ + public function getType(): ?string + { + return $this->type; + } + + /** + * @param string $type + */ + public function setType(string $type): void + { + $this->type = $type; + } + + /** + * @return array|null + */ + public function getTemplate(): ?array + { + return $this->template; + } + + /** + * @param mixed $template + */ + public function setTemplate($template): void + { + $this->template = $template; + } + + /** + * @return string|null + */ + public function getBody(): ?string + { + return $this->body; + } + + /** + * @param string $body + */ + public function setBody(string $body): void + { + $this->body = $body; + } + + /** + * @return string|null + */ + public function getVerificationStatus(): ?string + { + return $this->verificationStatus; + } + + /** + * @param string $verificationStatus + */ + public function setVerificationStatus(string $verificationStatus): void + { + $this->verificationStatus = $verificationStatus; + } + + /** + * @return string|null + */ + public function getLang(): ?string + { + return $this->lang; + } + + /** + * @param string $lang + */ + public function setLang(string $lang): void + { + $this->lang = $lang; + } + + /** + * @return string|null + */ + public function getCategory(): ?string + { + return $this->category; + } + + /** + * @param string $category + */ + public function setCategory(string $category): void + { + $this->category = $category; + } + + /** + * @return string|null + */ + public function getRejectionReason(): ?string + { + return $this->rejectionReason; + } + + /** + * @param string $rejectionReason + */ + public function setRejectionReason(string $rejectionReason): void + { + $this->rejectionReason = $rejectionReason; + } + + /** + * @return string|null + */ + public function getQuality(): ?string + { + return $this->quality; + } + + public function setQuality(string $quality): void + { + $this->quality = $quality; + } + + /** + * @return array|null + */ + public function getHeader(): ?array + { + return $this->header; + } + + /** + * @param array $header + */ + public function setHeader(array $header): void + { + $this->header = $header; + } + + /** + * @return array|null + */ + public function getButtons(): ?array + { + return $this->buttons; + } + + /** + * @param array $buttons + */ + public function setButtons(array $buttons): void + { + $this->buttons = $buttons; + } +} diff --git a/src/Bot/Model/Entity/Template/TemplateVariables.php b/src/Bot/Model/Entity/Template/TemplateVariables.php new file mode 100644 index 0000000..8469a29 --- /dev/null +++ b/src/Bot/Model/Entity/Template/TemplateVariables.php @@ -0,0 +1,88 @@ + $buttons + * + * @Type("array") + * @Accessor(getter="getButtons",setter="setButtons") + */ + private $buttons; + + /** + * @return array|null + */ + public function getHeader(): ?array + { + return $this->header; + } + + /** + * @param array $header + */ + public function setHeader(array $header): void + { + $this->header = $header; + } + + /** + * @return array|null + */ + public function getBody(): ?array + { + return $this->body; + } + + /** + * @param array $body + */ + public function setBody(array $body): void + { + $this->body = $body; + } + + /** + * @return array[]|null + */ + public function getButtons(): ?array + { + return $this->buttons; + } + + /** + * @param array[] $buttons + */ + public function setButtons(array $buttons): void + { + $this->buttons = $buttons; + } +} diff --git a/src/Bot/Model/Request/TemplateSendRequest.php b/src/Bot/Model/Request/TemplateSendRequest.php new file mode 100644 index 0000000..0dfd6e6 --- /dev/null +++ b/src/Bot/Model/Request/TemplateSendRequest.php @@ -0,0 +1,77 @@ +phone; + } + + /** + * @param string $phone + */ + public function setPhone(string $phone): void + { + $this->phone = $phone; + } + + /** + * @return TemplateVariables|null + */ + public function getArgs(): ?TemplateVariables + { + return $this->args; + } + + /** + * @param TemplateVariables $args + */ + public function setArgs(TemplateVariables $args): void + { + $this->args = $args; + } +} diff --git a/tests/Bot/Tests/TemplatesTest.php b/tests/Bot/Tests/TemplatesTest.php new file mode 100644 index 0000000..696c4d5 --- /dev/null +++ b/tests/Bot/Tests/TemplatesTest.php @@ -0,0 +1,113 @@ +getJsonResponse('templates') + ); + + $response = $client->templates(); + + static::assertCount(2, $response, "Incorrect templates count"); + static::assertInstanceOf(Template\Template::class, $response[0], "Incorrect template instance"); + + $templateType = $response[0]->getHeader()['content']['type']; + static::assertStringContainsString("video", $templateType, "Incorrect template type"); + } + + /** + * @group("templates") + * @throws \Exception + */ + public function testTemplateSendNotFound() + { + $this->expectException(NotFoundException::class); + + $client = self::getApiClient( + null, + null, + false, + $this->getErrorsResponse(404, "template id=3 was not found") + ); + + $request = new TemplateSendRequest(); + $request->setPhone('123'); + + $client->templateSend(3, $request); + } + + /** + * @group("templates") + * @throws \Exception + */ + public function testTemplateSendVariablesError() + { + $this->expectException(NotFoundException::class); + + $client = self::getApiClient( + null, + null, + false, + $this->getErrorsResponse(404, "variables number doesn't match template") + ); + + $request = new TemplateSendRequest(); + $request->setPhone('123'); + + $client->templateSend(2, $request); + } + + /** + * @group("templates") + * @throws \Exception + */ + public function testTemplateSendSuccess() + { + $client = self::getApiClient( + null, + null, + false, + $this->getResponse( + '{"message_id":4242,"time":"2019-06-24T06:02:04.434291791Z"}', + 201 + ) + ); + + $request = new TemplateSendRequest(); + $request->setPhone('123'); + + $response = $client->templateSend(1, $request); + + self::assertInstanceOf(MessageSendResponse::class, $response); + + if ($response instanceof MessageSendResponse) { + self::assertTrue($response->isSuccessful()); + self::assertCount(0, $response->getErrors()); + self::assertEquals(4242, $response->getMessageId()); + } + } +} diff --git a/tests/Resources/templates.json b/tests/Resources/templates.json new file mode 100644 index 0000000..9ee1e08 --- /dev/null +++ b/tests/Resources/templates.json @@ -0,0 +1,56 @@ +[ + { + "id": 1, + "code": "test1#ru", + "channel_id": 1, + "name": "test1", + "enabled": true, + "type": "media", + "template": [ + "test1Template" + ], + "body": "test1Template", + "lang": "ru", + "category": "marketing", + "verification_status": "approved", + "header": { + "content": { + "type": "video" + } + } + }, + { + "id": 2, + "code": "test2#ru", + "channel_id": 5, + "name": "test2", + "enabled": true, + "type": "media", + "template": [ + "Вы не завершили покупку на нашем сайте.\n", + { + "var": "custom" + }, + "Пройдите по ссылке чтобы оформить заказ." + ], + "body": "Вы не завершили покупку на нашем сайте.\n{{1}}Пройдите по ссылке чтобы оформить заказ.", + "lang": "ru", + "category": "marketing", + "verification_status": "approved", + "header": { + "content": { + "body": "Товары в вашей корзине ждут вас!", + "type": "text" + } + }, + "buttons": { + "items": [ + { + "label": "Перейти в корзину", + "url": "https://test-url/{{1}}", + "type": "url" + } + ] + } + } +] \ No newline at end of file