Skip to content

About

Python SDK for WAIX WhatsApp API. Messages, templates, webhooks and OTP. No external dependencies.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

waix-python — WhatsApp API для Python

English

Клиент WAIX для Python 3.10 и новее. Работает на стандартной библиотеке, содержит аннотации типов. Запросы синхронные: в асинхронном веб-приложении вызывайте SDK через рабочий поток.

Установка

python -m pip install waix-python

Пакет PyPI · Исходный код

Перед первым запросом

Подключите номер в WAIX, получите Connection ID и серверный ключ с правом messages:write. Пример использует одобренный шаблон order_ready на русском языке с одной переменной в теле.

Отправка шаблона

import os
import uuid
from waix import Waix, WaixError

waix = Waix(os.environ['WAIX_API_KEY'])
# Создайте и сохраните UUID вместе с событием заказа до отправки.
event_id = str(uuid.uuid4())
result = waix.messages.send({
    'connection_id': os.environ['WAIX_CONNECTION_ID'],
    'to': '+77071234567', 'type': 'template',
    'template': {
        'name': 'order_ready', 'language': {'code': 'ru'},
        'components': [{'type': 'body', 'parameters': [{'type': 'text', 'text': '42'}]}],
    },
}, event_id)
print(result['data']['id'], result['data']['status'])

OTP: отправка и проверка

otp = Waix(os.environ['WAIX_OTP_PROJECT_KEY'])
sent = otp.otp.send({'to': '+77071234567', 'ttl': 300}, event_id)
# Сохраните sent['data']['id'] в серверной сессии пользователя.
status = otp.otp.status(sent['data']['id'])
# supplied_code — код, введённый пользователем в той же сессии.
verified = otp.otp.verify(sent['data']['id'], supplied_code)

Ошибки, файлы и параметры клиента

Перехватывайте WaixError. Поля: status (0 при сетевой ошибке), code, request_id, retry_after, body. Таймаут задаётся в секундах:

waix = Waix(os.environ['WAIX_API_KEY'], timeout=30, base_url='https://waix.kz/api/v1')

Проверка TLS-сертификатов включена. Если локальный Python не находит доверенный сертификат, настройте хранилище CA операционной системы или Python; не отключайте проверку TLS.

Загрузка файла: waix.media.upload(connection_id, 'invoice.pdf', content_type='application/pdf', type='document'). Файл читается в память; предел SDK — 100 МБ, дополнительно действуют ограничения API для типа файла.

Пагинация: waix.messages.list(limit=50, before=cursor, before_id=cursor_id).

Проверка вебхука: verify_webhook(raw_body, timestamp_header, signature_header, secret); функция импортируется из waix.

Разработка

PYTHONPATH=src python -m unittest discover -s tests
python -m pip install build
python -m build

Тесты используют локальный HTTP-сервер и не отправляют сообщения клиентам.

Какие методы есть

Раздел Возможности
Сообщения Отправка, список с пагинацией, просмотр, явный повтор
Подключения Список номеров, чтение и изменение профиля компании
Шаблоны Список, просмотр, создание, изменение, удаление, предварительный просмотр
Медиа Загрузка файла, список, получение URL, удаление
Вебхуки Чтение и изменение настроек, тест, удаление, смена секрета
OTP Отправка кода, проверка, статус запроса

Все запросы идут на https://waix.kz/api/v1. SDK возвращает полный JSON-ответ: data, а также pagination, если она есть. Для остальных операций API v1 можно использовать метод request с относительным путём. Не передавайте в него адрес, полученный от непроверенного пользователя.

Некоторым операциям нужны права управления и ключ компании. Ключ отдельного OTP-проекта не даёт доступа к настройкам вебхука компании. Список прав и полей: спецификация API.

Повторные запросы и доставка

Создайте UUID один раз при записи события в своей базе. Передайте его как ключ идемпотентности. При потере ответа повторяйте запрос с тем же UUID и теми же параметрами: новый ключ означает новое сообщение.

HTTP 202 означает, что сообщение поставлено в очередь. Доставку проверяйте по вебхуку, журналу WAIX или методу просмотра сообщения. У SDK нет автоматических повторов и переходов по HTTP redirect. Для 429 учитывайте Retry-After; ошибки 400, 401, 403 требуют исправления параметров или доступа. Сообщение со статусом outcome_unknown нельзя повторять вслепую.

Проверка подписи вебхука

Передавайте в функцию проверки исходные байты тела HTTP-запроса до разбора JSON, заголовки X-Waix-Timestamp, X-Waix-Signature и секрет вебхука. Подпись: HMAC-SHA256 от timestamp + "." + rawBody, с префиксом v1=. Сравнение выполняется за постоянное время; допустимое отклонение времени по умолчанию — 300 секунд.

Отклоняйте неверную подпись. Повторные события определяйте по X-Waix-Delivery: верная подпись сама по себе не защищает от повторной доставки в пределах допустимого времени. Сначала надёжно сохраните событие, затем ответьте кодом 2xx.

Ключи, OTP и данные клиентов

  • Храните ключи на сервере. Не включайте их в код сайта, мобильного приложения или общий файл сценария. Выдавайте только нужные права.
  • Для первого сообщения клиенту обычно нужен одобренный шаблон. Произвольный текст разрешён в рамках действующего окна обслуживания Meta. Проверяйте согласие клиента и учитывайте отказ от сообщений.
  • OTP использует отдельный ключ проекта. Начните с sandbox: он возвращает test_code и не отправляет сообщение WhatsApp. Тестовый код нельзя показывать человеку, чью личность вы проверяете.
  • Сохраните ID OTP-запроса в серверной сессии пользователя. Проверять код должна именно эта сессия. Выдавайте доступ только после успешной проверки; ограничивайте попытки по аккаунту и IP.
  • Для рабочих OTP нужны доступный тариф и одобренный отправитель. Проверьте их состояние в кабинете WAIX до включения реальной отправки.
  • SDK не записывает ключи, сообщения и коды в лог. Если добавляете свои логи, скрывайте эти данные и сохраняйте request_id для диагностики.

Документация и поддержка

Документация WAIX · Поддержка · Тарифы.

SDK работает с API v1 WAIX. Это не клиент Meta Graph API. Версии SDK следуют SemVer. Лицензия — MIT.

Поведение версии 0.2.0

SDK не повторяет запрос за вас. HTTP-ошибка от прокси остаётся HTTP-ошибкой, даже если вместо JSON пришёл HTML: сохраняются статус, request ID и Retry-After. Перенаправления запрещены. Некорректный успешный ответ вызывает INVALID_RESPONSE; ответ больше установленного лимита — RESPONSE_TOO_LARGE. Лимит по умолчанию — 2 МиБ, его можно увеличить до 16 МиБ.

Ситуация Что делать
400 / 422 Исправить поля, формат телефона, шаблон или код OTP.
401 / 403 Проверить ключ, права и принадлежность подключения/OTP-проекта.
409 Проверить конфликт ключа идемпотентности: под одним ключом нельзя менять тело.
429 Отложить запрос на срок из Retry-After, сохранив прежний ключ и тело.
5xx, TIMEOUT, TRANSPORT_ERROR Результат отправки может быть неизвестен. Сначала проверить сохранённый ID; если ID не получен, повторять прежний запрос с прежним ключом через ограниченную очередь повторов.
INVALID_RESPONSE / RESPONSE_TOO_LARGE Проверить прокси, адрес API и размер страницы. Не создавать новую отправку.
OTP_INVALID Код неверен, истёк или уже использован. Не выдавать сессию приложения.

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

Обновление с 0.1.x

Имена существующих методов сохранены. У otp.verify код должен быть строкой из шести цифр: '012345', а не число. Значения query — только строки, конечные числа и boolean; сложные объекты нужно разобрать на параметры. Ошибки HTML от прокси теперь имеют API_ERROR, а перенаправления — REDIRECT_DISALLOWED. При обработке ошибок ориентируйтесь также на HTTP-статус.

Пагинация и диагностика

waix = Waix(os.environ['WAIX_API_KEY'], timeout=30, max_response_bytes=2097152)
for message in waix.messages.iterate(connection_id=connection_id, limit=100, max_pages=100):
    save_status(message['id'], message['status'])

Генератор запрашивает страницы по мере чтения, сохраняет фильтры и передаёт оба курсора. Повторный курсор вызывает INVALID_PAGINATION; достижение max_pages — PAGINATION_LIMIT. По умолчанию предел — 1000 страниц. break останавливает загрузку следующих страниц.

try:
    result = waix.messages.get(saved_message_id)
except WaixError as error:
    logger.warning('WAIX request failed', extra=error.to_dict())
    delay_seconds = error.retry_delay()  # секунды или None
    # Решение о повторе принимает ваша очередь.

Python-клиент синхронный. timeout задаёт таймаут сетевых операций urllib, а не общий дедлайн задания. В асинхронном сервере запускайте клиент в отдельном потоке или очереди; не блокируйте event loop. Файл multipart загружается в память; для больших файлов выделите отдельный worker.

About

Python SDK for WAIX WhatsApp API. Messages, templates, webhooks and OTP. No external dependencies.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages