Авторизация по номеру телефона на python
Недавно появилась задача добавить на один из своих сервисов авторизацию по номеру телефона. Пришлось знатно порыться в интернетах и потратить немного времени на написание кода.
Для отправки смс я выбрал сервис sms.ru, у них самая низкая стоимость отправки сообщений примерно 1,7 рубля (из того что я нашел) и самое простое API + есть партнерская программа.

Регистрируемся на сервере и получаем в личном кабинете:

Теперь делаем небольшой скрипт для отправки и обработки запросов:
import dataclasses
import requests
import logging
import re
log = logging.getLogger("SMS")
@dataclasses.dataclass()
class TSMSResponse:
id: str = "0"
status: int = 0
status_code: int = -1
balance: float = 0
class SMSTransport:
_URL = "https://sms.ru/sms/send"
def __init__(self, api_id):
self._api_id = api_id
def send(self, to: str, msg: str) -> TSMSResponse:
if not self.validate_phone(to):
log.error("Invalid phone number")
return TSMSResponse()
response = requests.get(self._URL, params=dict(
api_id=self._api_id,
to=to,
msg=msg,
json=1
)).json()
log.debug("Response %s", response)
if response["status"] == "OK":
phone = response["sms"][to]
if phone["status"] == "OK":
return TSMSResponse(
status=1,
status_code=phone["status_code"],
balance=response['balance'],
id=phone["sms_id"]
)
log.debug("Error status %s", response)
return TSMSResponse(
status_code=response["status_code"]
)
@classmethod
def validate_phone(cls, phone):
return re.match(r"^7[0-9]{10}$", phone)В примере используется dataclass, данный модуль появился только в Python3.8
Как выидно из примера, это класс для отправки телефона, метод send, принемает два параметра:
- to - номер получателя в формате 79999999999
- msg - текст сообщения в кодировке UTF-8
Не смотря на то что api сервиса умеет принимать больше одного номера за раз или пачку сообщений, данная реализация отправляет 1 сообщение на 1 номер за раз, так как задача авторизация а не спам рассылка.
В ответ send возвращает объект SMSResponse со статусом ответа 1/0 и кодом ответа где:
- 100 - Запрос выполнен или сообщение находится в очереди на отправку
- 103 - Сообщение доставлено
- 200 - Неправильный api_id
- 201 - Не хватает средств на лицевом счету
- 202 - Неправильно указан номер телефона получателя, либо на него нет маршрута
- 203 - Нет текста сообщения
- 205 - Сообщение слишком длинное (превышает 8 СМС)
Эти и другие коды ответов можно найти на странице документации.
И использование скрипта:
api_id = "you api id"
sms = SMSTransport(api_id)
result = sms.send("79999999999", "hello")
print(result)
# TSMSResponse(id='201945-1000004', status=1, status_code=100, balance=110)Модуль получился максимально простой и надеюсь кому-то пригодится.