https://d226lax1qjow5r.cloudfront.net/blog/blogposts/throttling-bulk-sms-campaigns-with-python-and-vonage-sms-api/python_sms-throttling_1200x600.png

Estrangulamiento de campañas de SMS masivos con Python y Vonage SMS API

Publicado el August 18, 2021

Tiempo de lectura: 6 minutos

Introducción

Los SMS masivos son muy útiles cuando los equipos de marketing necesitan hacer campañas promocionales. Las organizaciones también pueden desplegarlos para transmitir información a un gran grupo de personas.

Pueden surgir problemas cuando se envía una campaña de SMS masivos destinada a generar respuestas a un público numeroso. Por ejemplo, recibir miles de respuestas entrantes a la vez podría abrumar a tu equipo. Una solución a este problema es utilizar el estrangulamiento. Por ejemplo, puedes diseñar una campaña para enviar los mensajes por lotes, en periodos específicos, o ambas cosas.

Este artículo te enseñará a implementar la limitación de SMS masivos en Python usando el framework Django REST y la API Messages API de Vonage. La aplicación web que construiremos en este tutorial te permitirá enviar mensajes a múltiples usuarios por lotes en intervalos de tiempo específicos.

El API de Messages de Vonage permite a los desarrolladores desarrollar aplicaciones basadas en SMS e implementar funciones de mensajería en sus aplicaciones para SMS, WhatsApp, Messenger, etc. Django es un framework de Python que se utiliza para crear aplicaciones web. El framework Django REST permite a los desarrolladores crear API RESTful con Django.

Requisitos previos

  1. Una cuenta gratuita de API de Vonage

  2. Una aplicación de Vonage. Puede seguir esta guía para crear una aplicación en tu panel de Vonage.

  3. Python (versión 3.6 o posterior). Puede descargar Python desde el sitio web oficial.

  4. El gestor de paquetes de Python pip. Puede encontrar instrucciones para instalar pip aquí.

  5. La herramienta Python virtualenv para crear entornos entornos virtuales para proyectos Python.

Vonage API Account

To complete this tutorial, you will need a Vonage API account. If you don’t have one already, you can sign up today and start building with free credit. Once you have an account, you can find your API Key and API Secret at the top of the Vonage API Dashboard.

Configuración e instalación

Comenzarás configurando las dependencias del proyecto e instalando los módulos que necesites con pip. A continuación, crearás el proyecto Django para el tutorial.

Instalar dependencias

En primer lugar, cree un nuevo directorio y un entorno virtual. A continuación, active el entorno virtual recién creado:

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

Los comandos anteriores instalan los siguientes paquetes:

  1. Djangoel paquete del framework Django.

  2. djangorestframework: el framework Django REST para crear APIs en Django.

  3. django-cors-headers: Esto permite a nuestra API hacer peticiones de origen cruzado a otros servidores.

  4. vonageel SDK del servidor Python de Vonage.

Crear un proyecto Django

Ahora, utiliza la utilidad django-admin para crear un proyecto Django llamado vonage_project:

django-admin startproject vonage_project

A continuación, debe configurar el Django-cors-headers para la aplicación. De esta forma, otros orígenes y aplicaciones frontend podrán hacer una petición a tu aplicación Django. Ve al campo MIDDLEWARE en el archivo settings.py y añade las siguientes clases de middleware:

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

A continuación, creamos una aplicación Django llamada myapp para alojar nuestra funcionalidad de SMS masivos:

cd vonage
django-admin startapp myapp

Crear funcionalidad de SMS masivos

En esta sección, configurarás la función de SMS masivos con la SMS API de Vonage. También implementarás una función de limitación.

Inicializar la biblioteca de Vonage

Normalmente, necesitarías inicializar la biblioteca de Vonage para usar la API de Vonage para enviar mensajes. Sin embargo, la nueva API Messages API de Vonage está en versión beta y Python aún no es compatible. Sin embargo, aún podemos utilizar la Messages API.

En primer lugar, añada el siguiente código al archivo views.py archivo:

import base64

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

En el código anterior, sustituya los caracteres API_KEY y API_SECRET por los valores de tu panel de Vonage. La variable vonageCredentials toma tus credenciales de Vonage: tu clave API y clave secreta en la forma 'API_KEY: API_SECRET.' Luego codifica y decodifica la cadena con tus credenciales en forma base64 para pasarlas como caracteres estándar ASCII.

Crear una vista para enviar mensajes SMS

Ahora, cree una vista para enviar los mensajes SMS en views.py así:

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

En el código anterior, has importado los archivos csrf_exempt, parser_classesy JSONParser para poder definir decoradores para la vista. También has importado las clases json, JsonResponsey otros módulos que necesitarás en tu aplicación web. A continuación, ha creado la función sendMessage donde pondrás la lógica para enviar el mensaje.

A continuación, añadirá código dentro de la vista sendMessage para aceptar peticiones y entradas de usuario. Modifique view.py como sigue:

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']

En el código anterior, ha especificado que la vista acepta peticiones POST en la línea : request.method == 'POST'. Luego, decodificaste el cuerpo de la solicitud en formato JSON. Después de eso, has despojado el cuerpo de la petición de los elementos que contiene. Los elementos son las siguientes entradas recibidas del usuario:

  1. sender: una variable que contiene la información sobre el remitente del mensaje.

  2. recipients: una lista de los números de teléfono de los destinatarios de los SMS.

  3. message_string: el texto que enviará en la campaña de SMS masivos.

  4. batch_size: estipula el número de destinatarios a los que enviar un SMS a la vez.

  5. delay_period: el intervalo de tiempo entre el envío de lotes de SMS (medido en segundos).

Ahora, crearás una función para dividir la lista de números de teléfono de los destinatarios en lotes. Añade el siguiente código fuera de la función sendMessage en el archivo views.py archivo:

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

Ha definido una función llamada batch. Acepta dos parámetros: la recipients lista y el batch_size que representa a cuántos destinatarios desea enviar un mensaje a la vez. Utiliza un bucle for y la palabra clave yield para crear un lote de números de teléfono. Si esto no le queda claro, puede leer más sobre la función rango y yield funcionan.

Ahora, implementará la lógica para habilitar el envío de mensajes. Modifique la vista sendMessage como se muestra a continuación:

@ 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)

Hay dos bucles for dentro de la función sendSmsMessage función. La sentencia for recorre los lotes de números de teléfono utilizando la función batch que definió anteriormente en este artículo. Divide los números de teléfono de los destinatarios en lotes utilizando `batch_size' de la solicitud POST.

Luego, tienes un bucle interno que toma cada número de cada lote y realiza una solicitud POST a la API de Messages API de Vonage en el punto final https://api.nexmo.com/v0.1/messages. El encabezado de la solicitud contiene las credenciales codificadas en base64 que creaste anteriormente como un "b64value". También incluye una carga útil JSON para entregar a la API de Messages. La carga útil JSON contiene la siguiente información:

  • sender: una variable que contiene la información sobre el remitente del mensaje.

  • recipients: una lista de los números de teléfono de los destinatarios de los SMS.

  • message_string: el texto que contendrá el SMS masivo.

  • batch_size: el número de destinatarios a los que se enviará un mensaje a la vez.

  • delay_period: el intervalo de tiempo entre los lotes de SMS que deben enviarse.

Una vez realizada con éxito la solicitud al punto final de la Messages API, el mensaje SMS se envía al destinatario y el código imprime un mensaje en su terminal para avisarle del mensaje enviado. A continuación, tu código trabaja en el envío del siguiente lote.

Después de haber enviado un mensaje a todos los destinatarios de un lote, el bucle for padre se ejecuta tras el periodo de retardo que hayas establecido con time.sleep(delay_period).

Cuando termina de enviar los mensajes SMS, su código devuelve un mensaje 200 - OK JsonResponse.

El código views.py completo es el siguiente:

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 una ruta URL

Dado que ha creado una vista para recibir solicitudes, necesitará una URL correspondiente para que los usuarios puedan acceder a la vista para realizar solicitudes. Por lo tanto, añadirá una ruta a la vista urlpatterns dentro del archivo urls.py del proyecto. Navega hasta el subdirectorio del proyecto y añade el siguiente código:

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

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

Como se muestra arriba, ha importado path y la vista sendMessage vista. A continuación, ha añadido una ruta con la URL message/ a la lista de archivos urlpatterns.

API de aplicaciones de prueba

Puede probar la funcionalidad construida anteriormente con el Postman para simular y documentar APIs. Puede registrarse una Account gratuita de Postman.

Para ejecutar esta prueba, también necesitas iniciar el servidor de pruebas de Django de la siguiente manera:

Python manage.py runserver

Supongamos que desea utilizar los siguientes datos para su campaña de SMS masivos.

{
    "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
}

Puede introducir los detalles anteriores en el cuerpo de una solicitud Postman como JSON, tal y como se muestra en la siguiente imagen:

A Postman screenshot

Asegúrese de sustituir los "recipients" números de teléfono con números reales y reemplaza "sender" con tu número de Vonage antes de enviar la solicitud. Luego, los mensajes serán entregados a tus destinatarios.

Conclusión

En este artículo, implementaste la limitación de SMS masivos usando Vonage en una API REST Django. Ahora puedes integrar esta solución en tus proyectos y crear más soluciones con Vonage. Puedes revisar nuestra guía de autenticación para comprender mejor la autenticación con las API de Vonage.

Compartir:

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.