Notifly в PrestaShop
PrestaShop расширяется модулями, которые подписываются на хуки ядра. Соберём
компактный модуль notiflyalerts, который вешается на три ключевых хука:
actionValidatedOrder (новый заказ), actionCustomerAccountAdd (регистрация) и
actionUpdateQuantity (товар закончился). Всё серверное, никакого JS на фронте.
Функцию-helper notifly_send() берём общую — ту же, что и для остальных CMS.
В модуле её удобно вынести в приватный метод, а URL и токен хранить в
конфигурации через Configuration::get().
Скелет модуля
Заголовок раздела «Скелет модуля»modules/notiflyalerts/└── notiflyalerts.phpnotiflyalerts.php:
<?phpif (!defined('_PS_VERSION_')) { exit;}
class NotiflyAlerts extends Module{ public function __construct() { $this->name = 'notiflyalerts'; $this->tab = 'administration'; $this->version = '1.0.0'; $this->author = 'Notifly'; parent::__construct(); $this->displayName = 'Notifly Alerts'; $this->description = 'Push-уведомления о заказах, клиентах и остатках.'; }
public function install(): bool { return parent::install() && $this->registerHook('actionValidatedOrder') && $this->registerHook('actionCustomerAccountAdd') && $this->registerHook('actionUpdateQuantity') && Configuration::updateValue('NOTIFLY_URL', 'https://your-notifly.example.com') && Configuration::updateValue('NOTIFLY_TOKEN', 'AGdjfk_L.dKe8q'); }
public function uninstall(): bool { Configuration::deleteByName('NOTIFLY_URL'); Configuration::deleteByName('NOTIFLY_TOKEN'); return parent::uninstall(); }
/** Универсальный helper (та же логика, что в /cases/cms/). */ private function send(string $title, string $message, int $priority = 5): void { $url = Configuration::get('NOTIFLY_URL'); $token = Configuration::get('NOTIFLY_TOKEN'); if (!$url || !$token) { return; }
$body = json_encode([ 'title' => mb_substr($title, 0, 200), 'message' => mb_substr($message, 0, 1500), 'priority' => $priority, ], JSON_UNESCAPED_UNICODE);
$ch = curl_init("$url/message?token=$token"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => ['Content-Type: application/json'], CURLOPT_POSTFIELDS => $body, CURLOPT_TIMEOUT => 5, ]); curl_exec($ch); curl_close($ch); }Хук: новый заказ
Заголовок раздела «Хук: новый заказ»actionValidatedOrder срабатывает, когда заказ подтверждён и оплата принята —
именно тот момент, ради которого стоит поднять телефон:
public function hookActionValidatedOrder(array $params): void { /** @var Order $order */ $order = $params['order']; $customer = $params['customer'];
$lines = []; foreach ($order->getProducts() as $p) { $lines[] = "• {$p['product_name']} × {$p['product_quantity']}"; }
$this->send( "🛒 Заказ #{$order->reference} — " . Tools::displayPrice($order->total_paid), "Покупатель: {$customer->firstname} {$customer->lastname}\n" . "Оплата: {$order->payment}\n\n" . "Состав:\n" . implode("\n", $lines) . "\n\n" . "Админка: заказ #{$order->id}", 9 // заказы — громкий приоритет ); }Хук: новый клиент
Заголовок раздела «Хук: новый клиент» public function hookActionCustomerAccountAdd(array $params): void { /** @var Customer $customer */ $customer = $params['newCustomer']; $this->send( "👤 Новый клиент: {$customer->firstname} {$customer->lastname}", "Email: {$customer->email}\n" . "ID: {$customer->id}", 4 ); }Хук: товар вышел в ноль
Заголовок раздела «Хук: товар вышел в ноль»actionUpdateQuantity вызывается при любом изменении остатка. Шлём push только
когда товар пересёк порог, чтобы не спамить на каждую продажу:
public function hookActionUpdateQuantity(array $params): void { $quantity = (int) $params['quantity']; if ($quantity > 3) { return; }
$product = new Product((int) $params['id_product'], false, (int) $this->context->language->id);
$this->send( "📦 Товар на исходе: {$product->name}", "Остаток: $quantity шт.\n" . "ID товара: {$params['id_product']}", $quantity <= 0 ? 8 : 6 ); }}(закрывающая } завершает класс модуля)
Где включить модуль
Заголовок раздела «Где включить модуль»- Заархивируйте папку
notiflyalertsи загрузите через Модули → Менеджер модулей → Загрузить модуль. - После установки задайте
NOTIFLY_URL/NOTIFLY_TOKEN— можно прямо вConfigurationили добавить страницу настроек черезgetContent().
Хуки регистрируются в методе install(), так что дополнительно вешать их не
нужно.
Тротлинг
Заголовок раздела «Тротлинг»Чтобы массовое обновление остатков (например, из 1С) не завалило канал,
кэшируйте отправку через Cache:
$cacheKey = 'notifly_' . md5($title);if (Cache::getInstance()->get($cacheKey)) { return;}Cache::getInstance()->set($cacheKey, 1, 60);- Заказ виден мгновенно.
actionValidatedOrder— это уже оплаченный заказ. - Не теряете товар в нуле. Push о нулевом остатке = вовремя пополнили склад.
- Свой модуль вместо платных «alert»-аддонов из PrestaShop Addons.
Что улучшить дальше
Заголовок раздела «Что улучшить дальше»- Страница настроек модуля с выбором каналов и порогов.
- Разные каналы Notifly для заказов, клиентов и склада.
- Deep-link на заказ через extras.