Новое

Обработка ответов сервера и коды ошибок SMS шлюза: справочник для разработчиков

Коды ответов SMS шлюза указывают, успешно ли доставлено сообщение или возникла проблема на уровне HTTP или API. Основные группы: 2xx — успех, 4xx — ошибки клиента (неверные параметры, авторизация), 5xx — ошибки сервера провайдера. Для отладки sms api необходимо анализировать статус-код, тело ответа и логировать запрос‑ответ полностью.

Что такое коды ответов SMS шлюза и HTTP ошибки

SMS шлюз взаимодействует через HTTP/HTTPS, поэтому каждый запрос возвращает стандартный статус-код RFC 7231. Помимо него, провайдер добавляет собственный код в теле JSON, который уточняет причину неудачи (например, invalid destination, insufficient balance). Понимание обеих частей позволяет быстро локализовать проблему.

Для большинства провайдеров структура ответа выглядит так:

{
  "http_status": 200,
  "provider_code": 0,
  "message_id": "abc123",
  "status": "queued"
}

Если http_status не равно 200, рассматривайте его как HTTP‑ошибку sms; если он 200, но provider_code ≠ 0 — это бизнес‑ошибка шлюза.

Основные категории кодов

  • 2xx (успех): 200 OK, 202 Accepted — сообщение принято в очередь.
  • 4xx (ошибка клиента): 400 Bad Request (неверный формат), 401 Unauthorized (отсутствует или неверный токен), 403 Forbidden (недостаточно прав), 429 Too Many Requests (лимит скорости).
  • 5xx (ошибка сервера): 500 Internal Server Error (проблема у провайдера), 502 Bad Gateway, 503 Service Unavailable (временная недоступность).

Эти группы покрывают более 95 % реальных случаев при работе с SMS API в 2025‑2026 гг.

Как интерпретировать sms api response codes

Первый шаг — проверка http_status. Если он вне диапазона 200‑299, ищите причину в документации провайдера по HTTP‑кодам. Пример: 401 часто означает, что Authorization заголовок отсутствует или срок действия токена истек.

Если http_status = 200, переходите к полю provider_code (иногда называется error_code или status). Ниже типичные значения для популярных шлюзов (варианты могут отличаться):

provider_codeОписаниеРекомендуемое действие
0УспехНикаких действий
1001Invalid destination numberПроверьте формат телефона (E.164)
1002Insufficient balanceПополните счёт или проверьте лимит
1003Message too longУменьшите текст или включите конкатенацию
1004Duplicate message IDГенерируйте уникальный идентификатор каждый запрос
1005Sender ID not approvedСогласуйте отправителя в личном кабинете

При получении不明ного кода обращайтесь к разделу “Error codes” в технической документации провайдера (см. Техническая документация и основы работы SMS API: полное руководство).

Типичные ошибки при работе с SMS API и способы отладки

Ошибки авторизации (401, 403)

Самая частая причина — отсутствие или неправильная передача токена. Проверьте:

  • Заголовок Authorization: Bearer <token> или API-Key.
  • Срок жизни токена (обычно 24 ч). При истечении выполните refresh‑запрос.
  • IP‑фильтрацию: некоторые провайдеры ограничивают доступ по списку разрешённых адресов.

Пример правильного запроса cURL:

curl -X POST https://api.smsprovider.ru/v1/messages 
  -H "Authorization: Bearer $TOKEN" 
  -H "Content-Type: application/json" 
  -d '{"to":"+79001234567","text":"Тест","sender":"Info"}'

Ошибки валидации данных (400)

Код 400 возникает, когда тело запроса не соответствует схеме JSON или обязательные поля пусты. Частые проблемы:

  • Отсутствует поле to или оно содержит буквы.
  • Поле text превышает допустимую длину (обычно 160 символов для одного сегмента GSM‑7).
  • Неправильный Content-Type (должен быть application/json).

Для быстрой диагностики включите вывод тела ответа в логи:

response = requests.post(url, json=payload, headers=headers)
if response.status_code != 200:
    logger.error("SMS API error %s: %s", response.status_code, response.text)

Ошибки провайдера (500, 502, 503)

Эти коды указывают на проблемы со стороны шлюза: перегрузка, внутренний сбой или временная недоступность. Рекомендации:

  • Повторить запрос с экспоненциальным backoff (например, 1 с, 2 с, 4 с, максимум 5 попыток).
  • Проверять статус‑страницу провайдера (часто предоставляет реальное время инцидентов).
  • При частых 503 рассмотреть резервный провайдер или очередь сообщений.

Логировать следует не только код, но и заголовок Retry-After, если он присутствует.

Практические примеры запросов и обработки ответов

Ниже показан полный цикл отправки SMS и детальной обработки ответа на Python с использованием библиотеки requests. Комментарии поясняют каждый шаг.

import requests, time, logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

BASE_URL = "https://api.smsprovider.ru/v1"
TOKEN = "ваш_токен_здесь"

def send_sms(to, text, sender="Info"):
    url = f"{BASE_URL}/messages"
    headers = {
        "Authorization": f"Bearer {TOKEN}",
        "Content-Type": "application/json"
    }
    payload = {
        "to": to,
        "text": text,
        "sender": sender
    }
    
    for attempt in range(1, 6):  # до 5 попыток
        resp = requests.post(url, json=payload, headers=headers, timeout=10)
        logger.info("Attempt %s: HTTP %s", attempt, resp.status_code)
        
        if resp.status_code == 200:
            data = resp.json()
            if data.get("provider_code") == 0:
                logger.info("SMS queued, id=%s", data.get("message_id"))
                return data.get("message_id")
            else:
                logger.warning("Provider error %s: %s", data.get("provider_code"), data.get("error_message"))
                # здесь можно поднять исключение или вернуть код ошибки
                return None
        
        # обработка временных ошибок
        if resp.status_code in (429, 500, 502, 503):
            wait = 2 ** attempt  # экспоненциальный backoff
            logger.warning("Transient error %s, retry in %s sec", resp.status_code, wait)
            time.sleep(wait)
            continue
        
        # все остальные 4xx — фатальные, не повторяем
        logger.error("Client error %s: %s", resp.status_code, resp.text)
        break
    return None

# пример использования
send_sms("+79001234567", "Привет! Это тестовое сообщение.")

При работе на высоких нагрузках рекомендуется вынести логирование в отдельный сервис (например, ELK стек) и использовать асинхронный HTTP‑клиент (httpx.AsyncClient) для неблокирующего ввода‑вывода.

Лучшие практики мониторинга и логирования

Чтобы минимизировать потери доставки и быстро реагировать на инциденты, внедрите следующее:

  1. Полный дамп запроса‑ответа в структурированный лог (JSON). Включайте: timestamp, method, URL, headers (без токена), тело запроса, http_status, provider_code, тело ответа, задержка.
  2. Метрики: счётчики успеха, 4xx, 5xx, среднее время ответа, процент дубликатов. Используйте Prometheus или аналогичную систему.
  3. Оповещения: при превышении порога 5xx (>1 % за 5 мин) или роста 401/403 отправить 알ертирование в Slack/PagerDuty.
  4. Идемпотентность: генерируйте уникальный message_id на стороне клиента и проверяйте его наличие в ответе, чтобы избежать двойной отправки при повторных попытках.
  5. Регулярный аудит токенов: автоматически обновляйте токен за 5 минут до истечения срока, храните его в безопасном хранилище (Vault, AWS Secrets Manager).

Следуя этим рекомендациям, вы сократите среднее время восстановления после сбоя шлюза с минут до секунд и повысите доверие клиентов к сервису рассылок.

FAQ

Как отличить ошибку провайдера от ошибки моего кода?

Если http_status находится в диапазоне 4xx — проблема в запросе (отсутствуют обязательные поля, неправильный формат, неверные учетные данные). Если http_status = 200, но provider_code ≠ 0 — это бизнес‑логика шлюза (недостаточно средств, неправильный номер). При 5xx — ошибка со стороны провайдера.

Что делать, если я постоянно получаю 429 Too Many Requests?

Это сигнал превышения лимита запросов в секунду. Снизьте скорость отправки, реализуйте очередь с ограничением скорости (rate limiter) или запросите увеличение лимита у технической поддержки провайдера.

Нужно ли логировать содержимое SMS‑сообщения?

Логировать тело сообщения допустимо, если оно не содержит персональных данных (ПДН). Если в тексте есть личные сведения — маскируйте или хешируйте их перед записью в лог.

Можно ли использовать один и тот же message_id для повторной отправки?

Нет. message_id должен быть уникальным для каждой попытки; иначе провайдер может посчитать запрос дубликатом и вернуть ошибку 1004.

Как быстро проверить, доступен ли шлюз перед массовой рассылкой?

Отправьте тестовое SMS на собственный номер с минимальным текстом и проверьте, что http_status = 200 и provider_code = 0. При любой ошибке отложите массовую рассылку и разберите причину.

Влияет ли выбор протокола (REST vs SOAP) на коды ошибок?

Коды ошибок остаются теми же, потому что они определены логикой провайдера, а не транспортным протоколом. SOAP оборачивает тот же JSON/XML в конверт, поэтому обработка ответов аналогична.

Нужно ли проверять сертификат SSL при подключении к SMS API?

Да. Все современные шлюзы требуют TLS 1.2 или выше. Отключение проверки сертификата делает соединение уязвимым к MITM‑атакам и не рекомендуется в продакшене.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *