[Программирование, Разработка под e-commerce, Управление e-commerce] Интеграция интернет-магазина на 1С-Битрикс с Mindbox
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Для развития систем лояльности интернет-магазины обращаются к платформам автоматизации маркетинга, Customer Data Platform (CDP). При этом иногда для успешной интеграции нужно сохранять больше данных, чем указано в документации к API.
Рассказываем, какие данные понадобились нам для интеграции магазина на «1С-Битрикс» с платформой Mindbox, как их можно получить с помощью API и SDK и как использовать комбинированный подход с асинхронной отправкой данных.
С помощью сервисов Customer Data Platform ритейлеры «узнают» портрет своего покупателя, в том числе поведенческие данные. Эта информация хранится в CDP в защищенном виде и помогает ритейлерам в проведении маркетинговых кампаний и аналитике.
Когда покупатель добавляет в корзину телевизор или любой другой товар, CDP сохраняет эти данные. На их основе ритейлеры получают возможность расширить свое взаимодействие с пользователями, например предложить рекомендации и скидки на похожие товары.
Один из наших клиентов — сеть магазинов электроники — принял решение подключиться к CDP-платформе Mindbox и обратился к нам за помощью в интеграции. Мы проводили интеграцию по ключевым пользовательским сценариям: авторизация, добавление в корзину, оплата и др.
Предыстория
Интернет-магазины могут подключиться к Mindbox двумя основными способами: с помощью API либо JavaScript SDK (об отличиях мы расскажем далее).
Для выбора оптимального способа мы обратились к документации Mindbox, а если информации не хватало, то задавали вопросы менеджеру. Мы выяснили, что наше сотрудничество совпало с периодом бурного роста платформы Mindbox: среднесуточная нагрузка по вызовам API Mindbox увеличилась вдвое (до 120 тысяч запросов в минуту, в пик — до 250 тысяч). Это означало, что в период Черной пятницы и прочих распродаж из-за дополнительного роста нагрузки возникал риск, что CDP-сервис окажется недоступен и не получит данные интернет-магазина, который с ним интегрирован.
Mindbox быстро отреагировал на эту проблему и начал улучшать архитектуру и инфраструктуру своих IT-систем, чтобы добиться четырехкратного запаса прочности. Нам, в свою очередь, нужно было обеспечить бесперебойную отправку в Mindbox данных о покупках. Для этого требовалось выбрать самый надежный способ интеграции.
Методы интеграции с Mindbox
Как отмечено выше, Mindbox предлагает использовать для подключения API или JavaScript SDK. Далее рассмотрим их особенности.
- JavaScript SDK
Библиотека-«обёртка» над API, предоставляемая сервисом. Её плюсы — простота интеграции и возможность асинхронной передачи данных. Оптимально подходит для тех случаев, когда нужно поддерживать только web-платформу.
Ограничения: возможна потеря данных, если Mindbox недоступен в момент отправки. Скрипты платформы не подгрузятся, если на стороне интернет-магазина есть js-ошибки.
- Интеграция по API
Интеграцию магазина с Mindbox можно провести через API. Этот способ снижает зависимость от JavaScript и также подходит для настройки асинхронной отправки данных.
Ограничения: мы столкнулись с тем, что не получали некоторые данные cookie, а именно уникальный идентификатор пользователя на устройстве (mindboxDeviceUUID). Его необходимо передавать в большинстве операций Mindbox для склеивания информации по пользователю.
В документации эти cookie обязательны не для всех операций. И всё же, стремясь к бесперебойной передаче данных, мы обсудили этот вопрос с менеджером Mindbox. Выяснили, что для максимальной надежности желательно всегда отправлять cookie. При этом для получения cookie нужно использовать JavaScript SDK.
Комбинированный метод
Мы рассмотрели описанные выше способы интеграции, но в чистом виде они не подходили для нашего проекта. Для решения бизнес-задач ритейлера и построения системы лояльности нужно было передавать в Mindbox полный набор данных о действиях пользователей, включая идентификатор из cookie. Одновременно с этим мы стремились снизить зависимость от JavaScript и риски потери данных в случае временной недоступности Mindbox.
Поэтому мы обратились к третьему, комбинированному методу: работаем и с API, и с JavaScript SDK, используя наш модуль очередей.
С помощью Javascript SDK мы идентифицируем пользователя на сайте (mindboxDeviceUUID). Затем на стороне сервера формируем запрос со всеми необходимыми данными и помещаем его в очередь. Запросы из очереди через API отправляются сервису Mindbox. В случае отрицательного ответа запрос повторно помещается в очередь. Таким образом, при отправке данных Mindbox получает полный комплект необходимой информации.
В приведенном далее примере класс Sender позволяет собрать и отправить запрос, выполнив первичную обработку ответа. Класс использует данные из самой команды (тип запроса/ответа, deviceUUID и др.) и из настроек модуля (параметры работы с API, токены и т.п.).
<?php
declare(strict_types=1);
namespace Simbirsoft\MindBox;
use Bitrix\Main\Web\Uri;
use Bitrix\Main\Web\HttpClient;
use Simbirsoft\Base\Converters\ConverterFactory;
use Simbirsoft\MindBox\Contracts\SendableCommand;
class Sender
{
/** @var Response Тело ответа */
protected $response;
/** @var SendableCommand Команда */
protected $command;
/**
* Sender constructor.
*
* @param SendableCommand $command
*/
public function __construct(SendableCommand $command)
{
$this->command = $command;
}
/**
* Сформировать массив заголовков запроса.
*
* @return array
*/
protected function getHeaders(): array
{
return [
'Accept' => Type\ContentType::REQUEST[$this->command->getRequestType()],
'Content-Type' => Type\ContentType::RESPONSE[$this->command->getResponseType()],
'Authorization' => 'Mindbox secretKey="'. Options::get('secretKey') .'"',
'User-Agent' => $this->command->getHttpInfo('HTTP_USER_AGENT'),
'X-Customer-IP' => $this->command->getHttpInfo('REMOTE_ADDR'),
];
}
/**
* Сформировать адрес запроса.
*
* @return string
*/
protected function getUrl(): string
{
$uriParts = [
Options::get('apiUrl'),
$this->command->getOperationType(),
];
$uriParams = [
'operation' => $this->command->getOperation(),
'endpointId' => Options::get('endpointId'),
];
$deviceUUID = $this->command->getHttpInfo('deviceUUID');
if (!empty($deviceUUID)) {
$uriParams['deviceUUID'] = $deviceUUID;
}
return (new Uri(implode('/', $uriParts)))
->addParams($uriParams)
->getUri();
}
/**
* Отправить запрос.
*
* @return bool
*/
public function send(): bool
{
$httpClient = new HttpClient();
$headers = $this->getHeaders();
foreach ($headers as $name => $value) {
$httpClient->setHeader($name, $value, false);
}
$encodedData = null;
$request = $this->command->getRequestData();
if (!empty($request)) {
$converter = ConverterFactory::factory($this->command->getRequestType());
$encodedData = $converter->encode($request);
}
$url = $this->getUrl();
if ($httpClient->query($this->command->getMethod(), $url, $encodedData)) {
$converter = ConverterFactory::factory($this->command->getResponseType());
$response = $converter->decode($httpClient->getResult());
$this->response = new Response($response);
return true;
}
return false;
}
/**
* @return Response
*/
public function getResponse(): Response
{
return $this->response;
}
}
Трейт Sendable содержит все возможные настройки команды для отправки запроса в Mindbox, в том числе предустановленные, такие как тип запроса/ответа, метод запроса и параметр синхронности/асинхронности. Также в нем присутствуют методы, общие для всех команд.
<?php
declare(strict_types=1);
namespace Simbirsoft\MindBox\Traits;
use RuntimeException;
use Bitrix\Main\Context;
use Simbirsoft\MindBox\Type;
use Simbirsoft\MindBox\Sender;
use Simbirsoft\MindBox\Response;
use Bitrix\Main\Localization\Loc;
use Simbirsoft\MindBox\Contracts\SendableCommand;
Loc::loadMessages($_SERVER['DOCUMENT_ROOT'] .'/local/modules/simbirsoft.base/lib/Contracts/Command.php');
trait Sendable
{
/** @var string Метод отправки (GET/POST) */
protected $method = Type\OperationMethod::POST;
/** @var string Тип операции (sync/async) */
protected $operationType = Type\OperationType::ASYNC;
/** @var string Тип запроса (json/xml) */
protected $requestType = Type\ContentType::JSON;
/** @var string Тип ответа (json/xml) */
protected $responseType = Type\ContentType::JSON;
/** @var array Вспомогательные данные */
protected $data = [];
/**
* Название операции.
* @return string
*/
abstract public function getOperation(): string;
/**
* Формируем данные.
*
* @return array
*/
abstract public function getRequestData(): array;
/**
* HTTP метод запроса
*
* @return string
*/
public function getMethod(): string
{
return $this->method;
}
/**
* Тип операции
*
* @return string
*
* @noinspection PhpUnused
*/
public function getOperationType(): string
{
return $this->operationType;
}
/**
* Тип запроса.
*
* @return string
*
* @noinspection PhpUnused
*/
public function getRequestType(): string
{
return $this->requestType;
}
/**
* Тип ответа.
*
* @return string
*
* @noinspection PhpUnused
*/
public function getResponseType(): string
{
return $this->responseType;
}
/**
* Вспомогательные данные запроса
*
* @return void
*/
public function initHttpInfo(): void
{
$server = Context::getCurrent()->getServer();
$request = Context::getCurrent()->getRequest();
$this->data = [
'X-Customer-IP' => $server->get('REMOTE_ADDR'),
'User-Agent' => $server->get('HTTP_USER_AGENT'),
'deviceUUID' => $request->getCookieRaw('mindboxDeviceUUID'),
];
}
/**
* Получить вспомогательные данные запроса
*
* @param string $key
* @param string $default
*
* @return string
*
* @noinspection PhpUnused
*/
public function getHttpInfo(string $key, string $default = ''): string
{
return $this->data[$key] ?? $default;
}
/**
* Выполняем команду.
*
* @return void
*
* @throws RuntimeException
*/
public function execute(): void
{
/** @var SendableCommand $thisCommand */
$thisCommand = $this;
$sender = new Sender($thisCommand);
if ($sender->send()) {
throw new RuntimeException(Loc::getMessage('BASE_COMMAND_NOT_EXECUTED'));
}
$response = $sender->getResponse();
if (!$response->isSuccess()) {
throw new RuntimeException(Loc::getMessage('BASE_COMMAND_NOT_EXECUTED'));
}
if (!$this->prepareResponse($response)) {
throw new RuntimeException(Loc::getMessage('BASE_COMMAND_NOT_EXECUTED'));
}
}
/**
* Обработка ответа запроса.
*
* @param Response $response
*
* @return bool
*/
public function prepareResponse(Response $response): bool
{
// $body = $response->getBody();
// $status = $body['customer']['processingStatus'];
/**
* Возможные статусы:
* AuthenticationSucceeded - Если пароль верен
* AuthenticationFailed - Если пароль не верен
* NotFound - Если потребитель не найден
*/
return true;
}
}
В качестве примера рассмотрим событие авторизации пользователя. В обработчике события авторизации мы добавляем в нашу очередь объект класса AuthorizationCommand. В этом классе происходит минимально необходимая подготовка информации, поскольку в момент выполнения команды данные в базе могут измениться, и нужно их сохранить. Также устанавливаются соответствующие параметры для запроса в Mindbox, в данном случае это название операции (узнаем в админ. панели Mindbox). Дополнительно можно указать тип запроса/ответа, метод запроса и параметр синхронности/асинхронности согласно трейту Sendable.
<?php
declare(strict_types=1);
namespace Simbirsoft\MindBox\Commands;
use Simbirsoft\Queue\Traits\Queueable;
use Simbirsoft\MindBox\Traits\Sendable;
use Simbirsoft\Queue\Contracts\QueueableCommand;
use Simbirsoft\MindBox\Contracts\SendableCommand;
final class AuthorizationCommand implements QueueableCommand, SendableCommand
{
use Queueable, Sendable;
/** @var array Данные пользователя */
protected $user;
/**
* AuthorizationCommand constructor.
*
* @param array $user
*/
public function __construct(array $user)
{
$keys = ['ID', 'EMAIL', 'PERSONAL_MOBILE'];
$this->user = array_intersect_key($user, array_flip($keys));
$this->initHttpInfo();
}
/**
* Название операции.
*
* @return string
*/
public function getOperation(): string
{
return 'AuthorizationOnWebsite';
}
/**
* Формируем данные.
*
* @return array
*/
public function getRequestData(): array
{
return [
'customer' => [
'email' => $this->user['EMAIL'],
],
];
}
}
Схема взаимодействия модулей
В нашем проекте мы выделили три модуля:
- Базовый
Служит для хранения общих вспомогательных классов и интерфейсов (например, интерфейсов команд), которые можно потом использовать во всем проекте.
- Модуль очередей
Взаимодействие с Mindbox реализовано через команды. Для их последовательного выполнения мы используем наш модуль очередей. Этот модуль сохраняет поступившие команды и выполняет их, когда наступает время выполнения.
- Модуль интеграции с Mindbox
Этот модуль «ловит» события на сайте, такие, как авторизация, регистрация, создание заказа, добавление в корзину и прочие, а затем формирует команды и отправляет их в модуль очередей.
Модуль Mindbox отслеживает на сайте события и сопутствующую информацию, в том числе из cookie, формирует из них команду и помещает её в очередь. Когда модуль очередей извлекает команду из очереди и выполняет её, происходит отправка данных. Если ответ от Mindbox отрицательный — неудачно выполненная команда переносится в конец очереди, если положительный — успешно выполненная команда удаляется из очереди.
Таким образом, с помощью описанного выше комбинированного метода мы смогли обеспечить бесперебойную передачу данных в Mindbox.
Подводя итоги
В этой статье мы рассмотрели, какими способами интернет-магазин может подключиться к Customer Data Platform для развития систем лояльности.
В нашем примере в документации Mindbox были описаны два основных способа подключения: через Javascript SDK и через API. Для повышения надежности передачи данных, даже в случае временной недоступности CDP-сервиса, мы выбрали и реализовали третий, комбинированный способ: с помощью API и Javascript SDK, с асинхронной отправкой данных.
Спасибо за внимание! Надеемся, эта статья была для вас полезна.
===========
Источник:
habr.com
===========
Похожие новости:
- [JavaScript, Программирование, Разработка веб-сайтов] Что за черт, JavaScript?
- [Анализ и проектирование систем, Программирование, Проектирование и рефакторинг, Управление разработкой] Архитектурный слой. Понятие, определение, представление
- [Angular, Dart, Программирование] Зоны в Dart: большой брат следит за тобой
- [.NET, C#, Квантовые технологии, Программирование] Создайте свой собственный симулятор Q# — Часть 1 (перевод)
- [Go, Программирование] Языковая механика профилирования памяти (перевод)
- [JavaScript, Python, Программирование, Разработка веб-сайтов] Надоел JavaScript — используй браузерный Python (перевод)
- [Open source, OpenStreetMap, Визуализация данных, Научно-популярное, Программирование] Делаем маршрутизацию (роутинг) на OpenStreetMap. Введение
- [Контент-маркетинг, Конференции, Научно-популярное] Великолепная семерка: технари, ставшие выдающимися литераторами
- [SQL, Веб-аналитика, Интернет-маркетинг] Обзор основных функций Google BigQuery и примеры запросов для маркетинг-анализа
- [Big Data, Data Engineering, Карьера в IT-индустрии, Машинное обучение] Дата-инженеры в бизнесе: кто они и чем занимаются?
Теги для поиска: #_programmirovanie (Программирование), #_razrabotka_pod_ecommerce (Разработка под e-commerce), #_upravlenie_ecommerce (Управление e-commerce), #_mindbox, #_javascript_sdk, #_customer_data_platform, #_marketing (маркетинг), #_modul_ocheredej (модуль очередей), #_ritejl (ритейл), #_ecommerce, #_1sbitriks (1С-Битрикс), #_bitriks (Битрикс), #_blog_kompanii_simbirsoft (
Блог компании SimbirSoft
), #_programmirovanie (
Программирование
), #_razrabotka_pod_ecommerce (
Разработка под e-commerce
), #_upravlenie_ecommerce (
Управление e-commerce
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 23-Ноя 03:24
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Для развития систем лояльности интернет-магазины обращаются к платформам автоматизации маркетинга, Customer Data Platform (CDP). При этом иногда для успешной интеграции нужно сохранять больше данных, чем указано в документации к API. Рассказываем, какие данные понадобились нам для интеграции магазина на «1С-Битрикс» с платформой Mindbox, как их можно получить с помощью API и SDK и как использовать комбинированный подход с асинхронной отправкой данных. С помощью сервисов Customer Data Platform ритейлеры «узнают» портрет своего покупателя, в том числе поведенческие данные. Эта информация хранится в CDP в защищенном виде и помогает ритейлерам в проведении маркетинговых кампаний и аналитике. Когда покупатель добавляет в корзину телевизор или любой другой товар, CDP сохраняет эти данные. На их основе ритейлеры получают возможность расширить свое взаимодействие с пользователями, например предложить рекомендации и скидки на похожие товары. Один из наших клиентов — сеть магазинов электроники — принял решение подключиться к CDP-платформе Mindbox и обратился к нам за помощью в интеграции. Мы проводили интеграцию по ключевым пользовательским сценариям: авторизация, добавление в корзину, оплата и др. Предыстория Интернет-магазины могут подключиться к Mindbox двумя основными способами: с помощью API либо JavaScript SDK (об отличиях мы расскажем далее). Для выбора оптимального способа мы обратились к документации Mindbox, а если информации не хватало, то задавали вопросы менеджеру. Мы выяснили, что наше сотрудничество совпало с периодом бурного роста платформы Mindbox: среднесуточная нагрузка по вызовам API Mindbox увеличилась вдвое (до 120 тысяч запросов в минуту, в пик — до 250 тысяч). Это означало, что в период Черной пятницы и прочих распродаж из-за дополнительного роста нагрузки возникал риск, что CDP-сервис окажется недоступен и не получит данные интернет-магазина, который с ним интегрирован. Mindbox быстро отреагировал на эту проблему и начал улучшать архитектуру и инфраструктуру своих IT-систем, чтобы добиться четырехкратного запаса прочности. Нам, в свою очередь, нужно было обеспечить бесперебойную отправку в Mindbox данных о покупках. Для этого требовалось выбрать самый надежный способ интеграции. Методы интеграции с Mindbox Как отмечено выше, Mindbox предлагает использовать для подключения API или JavaScript SDK. Далее рассмотрим их особенности.
Библиотека-«обёртка» над API, предоставляемая сервисом. Её плюсы — простота интеграции и возможность асинхронной передачи данных. Оптимально подходит для тех случаев, когда нужно поддерживать только web-платформу. Ограничения: возможна потеря данных, если Mindbox недоступен в момент отправки. Скрипты платформы не подгрузятся, если на стороне интернет-магазина есть js-ошибки.
Интеграцию магазина с Mindbox можно провести через API. Этот способ снижает зависимость от JavaScript и также подходит для настройки асинхронной отправки данных. Ограничения: мы столкнулись с тем, что не получали некоторые данные cookie, а именно уникальный идентификатор пользователя на устройстве (mindboxDeviceUUID). Его необходимо передавать в большинстве операций Mindbox для склеивания информации по пользователю. В документации эти cookie обязательны не для всех операций. И всё же, стремясь к бесперебойной передаче данных, мы обсудили этот вопрос с менеджером Mindbox. Выяснили, что для максимальной надежности желательно всегда отправлять cookie. При этом для получения cookie нужно использовать JavaScript SDK. Комбинированный метод Мы рассмотрели описанные выше способы интеграции, но в чистом виде они не подходили для нашего проекта. Для решения бизнес-задач ритейлера и построения системы лояльности нужно было передавать в Mindbox полный набор данных о действиях пользователей, включая идентификатор из cookie. Одновременно с этим мы стремились снизить зависимость от JavaScript и риски потери данных в случае временной недоступности Mindbox. Поэтому мы обратились к третьему, комбинированному методу: работаем и с API, и с JavaScript SDK, используя наш модуль очередей. С помощью Javascript SDK мы идентифицируем пользователя на сайте (mindboxDeviceUUID). Затем на стороне сервера формируем запрос со всеми необходимыми данными и помещаем его в очередь. Запросы из очереди через API отправляются сервису Mindbox. В случае отрицательного ответа запрос повторно помещается в очередь. Таким образом, при отправке данных Mindbox получает полный комплект необходимой информации. В приведенном далее примере класс Sender позволяет собрать и отправить запрос, выполнив первичную обработку ответа. Класс использует данные из самой команды (тип запроса/ответа, deviceUUID и др.) и из настроек модуля (параметры работы с API, токены и т.п.). <?php
declare(strict_types=1); namespace Simbirsoft\MindBox; use Bitrix\Main\Web\Uri; use Bitrix\Main\Web\HttpClient; use Simbirsoft\Base\Converters\ConverterFactory; use Simbirsoft\MindBox\Contracts\SendableCommand; class Sender { /** @var Response Тело ответа */ protected $response; /** @var SendableCommand Команда */ protected $command; /** * Sender constructor. * * @param SendableCommand $command */ public function __construct(SendableCommand $command) { $this->command = $command; } /** * Сформировать массив заголовков запроса. * * @return array */ protected function getHeaders(): array { return [ 'Accept' => Type\ContentType::REQUEST[$this->command->getRequestType()], 'Content-Type' => Type\ContentType::RESPONSE[$this->command->getResponseType()], 'Authorization' => 'Mindbox secretKey="'. Options::get('secretKey') .'"', 'User-Agent' => $this->command->getHttpInfo('HTTP_USER_AGENT'), 'X-Customer-IP' => $this->command->getHttpInfo('REMOTE_ADDR'), ]; } /** * Сформировать адрес запроса. * * @return string */ protected function getUrl(): string { $uriParts = [ Options::get('apiUrl'), $this->command->getOperationType(), ]; $uriParams = [ 'operation' => $this->command->getOperation(), 'endpointId' => Options::get('endpointId'), ]; $deviceUUID = $this->command->getHttpInfo('deviceUUID'); if (!empty($deviceUUID)) { $uriParams['deviceUUID'] = $deviceUUID; } return (new Uri(implode('/', $uriParts))) ->addParams($uriParams) ->getUri(); } /** * Отправить запрос. * * @return bool */ public function send(): bool { $httpClient = new HttpClient(); $headers = $this->getHeaders(); foreach ($headers as $name => $value) { $httpClient->setHeader($name, $value, false); } $encodedData = null; $request = $this->command->getRequestData(); if (!empty($request)) { $converter = ConverterFactory::factory($this->command->getRequestType()); $encodedData = $converter->encode($request); } $url = $this->getUrl(); if ($httpClient->query($this->command->getMethod(), $url, $encodedData)) { $converter = ConverterFactory::factory($this->command->getResponseType()); $response = $converter->decode($httpClient->getResult()); $this->response = new Response($response); return true; } return false; } /** * @return Response */ public function getResponse(): Response { return $this->response; } } Трейт Sendable содержит все возможные настройки команды для отправки запроса в Mindbox, в том числе предустановленные, такие как тип запроса/ответа, метод запроса и параметр синхронности/асинхронности. Также в нем присутствуют методы, общие для всех команд. <?php
declare(strict_types=1); namespace Simbirsoft\MindBox\Traits; use RuntimeException; use Bitrix\Main\Context; use Simbirsoft\MindBox\Type; use Simbirsoft\MindBox\Sender; use Simbirsoft\MindBox\Response; use Bitrix\Main\Localization\Loc; use Simbirsoft\MindBox\Contracts\SendableCommand; Loc::loadMessages($_SERVER['DOCUMENT_ROOT'] .'/local/modules/simbirsoft.base/lib/Contracts/Command.php'); trait Sendable { /** @var string Метод отправки (GET/POST) */ protected $method = Type\OperationMethod::POST; /** @var string Тип операции (sync/async) */ protected $operationType = Type\OperationType::ASYNC; /** @var string Тип запроса (json/xml) */ protected $requestType = Type\ContentType::JSON; /** @var string Тип ответа (json/xml) */ protected $responseType = Type\ContentType::JSON; /** @var array Вспомогательные данные */ protected $data = []; /** * Название операции. * @return string */ abstract public function getOperation(): string; /** * Формируем данные. * * @return array */ abstract public function getRequestData(): array; /** * HTTP метод запроса * * @return string */ public function getMethod(): string { return $this->method; } /** * Тип операции * * @return string * * @noinspection PhpUnused */ public function getOperationType(): string { return $this->operationType; } /** * Тип запроса. * * @return string * * @noinspection PhpUnused */ public function getRequestType(): string { return $this->requestType; } /** * Тип ответа. * * @return string * * @noinspection PhpUnused */ public function getResponseType(): string { return $this->responseType; } /** * Вспомогательные данные запроса * * @return void */ public function initHttpInfo(): void { $server = Context::getCurrent()->getServer(); $request = Context::getCurrent()->getRequest(); $this->data = [ 'X-Customer-IP' => $server->get('REMOTE_ADDR'), 'User-Agent' => $server->get('HTTP_USER_AGENT'), 'deviceUUID' => $request->getCookieRaw('mindboxDeviceUUID'), ]; } /** * Получить вспомогательные данные запроса * * @param string $key * @param string $default * * @return string * * @noinspection PhpUnused */ public function getHttpInfo(string $key, string $default = ''): string { return $this->data[$key] ?? $default; } /** * Выполняем команду. * * @return void * * @throws RuntimeException */ public function execute(): void { /** @var SendableCommand $thisCommand */ $thisCommand = $this; $sender = new Sender($thisCommand); if ($sender->send()) { throw new RuntimeException(Loc::getMessage('BASE_COMMAND_NOT_EXECUTED')); } $response = $sender->getResponse(); if (!$response->isSuccess()) { throw new RuntimeException(Loc::getMessage('BASE_COMMAND_NOT_EXECUTED')); } if (!$this->prepareResponse($response)) { throw new RuntimeException(Loc::getMessage('BASE_COMMAND_NOT_EXECUTED')); } } /** * Обработка ответа запроса. * * @param Response $response * * @return bool */ public function prepareResponse(Response $response): bool { // $body = $response->getBody(); // $status = $body['customer']['processingStatus']; /** * Возможные статусы: * AuthenticationSucceeded - Если пароль верен * AuthenticationFailed - Если пароль не верен * NotFound - Если потребитель не найден */ return true; } } В качестве примера рассмотрим событие авторизации пользователя. В обработчике события авторизации мы добавляем в нашу очередь объект класса AuthorizationCommand. В этом классе происходит минимально необходимая подготовка информации, поскольку в момент выполнения команды данные в базе могут измениться, и нужно их сохранить. Также устанавливаются соответствующие параметры для запроса в Mindbox, в данном случае это название операции (узнаем в админ. панели Mindbox). Дополнительно можно указать тип запроса/ответа, метод запроса и параметр синхронности/асинхронности согласно трейту Sendable. <?php
declare(strict_types=1); namespace Simbirsoft\MindBox\Commands; use Simbirsoft\Queue\Traits\Queueable; use Simbirsoft\MindBox\Traits\Sendable; use Simbirsoft\Queue\Contracts\QueueableCommand; use Simbirsoft\MindBox\Contracts\SendableCommand; final class AuthorizationCommand implements QueueableCommand, SendableCommand { use Queueable, Sendable; /** @var array Данные пользователя */ protected $user; /** * AuthorizationCommand constructor. * * @param array $user */ public function __construct(array $user) { $keys = ['ID', 'EMAIL', 'PERSONAL_MOBILE']; $this->user = array_intersect_key($user, array_flip($keys)); $this->initHttpInfo(); } /** * Название операции. * * @return string */ public function getOperation(): string { return 'AuthorizationOnWebsite'; } /** * Формируем данные. * * @return array */ public function getRequestData(): array { return [ 'customer' => [ 'email' => $this->user['EMAIL'], ], ]; } } Схема взаимодействия модулей В нашем проекте мы выделили три модуля:
Служит для хранения общих вспомогательных классов и интерфейсов (например, интерфейсов команд), которые можно потом использовать во всем проекте.
Взаимодействие с Mindbox реализовано через команды. Для их последовательного выполнения мы используем наш модуль очередей. Этот модуль сохраняет поступившие команды и выполняет их, когда наступает время выполнения.
Этот модуль «ловит» события на сайте, такие, как авторизация, регистрация, создание заказа, добавление в корзину и прочие, а затем формирует команды и отправляет их в модуль очередей. Модуль Mindbox отслеживает на сайте события и сопутствующую информацию, в том числе из cookie, формирует из них команду и помещает её в очередь. Когда модуль очередей извлекает команду из очереди и выполняет её, происходит отправка данных. Если ответ от Mindbox отрицательный — неудачно выполненная команда переносится в конец очереди, если положительный — успешно выполненная команда удаляется из очереди. Таким образом, с помощью описанного выше комбинированного метода мы смогли обеспечить бесперебойную передачу данных в Mindbox. Подводя итоги В этой статье мы рассмотрели, какими способами интернет-магазин может подключиться к Customer Data Platform для развития систем лояльности. В нашем примере в документации Mindbox были описаны два основных способа подключения: через Javascript SDK и через API. Для повышения надежности передачи данных, даже в случае временной недоступности CDP-сервиса, мы выбрали и реализовали третий, комбинированный способ: с помощью API и Javascript SDK, с асинхронной отправкой данных. Спасибо за внимание! Надеемся, эта статья была для вас полезна. =========== Источник: habr.com =========== Похожие новости:
Блог компании SimbirSoft ), #_programmirovanie ( Программирование ), #_razrabotka_pod_ecommerce ( Разработка под e-commerce ), #_upravlenie_ecommerce ( Управление e-commerce ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 23-Ноя 03:24
Часовой пояс: UTC + 5