Pull to refresh
35.17
Exolve
Конструктор омниканальных диалогов для бизнеса

Как получать SMS, когда в МойСклад поступает предоплата

Level of difficultyEasy
Reading time6 min
Views351

Сегодня мы поговорим о том, как реализовать автоматическую отправку SMS-уведомлений через платформу МТС Exolve при получении предоплаты в сервисе МойСклад.

Кейс из жизни

В логистической компании менеджер обычно работает по стандартному договору: запускает заказ после предоплаты от клиента. Чтобы не ждать подтверждения из бухгалтерии и не отвлекаться от текущих задач, можно настроить отправку SMS-уведомления сразу после зачисления средств на счёт. Так менеджер моментально даст распоряжение сотрудникам и запустит процесс доставки.

Настройка

Чтобы реализовать систему, потребуется:

  1. Сервис управления товарооборотом МойСклад — учётная система, где фиксируются финансовые операции

  2. Платформа для отправки SMS-уведомлений МТС Exolve — сервис отправки сообщений клиентам и сотрудникам по заданным условиям

  3. Настройка интеграции между МойСклад и МТС Exolve с помощью API

Для успешной реализации проекта подключим API МойСклад и МТС Exolve, настроим правильную интеграцию между сервисами. Разработаем сценарий обработки предоплат с автоматической отправкой SMS-уведомлений.

Порядок работы системы:

Фиксация платежа

  • Клиент переводит предоплату на счёт компании

  • МойСклад регистрирует поступление средств на счёт компании

Автоматическая отправка SMS

  • Настроенный сценарий в МойСклад автоматически передаёт информацию о платеже в сервис Exolve

  • Exolve формирует SMS и отправляет его на номер ответственного менеджера

Реакция менеджера

  • Получив уведомление, менеджер оперативно принимает решение и отдаёт распоряжение складу и водителям для начала выполнения заказа.

Работа с API МойСкладдля обработки предоплат

В ERP МойСклад есть удобный JSON API для работы с предоплатами. Код сущности предоплаты — ключевое слово prepayment. Чтобы получить список всех предоплат, можно использовать контекстный поиск с параметром search, который ищет строки по одному полю одновременно, без использования сложной токенизации. Так мы быстро и эффективно будем обрабатывать данные.

Начнём реализацию проекта на языке php: инициализируем его и установим требуемые зависимости. Теперь определим, как будет устроен наш проект: 

moysklad_sms/
├── src/
│   ├── SmsSender.php      # Реализация функционала отправки SMS
│  ├── MoySkladClient.php # Взаимодействие с системой "МойСклад" для получения данных
│  ├── Worker.php         # Организация параллельной обработки задач рассылки SMS
│   ├── main.php           # Главный исполняемый файл
├── .env                   # Конфигурационный файл
├── composer.json          # Файл зависимостей

Выполним необходимые команды для создания проекта и установки требуемых зависимостей:

mkdir moysklad_sms
cd moysklad_sms
composer init
composer require vlucas/phpdotenv guzzlehttp/guzzle

В конфигурационный файл .env запишем пять строк:

MOYSKLAD_API_KEY=ваш_ключ_от_мойсклад
MOYSKLAD_BASE_URL=https://online.moysklad.ru/api/remap/1.2
EXOLVE_API_KEY=ваш_ключ_от_exolve
EXOLVE_SENDER=номер_отправителя
MANAGER_PHONE=номер_менеджера

Настройка автозагрузки в composer.json. Этот блок указывает Composer, что классы из пространства имён App находятся в директории src/.

"autoload": {
   "psr-4": {
       "App\\": "src/"
   }
}

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

composer dump-autoload

Извлечение данных о предоплатах из МойСклад

Файл (src/MoySkladClient.php) отвечает за получение списка заказов с предоплатой:

<?php
namespace App;
use GuzzleHttp\Client;
use Dotenv\Dotenv;
use GuzzleHttp\Exception\RequestException;
class MoySkladClient
{
   private Client $client;
   private string $baseUrl;
   private string $apiKey;
   public function __construct()
   {
       $dotenv = Dotenv::createImmutable(__DIR__ . '/../');
       $dotenv->load();
       $this->baseUrl = $_ENV['MOYSKLAD_BASE_URL'];
       $this->apiKey = $_ENV['MOYSKLAD_API_KEY'];
       $this->client = new Client();
   }
   public function getPrepaidOrders(): array
   {
       $url = "{$this->baseUrl}/entity/prepayment";
       try {
           $response = $this->client->get($url, [
               'headers' => [
                   'Authorization' => 'Basic ' . base64_encode($this->apiKey),
                   'Accept'        => 'application/json',
               ],
           ]);
       } catch (RequestException $exception) {
     echo "Произошла ошибка при выполнении запроса: " . $exception->getMessage() . PHP_EOL;
           return [];
       }
       return json_decode($response->getBody(), true) ?? [];
   }
}

В (src/SmsSender.php) создадим логику отправки SMS:

<?php
namespace App;
use GuzzleHttp\Client;
class SmsSender
{
   private Client $client;
   private string $apiKey;
   private string $sender;
   public function __construct()
   {
       $this->client = new Client();
       $this->apiKey = $_ENV['EXOLVE_API_KEY'];
       $this->sender = $_ENV['EXOLVE_SENDER'];
   }
   public function sendSMS(string $to, string $message): bool
   {
       $url = 'https://api.exolve.ru/sms/v1/send';
       $data = [
           'from'    => $this->sender,
           'to'      => $to,
           'message' => $message,
       ];
       for ($i = 0; $i < 3; $i++) { // 3 попытки
           try {
               $response = $this->client->post($url, [
                   'headers' => [
                       'Authorization' => "Bearer {$this->apiKey}",
                       'Content-Type'  => 'application/json',
                   ],
                   'json' => $data,
               ]);
               if ($response->getStatusCode() === 200) {
                   echo "SMS отправлено: $to\n";
                   return true;
               }
           } catch (\Exception $exception) {
               echo "Ошибка отправки SMS (попытка " . ($i + 1) . "): " . $exception->getMessage() . PHP_EOL;
           }
       }
       return false;
   }
}

Для обработки большого объёма номеров используем многопоточный подход. В (src/Worker.php) реализуем логику работы с очередью:

<?php
namespace App;
class Worker
{
   public function process(array $prepayments)
   {
       $managerPhone = $_ENV['MANAGER_PHONE'];
       if (!$managerPhone) {
           die("Ошибка: номер менеджера не указан в .env\n");
       }
       $smsSender = new SmsSender();
       $children = [];
       foreach ($prepayments as $prepayment) {
           $pid = pcntl_fork();
           if ($pid == -1) {
               die("Ошибка создания процесса\n");
           } elseif ($pid) {
               $children[] = $pid;
           } else {
               // Дочерний процесс
               $this->handlePrepayment($prepayment, $smsSender, $managerPhone);
               exit(0);
           }
       }
       // Ждем завершения всех дочерних процессов
       foreach ($children as $child) {
           pcntl_waitpid($child, $status);
       }
   }
   private function handlePrepayment(array $prepayment, SmsSender $smsSender, string $managerPhone)
   {
       $managerMessage = "Заказ {$prepayment['id']} получил предоплату от {$prepayment['agent']['name']}.";
       $clientMessage = "Ваша предоплата успешно получена! Спасибо за покупку.";
       // Отправка SMS менеджеру
       if ($smsSender->sendSMS($managerPhone, $managerMessage)) {
           echo date('Y/m/d H:i:s') . " SMS успешно отправлено менеджеру: $managerPhone\n";
       } else {
           echo date('Y/m/d H:i:s') . " Ошибка отправки SMS менеджеру: $managerPhone\n";
       }
       // Отправка SMS клиенту
       if (!empty($prepayment['agent']['phone'])) {
           if ($smsSender->sendSMS($prepayment['agent']['phone'], $clientMessage)) {
               echo date('Y/m/d H:i:s') . " SMS успешно отправлено клиенту: {$prepayment['agent']['phone']}\n";
           } else {
               echo date('Y/m/d H:i:s') . " Ошибка отправки SMS клиенту: {$prepayment['agent']['phone']}\n";
           }
       }
   }
}

Основной исполняемый файл (src/index.php).

<?php
require __DIR__ . '/../vendor/autoload.php';
use App\MoySkladClient;
use App\Worker;
use Dotenv\Dotenv;
$dotenv = Dotenv::createImmutable(__DIR__ . '/../');
$dotenv->load();
$moySklad = new MoySkladClient();
$prepayments = $moySklad->getPrepaidOrders();
if (empty($prepayments)) {
   die("Нет предоплат для обработки.\n");
} else {
   echo date('Y/m/d H:i:s') . " Получено " . count($prepayments) . " предоплаты из \"МойСклад\"\n";
}
$worker = new Worker();
$worker->process($prepayments);
echo date('Y/m/d H:i:s') . " Все SMS успешно отправлены\n";

Запуск программы

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

php src/index.php

В итоге получим примерно следующий вывод:

/var/www/html/moysklad_sms # php src/index.php
2025/03/05 00:36:22 Получено 3 предоплаты из "МойСклад"
2025/03/05 00:36:23 SMS успешно отправлено менеджеру: +79123456789
2025/03/05 00:36:24 SMS успешно отправлено клиенту: +79876543210
2025/03/05 00:36:25 SMS успешно отправлено менеджеру: +79123456789
2025/03/05 00:36:26 SMS успешно отправлено клиенту: +79876543211
2025/03/05 00:36:27 SMS успешно отправлено менеджеру: +79123456789
2025/03/05 00:36:28 SMS успешно отправлено клиенту: +79876543212
2025/03/05 00:36:29 Все SMS успешно отправлены

Скриншоты полученных сообщений

Для менеджера

Для клиента

Вот и всё! Теперь у нас есть проект по автоматической отправке SMS-уведомлений при получении предоплаты в МойСклад. Решение экономит время, автоматизирует процессы и повышает прозрачность работы.

Система гибкая, её легко адаптировать под различные задачи, например, добавив напоминания о скидках или уведомления о завершении операции.

Tags:
Hubs:
Total votes 5: ↑4 and ↓1+5
Comments1

Articles

Information

Website
exolve.ru
Founded
Employees
501–1,000 employees