У вас включен AdBlock или иной блокировщик рекламы.

Пожалуйста, отключите его, доход от рекламы помогает развитию сайта и появлению новых статей.

Спасибо за понимание.

В другой раз
DevGang блог о програмировании
Авторизоваться

Авторизация по номеру телефона на 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)

Модуль получился максимально простой и надеюсь кому-то пригодится.

#Python