Привет, Хабр! Меня зовут Екатерина Саяпина, я Product Owner платформы МТС Exolve. Сегодня мы поговорим об одной интересной и полезной фиче — автоматических SMS-оповещениях о снижении цены на товар из вишлиста.

Мы не будем использовать невероятные достижения искусственного интеллекта или блокчейна. Иногда самые простые и приземленные вещи могут принести гораздо больше профита и бизнесу, и клиентам. В этом кейсе мы будем фиксировать добавление товара в вишлист, сравнивать текущую цену с последней и отправлять СМС при ее снижении.

Зачем это нужно?

Представьте типичный сценарий: пользователь бродит по вашему интернет-магазину, присматривает товары, добавляет самые желанные в «Избранное». Но по каким-то причинам не оформляет заказ. Может, цена кусается, а может, решил сравнить с конкурентами. Или просто отвлекся на котиков в Telegram.

И вот товар из вишлиста внезапно попадает под распродажу, а пользователь об этом ни сном ни духом. В такой ситуации уведомления о снижении цены уже не выглядят назойливо. Получить такое сообщение куда приятнее, чем случайно заметить, что товар уже распродан. Такой сценарий дает рост конверсии. Когда человеку напоминают о скидке на желанный товар, вероятность покупки значительно повышается.

Но тут важно не переборщить, чтобы забота не превратилась в назойливость. Поэтому дадим пользователю возможность управлять настройками рассылки, укажем в самом сообщении способ отписки. В общем, будем вести себя максимально деликатно и ненавязчиво, не забыв добавить на сайт галочку, позволяющую отказаться от уведомлений.

Детали реализации

Хватит лирики, перейдем к техническим нюансам. Для примера рассмотрим сайт на WordPress, WooCommerce в качестве плагина для работы с товарами и, собственно, Exolve API для отправки SMS.

Шаг 1. Реализуем вишлист

Первым делом нужно дать пользователям возможность добавлять товары в «Избранное». С WooCommerce эта задача легко решается плагином YITH WooCommerce Wishlist. Он позволяет реализовать нужные функции буквально в два клика.

Шаг 2. Ставим на Cron регулярную проверку цен

// Регистрация Cron-задачи
function register_price_check_cron() {
    if (!wp_next_scheduled('check_price_drop')) {
        wp_schedule_event(time(), 'daily', 'check_price_drop');
    }
}
add_action('wp', 'register_price_check_cron');

Этот фрагмент кода отвечает за регистрацию нашей задачи в планировщике WordPress. Функция register_price_check_cron проверяет регистрацию задачи с ключом check_price_drop. Это важно, чтобы не создавать дубликаты при каждом обновлении страницы. Если такой задачи еще нет, она добавляется с помощью функции wp_schedule_event. Time() указывает время первого запуска (в нашем случае — сразу после регистрации), daily — его периодичность (ежедневно), check_price_drop — ключ задачи.

Функция register_price_check_cron привязывается с помощью add_action к хуку wp, который срабатывает при каждой загрузке страницы в WordPress. Таким образом, при первом же заходе на сайт после добавления этого кода задача будет зарегистрирована и начнет выполняться ежедневно.

// Функция проверки цен
function check_price_drop() {
    global $wpdb;

    // Получаем список избранных товаров и их текущие цены
    $wishlist_items = $wpdb->get_results("SELECT * FROM wp_yith_wcwl WHERE price_drop_alert = 1");

    foreach ($wishlist_items as $item) {
        $current_price = get_post_meta($item->product_id, '_price', true);

        if ($current_price < $item->last_notified_price) {
            // Обновляем цену и отправляем уведомление
            update_price_notification($item->user_id, $item->product_id, $current_price);
        }
    }
}
add_action('check_price_drop', 'check_price_drop');

Теперь разберем саму функцию check_price_drop, запускаемую планировщиком.

Сначала мы делаем глобально доступной переменную $wpdb. Это объект класса wpdb, который предоставляет удобные методы для работы с базой данных WordPress. Можно было бы использовать чистый SQL, но с wpdb код становится более лаконичным и безопасным.

Дальше получаем из базы список всех избранных товаров, у которых установлен флаг price_drop_alert в значение 1 (о нем поговорим чуть позже). Вся магия происходит в SQL-запросе:

SELECT * FROM wp_yith_wcwl WHERE price_drop_alert = 1

Мы выбираем все записи из таблицы wp_yith_wcwl (это таблица плагина YITH WooCommerce Wishlist, в которой хранятся данные об избранных товарах), где поле price_drop_alert равно 1.

Проходимся по полученному списку в цикле foreach. Для каждого элемента (грубо говоря, строки таблицы) делаем следующее:

  1. Получаем текущую цену товара с помощью функции get_post_meta. WooCommerce хранит цены в метаполе _price, поэтому мы его и запрашиваем.

  2. Сравниваем текущую цену с последней, о которой мы уже сообщали (last_notified_price). Если текущая цена ниже, значит, пора отправлять новое уведомление.

  3. Вызываем функцию update_price_notification, передав ей ID пользователя, ID товара и новую цену. Эта функция обновит last_notified_price в базе (чтобы не спамить при каждой проверке) и вызовет отправку SMS через Exolve API. Код ее мы уже разбирали в предыдущем шаге.

Ну и в самом конце привязываем функцию check_price_drop к одноименному хуку с помощью add_action. Когда планировщик вызовет задачу check_price_drop (а при регистрации мы указали периодичность проверки раз в день), будет выполняться код нашей функции.

Теперь о флаге price_drop_alert. Он нужен, чтобы отправлять уведомления только по тем товарам, на которые пользователь явно подписался. Устанавливается он, например, когда ставится соответствующая галочка при добавлении товара в вишлист.

Хранить его можно прямо в таблице wp_yith_wcwl, добавив новый столбец price_drop_alert типа TINYINT(1). При попадании товара в вишлист, если галочка стоит, записываем в этот столбец 1, если ее нет — 0. А при удалении или отписке от уведомлений просто обнуляем это значение.

Шаг 3. Уведомляем клиента через Exolve API

Переходим непосредственно к отправке SMS. Тут нам понадобится аккаунт в Exolve и небольшая функция-обертка над API.

Функция send_price_alert_sms принимает три параметра: $user_id (ID пользователя, которому отправляем SMS), $product_id (ID товара, о котором уведомляем) и $price (новая цена).

Внутри функции мы сначала получаем номер телефона пользователя и название товара:

$user_phone = get_user_meta($user_id, 'phone', true);
$product_name = get_the_title($product_id);

Для получения телефона используем функцию get_user_meta. Она позволяет взять значение произвольного поля профиля пользователя в WordPress. В нашем случае предполагается, что телефон хранится в поле phone. Третий параметр true указывает, что мы хотим получить одно значение, а не массив. Это актуально, когда у метаполя может быть несколько значений.

Название товара получаем с помощью функции get_the_title, передав ей ID товара. Это стандартная функция WordPress, которая возвращает заголовок поста. Товар в WooCommerce — это тоже пост, но с типом product.

Дальше нам нужно сформировать URL для запроса к API Exolve и наш API-ключ:

$api_url = 'https://api.exolve.ru/messaging/v1/SendSMS';
$api_key = 'ВАШ_API_КЛЮЧ';

URL API для отправки SMS всегда одинаковый, он есть в документации. А вот API-ключ уникальный для каждого аккаунта, его нужно будет заменить на свой. Он есть в личном кабинете сервиса после регистрации.

Теперь формируем текст нашего сообщения:

$message = "Цена на товар '$product_name' снизилась до $price. Успейте купить!";

Здесь мы подставляем в заготовленную фразу название товара и его новую цену. Обратите внимание, что цену мы указываем без форматирования, просто как число. О красивом отображении позаботится сам клиент SMS.

Все данные готовы, можно отправлять запрос. Делаем это с помощью уже знакомой нам функции wp_remote_post:

$response = wp_remote_post($api_url, [
  'headers' => [
        'Authorization' => 'Bearer ' . $api_key,
        'Content-Type' => 'application/json',
    ],
    'body' => json_encode([
        'number' => 'ВАШ_АРЕНДОВАННЫЙ_НОМЕР_EXOLVE',
        'destination' => $user_phone,
        'text' => $message,
    ]),
]);

В заголовках запроса мы передаем два параметра:

  1. Authorization — для авторизации в API Exolve. Его значение должно быть в формате Bearer ВАШ_API_КЛЮЧ. Обратите внимание на пробел после слова Bearer, он обязателен.

  2. Content-Type — как и в случае с отправкой данных в CRM, указываем, что тип контента — JSON.

В теле запроса у нас три параметра:

  1. number — номер телефона, с которого будет отправлено SMS. Это должен быть один из номеров, арендованных в Exolve. Его также следует заменить на свой. Отдельно стоит помнить, что доставка СМС с мобильных номеров не гарантирована операторами получателей. Только около 30% доходят до адресата, поэтому лучше отправлять от индивидуального имени (альфа-имени).

  2. destination — номер телефона получателя. Здесь мы подставляем $user_phone, полученный в начале функции.

  3. text — текст нашего сообщения, который мы сформировали чуть выше.

Как и в случае с отправкой данных в CRM, тело запроса мы кодируем в JSON с помощью функции json_encode.

После отправки запроса мы сохраняем ответ сервера в переменную $response. Это будет объект класса WP_Error в случае ошибки или обычный массив, если все прошло успешно. Проверить успех отправки можно с помощью функции is_wp_error:

if (is_wp_error($response)) {
    error_log('Ошибка отправки SMS: ' . $response->get_error_message());
}

Если была ошибка, мы логируем ее с помощью функции error_log. Это позволит нам позже найти и исправить возможные проблемы. Текст ошибки получаем методом get_error_message объекта WP_Error.

Если ошибки не было, мы ничего не делаем. SMS было успешно отправлено, и наша функция выполнила свою задачу.

В реальном проекте стоило бы добавить больше обработок ошибок. Например, что делать, если у пользователя не указан номер телефона? Или что делать с уведомлением, если Exolve вернул ошибку? Отправлять еще раз или считать его неудачным? Также стоило бы проверять баланс SMS на аккаунте, чтобы не попасть в ситуацию, когда SMS не отправляются из-за нехватки средств. И учтите таймаут отправки, чтобы уведомления о снижениях цен не превратились в надоедливый спам.

Но даже в таком базовом виде наша функция send_price_alert_sms уже может уведомить пользователя о снижении цены на интересующий его товар. А с помощью track_sms_statistics, которую мы разобрали ранее, мы сможем оценить эффективность этих уведомлений и оптимизировать их под нашу аудиторию.

Шаг 4. Собираем аналитику

Передача данных в CRM для аналитики реализуется следующим образом. У нас есть функция track_sms_statistics, которая принимает три параметра: $user_id (ID пользователя, которому отправляем SMS), $product_id (ID товара, о котором уведомляем) и $price (новая цена).

function track_sms_statistics($user_id, $product_id, $price) {
    // ...
}

Внутри функции сначала мы задаем переменную $crm_url. Это URL эндпоинта в нашей CRM, на который мы будем отправлять данные. У каждой CRM он свой, так что не забудьте поменять его на актуальный для вашей системы.

$crm_url = 'https://yourcrm.example.com/api/track';

Дальше формируем массив $data с данными, которые хотим передать. Тут все просто: берем переданные в функцию $user_id, $product_id и $price и добавляем к ним еще один параметр — timestamp.

timestamp — это временная метка, показывающая, когда именно мы отправили SMS. Получаем ее с помощью функции current_time WordPress, указав формат mysql. Это значит, что время будет возвращено в формате "Y-m-d H:i:s", привычном для баз данных. Например, "2023-06-08 15:30:00".

Timestamp позволит нам в будущем анализировать, когда SMS эффективнее всего. Может оказаться, что сообщения, отправленные вечером, приводят к большему количеству покупок, чем утренние. Или наоборот. Имея эти данные, мы сможем оптимизировать время отправки уведомлений.

Итак, данные мы подготовили. Теперь нужно передать их в CRM. Для этого в WordPress есть функция wp_remote_post, которая позволяет делать POST-запросы к внешним сервисам:

wp_remote_post($crm_url, [
    'headers' => ['Content-Type' => 'application/json'],
    'body' => json_encode($data),
]);

Первым параметром она принимает URL, куда нужно отправить запрос (у нас это $crm_url), а вторым — массив опций.

В нем мы указываем два ключа: headers и body.

  • В headers мы передаем заголовки запроса. В нашем случае это только Content-Type со значением application/json. Это нужно, чтобы CRM поняла, в каком формате мы передаем данные.

  • В body мы помещаем сами данные, которые хотим передать. Но просто так взять и отправить массив мы не можем, сначала нам нужно преобразовать его в JSON-строку. Для этого используем функцию json_encode, которая принимает массив и возвращает его JSON-представление.

Например, если бы наш $data выглядел так:

$data = [
    'user_id' => 15,
    'product_id' => 28,
    'price' => 99.99,
    'timestamp' => '2023-06-08 15:30:00',
];

То после json_encode мы бы получили такую строку:

{
    "user_id": 15,
    "product_id": 28,
    "price": 99.99,
    "timestamp": "2023-06-08 15:30:00"
}

Именно эта строка и будет отправлена в теле нашего POST-запроса.

После того как wp_remote_post отработает, наша функция завершится. Мы не обрабатываем результат запроса (хотя это можно было бы сделать, проверив код ответа и залогировав возможные ошибки), потому что нам нужно просто передать данные в CRM. А вот что с ними делать дальше, это уже задача самой CRM.

Предположим, CRM умеет принимать такие запросы и сохранять их в свою базу данных. Тогда, имея историю всех отправленных SMS, мы сможем строить разнообразные отчеты и анализировать результаты нашей системы уведомлений.

Мы можем сравнивать эффективность SMS для разных категорий товаров, групп пользователей, дней недели и времени суток. Мы можем строить воронки продаж и смотреть, на каком этапе пользователи чаще всего «отваливаются». Для этого понадобится более глубокая интеграция с CRM и, возможно, дополнительная разметка событий на сайте (например, через Google Tag Manager). Но база для всего этого закладывается именно здесь, в этой небольшой функции track_sms_statistics.

Шаг 5. Даем пользователю контроль

Ну и напоследок — о настройках приватности. Добавьте где-нибудь в личном кабинете пользователя чекбокс, который будет включать/выключать отправку уведомлений о снижении цены. При добавлении товара в вишлист, если галочка стоит, ставим нашему price_drop_alert значение 1, если нет — 0. Все просто!

Ну и не забудьте про отписку. Рассылки не должны быть включены по умолчанию, и клиенту нужно обеспечить возможность от них отказаться.

Подводим итоги

Итак, сегодня мы на простом примере разобрались, как работает механизм SMS-уведомлений о снижении цен, зачем он нужен бизнесу и клиентам и как реализовать его технически на базе WordPress и API Exolve.

Это только один из возможных сценариев персонализированных рассылок. Поле для экспериментов тут огромное. Главное — всегда отталкиваться от реальных потребностей и болей ЦА, искать баланс между эффективностью для бизнеса и комфортом для клиента.

На этом у меня все. Подписывайтесь на наш блог, впереди еще много интересного. И да пребудет с вами сила персонализации!

Комментарии (0)