https://a.storyblok.com/f/270183/84772/0715e11c82/python_sms-throttling_1200x600.png

Limitação de campanhas de SMS em massa com Python e a SMS API da Vonage

Publicado em August 18, 2021

Tempo de leitura: 6 minutos

Introdução

O envio em massa de SMS é útil quando as equipes de marketing precisam realizar campanhas promocionais. As organizações também podem utilizá-lo para transmitir informações a um grande grupo de pessoas.

Podem surgir problemas ao enviar uma campanha de SMS em massa destinada a gerar respostas de um grande público. Por exemplo, receber milhares de respostas de uma só vez pode sobrecarregar sua equipe. Uma solução para esse problema é utilizar o controle de fluxo. Por exemplo, você pode criar uma campanha para enviar as mensagens em lotes, em intervalos específicos ou ambos.

Este artigo ensinará como implementar o controle de envio em massa de SMS em Python, utilizando o Django REST Framework e a Messages API do Vonage. O aplicativo web que criaremos neste tutorial permitirá que você envie mensagens para vários usuários em lotes, em intervalos de tempo especificados.

A Messages API da Vonage permite que os desenvolvedores criem aplicativos baseados em SMS e implementem recursos de mensagens em seus aplicativos para SMS, WhatsApp, Messenger etc. O Django é um framework em Python usado para a criação de aplicativos web. O Django REST Framework permite que os desenvolvedores criem APIs RESTful com o Django.

Pré-requisitos

  1. Um account gratuito da API da Vonage

  2. Um aplicativo da Vonage. Você pode seguir este guia para criar uma aplicação no seu painel da Vonage.

  3. Python (versão 3.6 ou posterior). Você pode baixar o Python no site oficial.

  4. O gerenciador de pacotes do Python, o pip. Você pode encontrar instruções para instalar o pip aqui.

  5. A ferramenta em Python virtualenv para criar ambientes virtuais isolados para projetos em Python.

Configuração e instalação

Você começará configurando as dependências do projeto e instalando os módulos necessários com o pip. Em seguida, criará o projeto Django para o tutorial.

Instalar dependências

Primeiro, crie um novo diretório e um ambiente virtual. Em seguida, ative o ambiente virtual recém-criado:

mkdir test_project && cd test_project
python -m venv env
source env/bin/activate

Os comandos acima instalaram os seguintes pacotes:

  1. Django: o pacote do framework Django.

  2. djangorestframework: o Django REST Framework para a criação de APIs no Django.

  3. django-cors-headers: Isso permite que nossa API faça solicitações entre origens a outros servidores.

  4. vonage: o SDK do servidor Python da Vonage.

Criar um projeto Django

Agora, use o django-admin utilitário para criar um projeto Django chamado vonage_project:

django-admin startproject vonage_project

Em seguida, você precisa configurar o Django-cors-headers para o aplicativo. Dessa forma, outras origens e aplicativos front-end poderão enviar uma solicitação ao seu aplicativo Django. Acesse o arquivo MIDDLEWARE no arquivo settings.py e adicione as seguintes classes de middleware:

MIDDLEWARE = [
    ...
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    ...
]

Em seguida, crie um aplicativo Django chamado myapp para hospedar nossa funcionalidade de envio em massa de SMS:

cd vonage
django-admin startapp myapp

Criar a funcionalidade de envio em massa de SMS

Nesta seção, você configurará o recurso de envio em massa de SMS com a SMS API da Vonage. Você também implementará um recurso de limitação de tráfego.

Inicializar a biblioteca da Vonage

Normalmente, seria necessário inicializar a biblioteca da Vonage para usar a API da Vonage no envio de mensagens. No entanto, a nova Messages API da Vonage está em fase beta e ainda não oferece suporte ao Python. Mesmo assim, ainda podemos usar a Messages API.

Primeiro, adicione o código a seguir ao views.py arquivo:

import base64

vonageCredentials = 'API_KEY:API_SECRET'
encodedData = vonageCredentials.encode("utf-8")
b64value = b64encode(encodedData).decode("ascii")

No código acima, substitua o API_KEY e API_SECRET pelos valores do seu painel da Vonage. A vonageCredentials variável recebe suas credenciais da Vonage: sua chave de API e sua chave secreta no formato 'API_KEY: API_SECRET.' Em seguida, você codifica e decodifica a string com suas credenciais no formato base64 para transmiti-las como caracteres padrão ASCII.

Criar uma visualização para enviar mensagens SMS

Agora, crie uma visualização para enviar as mensagens SMS views.py assim:

from django.views.decorators.csrf import csrf_exempt
from rest_framework.decorators import parser_classes
from rest_framework.parsers import JSONParser
import json
import requests
import base64
import time
from django.http.response import JsonResponse

vonageCredentials = 'API_KEY:API_SECRET'
encodedData = vonageCredentials.encode("utf-8")
b64value = base64.b64encode(encodedData).decode("ascii")

@ csrf_exempt
@ parser_classes(\[JSONParser])
def sendMessage(self, request):
    pass

No código acima, você importou o csrf_exempt, parser_classese JSONParser classe para poder definir decoradores para a visualização. Você também importou a json, JsonResponsee outros módulos de que precisará em seu aplicativo web. Em seguida, você criou a sendMessage função, onde você colocará a lógica para enviar a mensagem.

Em seguida, você adicionará código dentro da sendMessage visualização para aceitar solicitações e entradas do usuário. Modifique view.py da seguinte maneira:

def sendMessage(self, request):
    if request.method == 'POST':
        body_unicode = request.body.decode('utf-8')
        body_data = json.loads(body_unicode)

        sender = body_data['sender']
        recipients = body_data['recipients']
        message_string = body_data['message_string']
        batch_size = body_data['batch_size']
        delay_period = body_data['delay_period']

No código acima, você especificou que a visualização aceita solicitações POST na linha: request.method == 'POST'. Em seguida, você decodificou o corpo da solicitação no formato JSON. Depois disso, você separou o corpo da solicitação nos itens que ele contém. Os itens são as seguintes entradas recebidas do usuário:

  1. sender: uma variável que contém as informações sobre o remetente da mensagem.

  2. recipients: uma lista dos números de telefone dos destinatários das mensagens SMS.

  3. message_string: o texto que você enviará na campanha de SMS em massa.

  4. batch_size: determina o número de destinatários para os quais se deve enviar um SMS de uma só vez.

  5. delay_period: o intervalo de tempo entre o envio de lotes de SMS (medido em segundos).

Agora, você vai criar uma função para dividir a lista de números de telefone dos destinatários em lotes. Adicione o código a seguir fora da sendMessage função no views.py arquivo:

def batch(recipients, batch_size=1):
    for i in range(0, len(recipients), batch_size):
        yield recipients[i:min(i + batch_size, len(recipients))]

Você definiu uma função chamada batch. Ela aceita dois parâmetros: a recipients lista e o batch_size número inteiro que representa para quantos destinatários você deseja enviar uma mensagem de uma só vez. Você usa um loop for e a palavra-chave yield para criar um conjunto de números de telefone. Se isso não estiver claro, você pode ler mais sobre o range e yield funcionam.

Agora, você vai implementar a lógica para permitir o envio de mensagens. Modifique a sendMessage visualização conforme mostrado abaixo:

@ csrf_exempt
@ parser_classes([JSONParser])
def sendMessage(request):
    if request.method == 'POST':
        body_unicode = request.body.decode('utf-8')
        body_data = json.loads(body_unicode)

        sender = body_data['sender']
        recipients = body_data['recipients']
        message_string = body_data['message_string']
        batch_size = body_data['batch_size']
        delay_period = body_data['delay_period']

        for eachBatch in batch(recipients, batch_size):
            for number in eachBatch:
                response = requests.post('https://api.nexmo.com/v0.1/messages',
                     headers={
                         "Authorization": "Basic %s" % b64value,
                         "Content-type": "application/json",
                         "Accept": "application/json"},
                     json={
                         "to": {
                             "type": "sms",
                             "number": number
                         },
                         "from": {
                             "type": "sms",
                             "number": sender
                         },
                         "message": {
                             "content": {
                                 "type": "text",
                                 "text": message_string
                             }
                         }
                     })
                print("message sent to ", number)
            time.sleep(delay_period)
        try:
            return JsonResponse("OK", status=200, safe=False)

        except Exception as e:
            return JsonResponse({'the error is': str(e)}, status=403)

Existem dois loops “for” dentro da sendSmsMessage função. O for percorre os lotes de números de telefone usando a batch função que você definiu anteriormente neste artigo. Você divide os números de telefone dos destinatários em lotes usando o `batch_size' da solicitação POST.

Em seguida, há um loop interno que pega cada número de cada lote e faz uma solicitação POST à Messages API do Vonage no endpoint https://api.nexmo.com/v0.1/messages. O cabeçalho da solicitação contém as credenciais codificadas em base64 que você criou anteriormente como um “b64value”. Ele também inclui uma carga JSON a ser enviada à Messages API. A carga JSON contém as seguintes informações:

  • sender: uma variável que contém as informações sobre o remetente da mensagem.

  • recipients: uma lista dos números de telefone dos destinatários das mensagens SMS.

  • message_string: o texto a ser incluído na mensagem SMS em massa.

  • batch_size: o número de destinatários aos quais uma mensagem será enviada de uma só vez.

  • delay_period: o intervalo de tempo entre os lotes de SMS a serem enviados.

Após a realização de uma solicitação bem-sucedida ao endpoint da Messages API, a mensagem SMS é enviada ao destinatário, e o código exibe uma mensagem no seu terminal para alertá-lo sobre a mensagem enviada. Em seguida, o seu código passa a enviar o próximo lote.

Depois de enviar uma mensagem para todos os destinatários em um lote, o loop `for` principal é executado após o período de espera definido com time.sleep(delay_period).

Quando você terminar de enviar as mensagens SMS, seu código retorna um 200 - OK JsonResponse.

O código completo views.py código é o seguinte:

from django.views.decorators.csrf import csrf_exempt
from rest_framework.decorators import parser_classes
from rest_framework.parsers import JSONParser
import json
import requests
import base64
import time
from django.http.response import JsonResponse


# Create your views here.
vonageCredentials = 'ba779f8e:fFImpyBSezdXV1Nd'
encodedData = vonageCredentials.encode("utf-8")
b64value = base64.b64encode(encodedData).decode("ascii")
print(b64value)


@ csrf_exempt
@ parser_classes([JSONParser])
def sendMessage(request):
    if request.method == 'POST':
        body_unicode = request.body.decode('utf-8')
        body_data = json.loads(body_unicode)

        sender = body_data['sender']
        recipients = body_data['recipients']
        message_string = body_data['message_string']
        batch_size = body_data['batch_size']
        delay_period = body_data['delay_period']

        for eachBatch in batch(recipients, batch_size):
            for number in eachBatch:
                response = requests.post('https://api.nexmo.com/v0.1/messages',
                     headers={
                         "Authorization": "Basic %s" % b64value,
                         "Content-type": "application/json",
                         "Accept": "application/json"},
                     json={
                         "to": {
                             "type": "sms",
                             "number": number
                         },
                         "from": {
                             "type": "sms",
                             "number": sender
                         },
                         "message": {
                             "content": {
                                 "type": "text",
                                 "text": message_string
                             }
                         }
                     })
                print("message sent to ", number)
            time.sleep(delay_period)
        try:
            return JsonResponse("OK", status=200, safe=False)

        except Exception as e:
            return JsonResponse({'the error is': str(e)}, status=403)


def batch(recipients, batch_size=1):
    for i in range(0, len(recipients), batch_size):
        yield recipients[i:min(i + batch_size, len(recipients))]

Definir um caminho de URL

Como você criou uma visualização para receber solicitações, será necessário um URL correspondente para que os usuários possam acessá-la e fazer solicitações. Portanto, você adicionará um caminho ao urlpatterns dentro do urls.py arquivo do projeto. Navegue até o subdiretório do projeto e adicione o seguinte código:

from django.urls import path
from myapp.views import sendMessage

urlpatterns = [
   ...
    path('message/', sendMessage),
]

Conforme mostrado acima, você importou path e a sendMessage visualização. Em seguida, você adicionou uma rota com a URL message/ à lista de urlpatterns.

API de aplicativos de teste

Você pode testar a funcionalidade criada acima com o ferramenta Postman , uma ferramenta para simular e documentar APIs. Você pode se cadastrar para um account gratuito no Postman.

Para executar esse teste, você também precisa iniciar o servidor de testes do Django da seguinte maneira:

Python manage.py runserver

Vamos supor que você pretenda usar os seguintes dados para sua campanha de SMS em massa.

{
    "sender": "Your Vonage number.",
    "recipients": ["First number to send to.", "Second number to send to"],
    "message_string": "Hello, World!",
    "batch_size": 3,
    "delay_period": 3600
}

Você pode inserir os detalhes acima no corpo de uma solicitação do Postman no formato JSON, conforme mostrado na imagem a seguir:

A Postman screenshot

Certifique-se de substituir os "recipients" números de telefone por números reais e substitua "sender" pelo seu número da Vonage antes de enviar a solicitação. Assim, as mensagens serão entregues aos seus destinatários.

Conclusão

Neste artigo, você implementou o controle de taxa de envio de SMS em massa usando o Vonage em uma API REST do Django. Agora você pode integrar essa solução aos seus projetos e desenvolver mais soluções com o Vonage. Você pode consultar nosso guia de autenticação para entender melhor a autenticação com as APIs da Vonage.

Compartilhar:

https://a.storyblok.com/f/270183/400x397/505bfb0eb9/jekayinoluwa-olabemiwo.png
Jekayinoluwa Olabemiwo

Jẹ́káyinOlúwa is a software craftsman and product manager passionate about technology and its impact on people. He works on product management, backend development, DevOps, technical writing, and community strategy. He enjoys dealing in the intersection of software, design, and human interaction. He likes reading and music.