TL;DR: Создайте кастомный модуль для Drupal 10, внедрите `@http_client`, сохраните токен в Key и проверьте работу с помощью одной команды Drush, отправляющей запрос к `POST /messages/text`. Сделайте это до настройки вебхуков, очередей или административного интерфейса. Бесплатной песочницы Whapi.Cloud вполне достаточно, чтобы подтвердить работоспособность архитектуры.
Когда для Drupal 10 нужен именно кастомный модуль WhatsApp
Если цель заключается в создании многократно используемого механизма отправки сообщений в WhatsApp из Drupal 10, лучше начать с разработки кастомного модуля. Готовые фронтенд-виджеты и интерфейсные contrib-модули решают совсем другие задачи.
Нативная интеграция WhatsApp с Drupal всегда начинается с создания сервиса, а не виджета. Именно эта архитектурная развилка определяет, превратится ли ваш первый успех в поддерживаемый код или станет очередной панелью администратора, которую невозможно вызвать из обработчика событий, очереди или консольной команды.
| Вариант | Подходит для | Программная отправка | Повторное использование в Drupal | Статус поддержки | Когда выбирать |
|---|---|---|---|---|---|
| Интерфейсные модули вроде `whatsapp_button` или `whatsapp_bubble` | Создания точек входа Click-to-Chat (переход в чат по клику) | Отсутствует транспортный уровень для интеграции с бизнес-логикой | Низкий | Быстрая установка, узкая область применения | Вам нужна только кнопка чата на фронтенде |
| Contrib-модуль `whatsapp_cloud_api` | Экспериментов через панель администратора | Ограниченная отправка, привязанная к интерфейсу | В лучшем случае средний | Популярный проект на Drupal.org, но последнее обновление самого цитируемого модуля было в 2022 году | Вы тестируете концепцию, а не проектируете повторно используемый сервисный слой |
| Действия Brevo (Brevo actions) | Рассылок или автоматических цепочек с внешней платформы | Возможна, но вне сервисного контейнера Drupal | Низкий внутри кастомного PHP-кода | Отлично подходит для автоматизации маркетинга, но не дает полного контроля над кодом на стороне Drupal | Вам важнее готовая внешняя автоматизация, чем интеграция на уровне кода модуля |
| Кастомный модуль Drupal | Отправки исходящих сообщений на основе событий сайта | Да, из сервисов, консольных команд, контроллеров и очередей | Высокий | Требует больше усилий на старте, но гарантирует отличную масштабируемость | Вам нужен надежный и полностью контролируемый Drupal-код для отправки сообщений |
Несоответствие между потребностями разработчиков и готовыми решениями легко заметить по результатам поиска. Большинство статей о Drupal и WhatsApp посвящены виджетам чата, формам авторизации или действиям, запускаемым вручную администратором. В них редко описывается паттерн проектирования с упором на сервисный контейнер, необходимый в тех случаях, когда сообщение должно отправляться автоматически — например, при создании заказа, регистрации лида или вызове из кастомного контроллера.
Готовые интерфейсные модули
Модули вроде `whatsapp_button` и `whatsapp_bubble` отлично справляются со своей задачей, когда пользователю нужно просто перейти в чат. Однако они не предоставляют внедряемый сервис для отправки, построитель запросов или механизмы обработки ошибок для интеграции бизнес-логики WhatsApp внутрь Drupal.
Модули интеграции из репозитория Drupal
Официальный статус модуля `whatsapp_cloud_api` в экосистеме Drupal скорее заставляет задуматься о стабильности поддержки. Его ключевая часть — это конфигурационные формы, а последнее обновление датируется сентябрем 2022 года. Это не самый надежный фундамент, когда перед вами стоит задача написать надежный и расширяемый сервис для Drupal 10.
Когда кастомное решение — лучший выбор
Пишите собственный код, когда Drupal сам знает, в какой момент и почему должно быть отправлено сообщение. На практике разработчики интернет-магазинов на Drupal Commerce часто начинают с одного уведомления о заказе, генерируемого из кода сайта, а не из платформы чат-ботов. Схожим образом строятся системы уведомлений в недвижимости и медицине: сначала реализуется один надежный маршрут исходящей отправки, а сложная оркестрация добавляется позже.
Выбор подходящего бэкенда для WhatsApp API
Выберите решение, которое позволит быстро отправить первое сообщение и при этом не скроет реальные ограничения продакшена. Для целей нашего руководства Whapi.Cloud — самый короткий путь.
Whapi.Cloud предлагает максимально быстрый путь от пустого модуля до реального сообщения: сканирование QR-кода, получение токена, отправка POST-запроса — готово. Использование Meta Cloud API может быть правильным решением в долгосрочной перспективе для крупных компаний с жесткими требованиями к комплаенсу, однако оно требует прохождения сложной процедуры регистрации, прежде чем разработчик сможет отправить первое тестовое сообщение с сайта.
| Интеграция | Время до первой отправки | Барьеры для продакшена | Правила отправки для MVP | Сложность интеграции с Drupal 10 |
|---|---|---|---|---|
| Meta Cloud API | В тот же день (если все ресурсы Meta уже настроены), иначе несколько дней | Часто занимает дни или недели из-за подтверждения компании, настройки телефона, подписки на вебхуки и согласований | Официальные каналы накладывают ограничения на шаблоны сообщений и требуют соблюдения 24-часового окна поддержки клиентов | Выше, так как бюрократические и технические требования усложняют отладку кода на ранних этапах |
| Whapi.Cloud | Около 2 минут после сканирования QR-кода | Для тестового запуска и отправки MVP не требуется подтверждение компании в Meta | Нет ограничений на шаблоны для первых тестовых сообщений, что упрощает валидацию транспорта | Ниже, поскольку разработчик может сразу сосредоточиться на стандартном шаблоне HTTP-интеграции в Drupal |
Официальный Meta Cloud API
Здесь важно разделять тестовый запуск и полноценную работу. Начать тестирование в Meta можно быстрее, чем кажется многим командам, но развертывание в продакшене все равно затягивается. Необходимость подтверждения компании, регистрации номера и настройки вебхуков возникает еще до того, как интеграция станет стабильной. В рамках этой статьи мы не будем подробно разбирать процедуру Meta Business Verification, так как это отдельный процесс, не способствующий быстрому запуску кастомного модуля.
API-шлюзы
Решение Whapi.Cloud отлично подходит для нашего руководства, так как минимальный рабочий вариант (MVP) — это отправка одного исходящего текстового сообщения с сайта, а не выстраивание сложных цепочек комплаенса. Простая настройка через QR-код и бесплатная песочница предоставляют 5 активных чатов в месяц, 150 сообщений в день и 1000 запросов к API. Этого более чем достаточно для тестирования архитектуры, настройки хранения токенов, логирования и проверки через Drush перед тем, как связать отправку с реальными бизнес-событиями сайта.
Критерии выбора
Используйте официальный API от Meta, когда строгие требования платформы изначально прописаны в техническом задании. Выбирайте Whapi.Cloud, если нужно быстро создать кастомный модуль для Drupal 10 с возможностью протестировать отправку без лишних барьеров. Если у вас возникнет соблазн запустить собственный эмулятор веб-клиента WhatsApp, вспомните, к чему это обычно приводит: регулярным изменениям в протоколах со стороны WhatsApp, ошибкам 500 и бесконечной отладке кода, не имеющей никакого отношения к разработке самого сайта.
Структура модуля: сервис, конфигурация и внедрение зависимостей
Кастомный модуль должен выглядеть как стандартная интеграция Drupal, ведь именно ей он и является. Ограничьте транспортный код рамками одного сервиса и вызывайте его из любых других частей системы.
Внедрите сервис `@http_client` один раз, и любая функция отправки в WhatsApp станет повторно используемым кодом. Такое архитектурное решение позволит вызывать один и тот же метод отправки из команд Drush, контроллеров, обработчиков событий, очередей и тестов без дублирования транспортной логики.
Шаблон структуры файлов
Начните с малого. Вам понадобятся файлы описания модуля и сервисов, схема конфигурации, один класс клиента и один класс консольной команды Drush. Этого минимума достаточно для первой отправки.
name: Whapi Drupal
type: module
description: Drupal 10 custom module for outbound WhatsApp messaging.
core_version_requirement: ^10 || ^11
package: Custom
dependencies:
- key:key
Объявление сервиса services.yml и класс WhatsappApiClient
В файле описания сервисов стандарты Drupal становятся очевидными. Мы связываем HTTP-клиент, фабрику конфигураций, репозиторий Key и канал логирования в один транспортный класс. В дальнейшем его можно расширять в соответствии с документацией Whapi.Cloud API, не меняя структуру самого модуля.
services:
logger.channel.whapi_drupal:
parent: logger.channel_base
arguments: ['whapi_drupal']
whapi_drupal.client:
class: Drupal\whapi_drupal\Service\WhatsappApiClient
arguments:
- '@http_client'
- '@config.factory'
- '@key.repository'
- '@logger.channel.whapi_drupal'
<?php
namespace Drupal\whapi_drupal\Service;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\key\KeyRepositoryInterface;
use GuzzleHttp\ClientInterface;
use Psr\Log\LoggerInterface;
final class WhatsappApiClient {
public function __construct(
private ClientInterface $httpClient,
private ConfigFactoryInterface $configFactory,
private KeyRepositoryInterface $keyRepository,
private LoggerInterface $logger,
) {}
}
Внедрение зависимости http_client против статических вызовов
Drupal уже оборачивает Guzzle в свой сервисный контейнер. Используйте этот стандартный механизм вместо написания сырых cURL-запросов или вызова статических методов контейнера. Это упрощает написание тестов для клиента, исключает дублирование кода и соответствует стандартам разработки, на которые будут опираться остальные части вашего модуля.
Безопасное хранение ключей API в Drupal
Отделяйте секретные значения от остальных настроек модуля. Стандартный механизм конфигураций Drupal предназначен для хранения флагов и связей, а для хранения конфиденциальных токенов лучше использовать модуль Key.
Сохраняйте ID ключа в конфигурации, а сам токен — в модуле Key. Никогда не храните токен в открытом виде в коде модуля или экспортируемых YAML-файлах конфигурации. В этом заключается разница между учебным примером и реальным коммерческим кодом, авторы которого заботятся о том, чтобы приватные ключи не попали в репозиторий git.
Настройка модуля Key
Создайте сущность Key в системе Drupal и укажите её ID в настройках вашего модуля. Наиболее безопасный паттерн — настроить модуль Key так, чтобы он получал значение из переменных окружения сервера, после чего ваш модуль будет запрашивать готовое значение через `key.repository`.
Схема конфигурации
Схема конфигурации вашего модуля должна четко описывать все несекретные параметры: идентификатор канала или отправителя, ID ключа из модуля Key и любые другие настройки по умолчанию. Сам токен доступа здесь фигурировать не должен.
whapi_drupal.settings:
type: config_object
label: 'Whapi Drupal settings'
mapping:
channel_id:
type: string
label: 'Connected WhatsApp channel ID'
token_key:
type: string
label: 'Key entity ID for the Whapi token'
default_country_code:
type: string
label: 'Default country code for test sends'
Чего никогда не должно быть в файлах .module
Маршрутному токену не место в файлах `.module`, скопированных из блогов сниппетах или жестко прописанных значениях по умолчанию. Самая частая проблема таких интеграций — это не сбой в самом API-вызове, а случайная утечка конфиденциальных токенов в историю коммитов git сразу после презентации проекта.
Отправка первого исходящего сообщения
Когда структура модуля и безопасное хранение токенов настроены, логика отправки становится предельно простой. Сформируйте payload, отправьте его на проверенный эндпоинт и прочитайте ответ в виде структурированных данных.
Одного успешного POST-запроса к `/messages/text` достаточно, чтобы подтвердить правильность архитектуры. На этом этапе не нужны вебхуки, очереди или панели администратора. Достаточно иметь один воспроизводимый метод отправки, вызываемый из кода Drupal.
Формирование полезной нагрузки (payload)
Для отправки текстовых сообщений используется эндпоинт Whapi.Cloud `POST /messages/text`. Обязательными полями в теле запроса являются `to` (получатель) и `body` (текст сообщения), что идеально ложится на структуру метода в нашем Drupal-сервисе.
POST-запрос через внедренный HTTP-клиент
Ниже представлен код основного транспортного метода. Он извлекает токен доступа из Key, отправляет JSON-данные через стандартный внедренный HTTP-клиент Drupal, логирует ошибки со стороны внешнего сервиса и возвращает вызывающей стороне декодированные данные ответа.
<?php
use GuzzleHttp\Exception\RequestException;
public function sendText(string $to, string $body): array {
$config = $this->configFactory->get('whapi_drupal.settings');
$keyId = $config->get('token_key');
$token = $this->keyRepository->getKey($keyId)?->getKeyValue();
if (!$token) {
throw new \RuntimeException('Missing Whapi token in Key module.');
}
try {
$response = $this->httpClient->request('POST', 'https://gate.whapi.cloud/messages/text', [
'headers' => [
// If you skip this Bearer header, Whapi.Cloud returns 401 and the send never leaves Drupal.
'Authorization' => 'Bearer ' . $token,
'Content-Type' => 'application/json',
],
'json' => [
'to' => $to,
'body' => $body,
],
'timeout' => 15,
]);
return json_decode((string) $response->getBody(), TRUE, 512, JSON_THROW_ON_ERROR);
}
catch (RequestException $exception) {
$this->logger->error('Whapi send failed for {recipient}: {message}', [
'recipient' => $to,
'message' => $exception->getMessage(),
]);
throw $exception;
}
}
Обработка ответа API
Прочитайте полученный JSON-ответ и верните ID отправленного сообщения или его статус. При тестировании в песочнице важным сигналом о превышении лимитов будет код ошибки `402`. Код `401` обычно указывает на отсутствие или неверный формат токена, а `403` сигнализирует о том, что выбранный чат или получатель не могут принять сообщение при текущем состоянии канала связи.
Эти нюансы важны, поскольку лимиты песочницы ориентированы исключительно на отладку кода. Их не стоит рассматривать как тест производительности в реальных условиях. На этом этапе ваша задача — проверить саму архитектуру интеграции, а не объемы отправки.
Тестирование интеграции в среде Drupal
Проводите тесты там, где возникшие ошибки будут сразу заметны. Использование Drush обеспечивает более быструю обратную связь по сравнению с веб-интерфейсом и делает цикл отладки более компактным.
Проверьте интеграцию через Drush перед тем, как создавать формы в интерфейсе администратора. Вы сможете мгновенно увидеть исключения, структуру передаваемых данных и ответ сервера, что существенно сократит время отладки.
Написание команды Drush
Реализуйте вызов созданного сервиса в виде консольной команды Drush. Это даст быстрое подтверждение того, что Drupal корректно инициализирует клиент, запрашивает токен и отправляет сообщение. На практике это экономит часы работы, например, при разработке проектов на Drupal Commerce, поскольку вы сразу тестируете транспортный уровень, минуя настройку форм.
<?php
namespace Drupal\whapi_drupal\Commands;
use Drupal\whapi_drupal\Service\WhatsappApiClient;
use Drush\Commands\DrushCommands;
final class WhapiDrupalCommands extends DrushCommands {
public function __construct(
private WhatsappApiClient $client,
) {}
/*
* Sends a test WhatsApp message through Whapi.Cloud.
*
* @command whapi:send-test
*/
public function sendTest(string $chatId, string $message): void {
$result = $this->client->sendText($chatId, $message);
$this->output()->writeln('Message sent. Remote id: ' . ($result['messages'][0]['id'] ?? 'n/a'));
}
}
Запустите команду, указав тестовый номер телефона или ID чата, и при возникновении вопросов сравните результат с поведением запросов в коллекции Postman от Whapi.Cloud. Такой подход позволит быстро локализовать проблему и понять, где именно возникла ошибка — в коде Drupal, формате токена или структуре тела запроса.
Создание простого тестового контроллера
Убедившись в работоспособности команды Drush, при необходимости можно добавить простой внутренний маршрут и контроллер для быстрой проверки из браузера. Сделайте его максимально лаконичным: получение входящих параметров, вызов готового сервиса и вывод результата на экран. Не дублируйте логику отправки.
Обработка ошибок API по стандартам Drupal
Сбои в сети и ошибки на стороне внешнего API неизбежны. Важно то, насколько информативно Drupal сообщает о них вашей команде разработки.
Сочетание стандартного логирования Drupal и системных сообщений превращает неочевидный сбой API в легко отлаживаемое событие. Перехватывайте транспортные исключения непосредственно в месте вызова, записывайте контекст ошибки в системный лог и выводите понятное уведомление для пользователя вместо пустой страницы или игнорирования проблемы.
Перехват исключения RequestException
Локализуйте перехват `RequestException` непосредственно вокруг метода отправки, а не во всем классе контроллера или команды. Это позволит точнее очертить границы возможных сбоев и зафиксировать в логе получателя, детали HTTP-запроса и конкретное событие, инициировавшее отправку.
Использование фабрики логов (logger factory)
Выделяйте для модуля собственный канал логирования, например `whapi_drupal`. Это значительно упростит фильтрацию записей в журнале событий, особенно когда один и тот же клиент будет одновременно использоваться в очередях, обработчиках событий и ручных командах.
Уведомления в интерфейсе
Контроллеры и административные формы должны преобразовывать технические исключения в краткие сообщения службы `Messenger`: информировать о неудачной отправке и рекомендовать обратиться к системному журналу. Не выводите сырой JSON ответа в интерфейс пользователя. Логи предназначены для разработчиков, а аккуратные уведомления — для операторов сайта.
Если в процессе настройки возникнут непрепредвиденные проблемы, вы всегда можете написать в чат технической поддержки на сайте whapi.cloud. Прямое обращение к специалистам поможет решить вопрос быстрее, чем поиск ответов на форумах со схожими, но отличающимися конфигурациями серверов.
Развитие интеграции: вебхуки, очереди и действия ECA
Переходите к расширению функционала только после того, как базовая отправка исходящих сообщений будет работать стабильно. Следующий уровень интеграции посвящен отказоустойчивости и обработке входящих событий, а не проверке базовой связности.
Лучший MVP — это одна успешно работающая отправка сообщения перед переходом к автоматизации сложных пользовательских сценариев. Убедившись в надежности транспорта, вы сможете безболезненно добавить обработку входящих вебхуков, механизм повторных попыток и удобные действия для контент-менеджеров.
Базовый контроллер для вебхуков
Реализуйте простейший контроллер вебхуков: прием запроса, его валидация, извлечение типа события в соответствии с форматом вебхуков Whapi.Cloud и передача данных в специализированный сервис. Логика вебхуков быстро усложняется, если валидация подписи, бизнес-логика и побочные эффекты пишутся внутри одного контроллера. Валидация подписи запроса — это первый шаг к повышению безопасности системы после настройки исходящего транспорта.
Использование Queue API
Задействуйте стандартный механизм очередей Drupal Queue API для задач, требующих гарантированной доставки, устойчивости к пиковым нагрузкам или асинхронного выполнения. Это особенно актуально для уведомлений о заказах в интернет-магазинах, обработки лидов и запланированных напоминаний, когда событие на сайте должно лишь ставить задачу в очередь, не блокируя выполнение основного PHP-потока ожиданием ответа внешнего сервера.
Создание действий в модуле ECA
После стабилизации транспортного сервиса его можно обернуть в действие модуля ECA (Event - Condition - Action) для визуального проектирования сценариев автоматизации. Это позволит контент-менеджерам и администраторам настраивать отправку без необходимости погружаться в код и детали авторизации. При этом разработанный вами надежный сервис по-прежнему останется главным связующим звеном.
В этой вводной статье мы намеренно не рассматриваем валидацию подписей вебхуков, ветвление диалогов чат-бота или полное руководство по прохождению модерации в Meta. Это темы для последующих этапов развития вашей системы, когда базовая отправка из кастомного модуля Drupal уже проверена и стабильно работает.
Простая в поддержке интеграция WhatsApp с Drupal 10 намеренно проектируется компактной: один сервис, одна ссылка на ключ авторизации, один исходящий POST-запрос и одна команда Drush для тестирования. Этого набора достаточно для отправки первого тестового сообщения в песочнице Whapi.Cloud и создания масштабируемой базы без необходимости переписывать код в будущем.
Самый логичный следующий шаг — практический. Подключите тестовый номер телефона, сохраните токен в Key, выполните команду Drush и убедитесь, что сообщение успешно покинуло Drupal. Ограничения песочницы заданы намеренно, но 5 активных чатов в месяц, 150 сообщений в день и 1000 обращений к API вполне достаточно для отладки всей архитектуры перед подключением обработчиков событий, очередей или механизмов автоматизации.









