1
0
mirror of synced 2024-11-24 12:46:02 +03:00

Add templates interaction

This commit is contained in:
Alex Komarichev 2024-06-24 20:21:41 +03:00
parent a05cf2cc09
commit 8a20b86b17
6 changed files with 755 additions and 3 deletions

View File

@ -11,9 +11,8 @@
namespace RetailCrm\Mg\Bot; namespace RetailCrm\Mg\Bot;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use RetailCrm\Common\Url;
use RetailCrm\Common\Serializer; 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\Bot;
use RetailCrm\Mg\Bot\Model\Entity\Channel\Channel; use RetailCrm\Mg\Bot\Model\Entity\Channel\Channel;
use RetailCrm\Mg\Bot\Model\Entity\Chat\Chat; 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\Customer;
use RetailCrm\Mg\Bot\Model\Entity\Dialog; use RetailCrm\Mg\Bot\Model\Entity\Dialog;
use RetailCrm\Mg\Bot\Model\Entity\Message\Message; 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\Entity\User;
use RetailCrm\Mg\Bot\Model\ModelAdapter;
use RetailCrm\Mg\Bot\Model\Request\UploadFileByUrlRequest; use RetailCrm\Mg\Bot\Model\Request\UploadFileByUrlRequest;
use RetailCrm\Mg\Bot\Model\Response\AssignResponse; 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\ErrorOnlyResponse;
use RetailCrm\Mg\Bot\Model\Response\FullFileResponse; use RetailCrm\Mg\Bot\Model\Response\FullFileResponse;
use RetailCrm\Mg\Bot\Model\Response\MessageSendResponse; use RetailCrm\Mg\Bot\Model\Response\MessageSendResponse;
use RetailCrm\Mg\Bot\Model\Response\UnassignResponse;
use RetailCrm\Mg\Bot\Model\Response\UploadFileResponse; use RetailCrm\Mg\Bot\Model\Response\UploadFileResponse;
/** /**
@ -460,6 +461,38 @@ class Client
return $adapter->getResponseModel($response); 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 * Returns filtered users list
* *

View File

@ -0,0 +1,385 @@
<?php
/**
* PHP version 7.1
*
* Template entity
*
* @package RetailCrm\Mg\Bot\Model\Entity\Template
*/
namespace RetailCrm\Mg\Bot\Model\Entity\Template;
use RetailCrm\Mg\Bot\Model\ModelInterface;
use JMS\Serializer\Annotation\Accessor;
use JMS\Serializer\Annotation\SkipWhenEmpty;
use JMS\Serializer\Annotation\Type;
/**
* Template class
*
* @package RetailCrm\Mg\Bot\Model\Entity\Template
*/
class Template implements ModelInterface
{
/**
* @var int $id
*
* @Type("int")
* @Accessor(getter="getId",setter="setId")
*/
private $id;
/**
* @var string $code
*
* @Type("string")
* @Accessor(getter="getCode",setter="setCode")
*/
private $code;
/**
* @var int $channelId
*
* @Type("int")
* @Accessor(getter="getChannelId",setter="setChannelId")
*/
private $channelId;
/**
* @var string $name
*
* @Type("string")
* @Accessor(getter="getName",setter="setName")
*/
private $name;
/**
* @var bool $enabled
*
* @Type("bool")
* @Accessor(getter="getEnabled",setter="setEnabled")
*/
private $enabled;
/**
* @var string $type
*
* @Type("string")
* @Accessor(getter="getType",setter="setType")
*/
private $type;
/**
* @var array $template
*
* @Type("array")
* @Accessor(getter="getTemplate",setter="setTemplate")
*/
private $template;
/**
* @var string $body
*
* @Type("string")
* @Accessor(getter="getBody",setter="setBody")
*/
private $body;
/**
* @var string $lang
*
* @Type("string")
* @Accessor(getter="getLang",setter="setLang")
*/
private $lang;
/**
* @var string $category
*
* @Type("string")
* @Accessor(getter="getCategory",setter="setCategory")
*/
private $category;
/**
* @var string $verificationStatus
*
* @Type("string")
* @Accessor(getter="getVerificationStatus",setter="setVerificationStatus")
*/
private $verificationStatus;
/**
* @var string $rejectionReason
*
* @Type("string")
* @Accessor(getter="getRejectionReason",setter="setRejectionReason")
*/
private $rejectionReason;
/**
* @var string $quality
*
* @Type("string")
* @Accessor(getter="getQuality",setter="setQuality")
* @SkipWhenEmpty()
*/
private $quality;
/**
* @var array $header
*
* @Type("array")
* @Accessor(getter="getHeader",setter="setHeader")
* @SkipWhenEmpty()
*/
private $header;
/**
* @var array $header
*
* @Type("array")
* @Accessor(getter="getButtons",setter="setButtons")
* @SkipWhenEmpty()
*/
private $buttons;
/**
* @return int|null
*/
public function getId(): ?int
{
return $this->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;
}
}

View File

@ -0,0 +1,88 @@
<?php
namespace RetailCrm\Mg\Bot\Model\Entity\Template;
use JMS\Serializer\Annotation\Accessor;
use JMS\Serializer\Annotation\SkipWhenEmpty;
use JMS\Serializer\Annotation\Type;
use RetailCrm\Mg\Bot\Model\ModelInterface;
/**
* TemplateVariables class
*
* @package RetailCrm\Mg\Bot\Model\Entity\Template
*/
class TemplateVariables implements ModelInterface
{
/**
* @var array $header
*
* @Type("array")
* @Accessor(getter="getHeader",setter="setHeader")
*/
private $header;
/**
* @var array $body
*
* @Type("array")
* @Accessor(getter="getBody",setter="setBody")
*/
private $body;
/**
* @var array<array> $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;
}
}

View File

@ -0,0 +1,77 @@
<?php
/**
* PHP version 7.1
*
* Template send request
*
* @package RetailCrm\Mg\Bot\Model\Request
*/
namespace RetailCrm\Mg\Bot\Model\Request;
use JMS\Serializer\Annotation\Accessor;
use JMS\Serializer\Annotation\SkipWhenEmpty;
use JMS\Serializer\Annotation\Type;
use RetailCrm\Mg\Bot\Model\Entity\Template\TemplateVariables;
use RetailCrm\Mg\Bot\Model\ModelInterface;
use Symfony\Component\Validator\Constraints as Assert;
/**
* TemplateSendRequest class
*
* @package RetailCrm\Mg\Bot\Model\Request
*/
class TemplateSendRequest implements ModelInterface
{
/**
* @var string $phone
*
* @Type("string")
* @Accessor(getter="getPhone",setter="setPhone")
*
* @Assert\NotBlank
*/
private $phone;
/**
* @var TemplateVariables $args
*
* @Type("RetailCrm\Mg\Bot\Model\Entity\Template\TemplateVariables")
* @Accessor(getter="getArgs",setter="setArgs")
* @SkipWhenEmpty()
*/
private $args;
/**
* @return string
*/
public function getPhone(): string
{
return $this->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;
}
}

View File

@ -0,0 +1,113 @@
<?php
namespace RetailCrm\Mg\Bot\Tests;
use RetailCrm\Common\Exception\NotFoundException;
use RetailCrm\Mg\Bot\Model\Request\TemplateSendRequest;
use RetailCrm\Mg\Bot\Model\Response\MessageSendResponse;
use RetailCrm\Mg\Bot\Test\TestCase;
use RetailCrm\Mg\Bot\Model\Entity\Template;
/**
* PHP version 7.0
*
* Class TemplatesTest
*
* @package RetailCrm\Mg\Bot\Tests
*/
class TemplatesTest extends TestCase
{
/**
* @group("templates")
* @throws \Exception
*/
public function testTemplatesList()
{
$client = self::getApiClient(
null,
null,
false,
$this->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());
}
}
}

View File

@ -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"
}
]
}
}
]