Creando y Consumando Webhooks de Aves

Lo siguiente es una guía sencilla para ayudar a los remitentes a sentirse cómodos al crear un webhook de eventos de Bird y consumir los datos utilizando la infraestructura de AWS.

Author

Pájaro

Categoría

Correo electrónico

Creando y Consumando Webhooks de Aves

Lo siguiente es una guía sencilla para ayudar a los remitentes a sentirse cómodos al crear un webhook de eventos de Bird y consumir los datos utilizando la infraestructura de AWS.

Author

Pájaro

Categoría

Correo electrónico

Creando y Consumando Webhooks de Aves

Lo siguiente es una guía sencilla para ayudar a los remitentes a sentirse cómodos al crear un webhook de eventos de Bird y consumir los datos utilizando la infraestructura de AWS.

Author

Pájaro

Categoría

Correo electrónico

Los webhooks de eventos en tiempo real de Bird son una herramienta increíblemente valiosa para que los remitentes tengan datos enviados automáticamente a sus sistemas. Esto puede impulsar la automatización en downstream, como la actualización de listas de mailing, la activación de viajes de correo electrónico automatizados o la población de paneles internos. Si bien los mismos datos de eventos se pueden acceder a través de la interfaz de usuario de Bird usando Búsqueda de Eventos, o programáticamente aprovechando la API de Eventos de Bird, las limitaciones impuestas sobre el número de registros devueltos en una sola solicitud o los límites de tasa aplicados al punto final de la API pueden hacer que ambos métodos sean restrictivos para remitentes grandes y sofisticados.  


Los webhooks de eventos en tiempo real permiten a un remitente configurar un punto final al que Bird transmite los datos, y los datos pueden ser consumidos sin tener que programar trabajos cron que extraen los datos. También hay intercambios logísticos cuando se extraen los datos en lugar de tener los datos enviados a usted, como tener que identificar qué período de tiempo y parámetros utilizar para cada solicitud de API. Si los períodos de tiempo no están alineados perfectamente, corre el riesgo de perder datos, y si los períodos de tiempo se superponen, entonces necesita manejar registros de datos duplicados. Con los webhooks en tiempo real, los datos de eventos se envían simplemente a su punto final a medida que están disponibles dentro de Bird.


Si bien los beneficios de recibir datos de eventos en tiempo real para impulsar procesos de automatización downstream pueden ser entendidos de inmediato por muchos remitentes, el proceso real para implementar y consumir webhooks puede ser intimidante. Esto puede ser especialmente cierto si no está familiarizado con los componentes técnicos de crear un punto final y manejar los datos programáticamente. Hay servicios disponibles que consumirán los datos de webhook de Bird y los ETL en su base de datos automáticamente; un ejemplo sería StitchData, de los cuales hemos escrito en el pasado.  Sin embargo, si desea tener más control sobre el proceso, puede construir fácilmente los componentes usted mismo. Lo siguiente es una guía simple para ayudar a los remitentes a sentirse cómodos al crear un webhook de eventos de Bird y consumir los datos utilizando la infraestructura dentro de AWS.


Configurando el Punto Final de Webhook


Cuando se crea un evento de Bird, queremos que esos datos de evento se transmitan en tiempo real a un punto final en AWS para que podamos consumir y usar esos datos programáticamente. Los datos serán enviados desde Bird a un punto final de destino, que enviará la carga útil a una función de lambda que procesará y almacenará los datos en un bucket de S3. Un diagrama de alto nivel del flujo de datos descrito se puede ver abajo:




Para implementar este flujo de trabajo, construyamos en el orden inverso comenzando con la creación de un bucket de S3 donde almacenaremos nuestros datos de eventos y luego trabajar hacia atrás - agregando cada componente que alimenta lo que hemos construido.


Crear un Bucket de S3 para Almacenar los Datos del Webhook


Antes de crear nuestro balanceador de carga para aceptar los datos, o nuestra función de lambda para almacenar los datos, primero necesitamos crear nuestro bucket de S3 donde se almacenarán los datos.  Para hacerlo, navegue al servicio S3 dentro de AWS y presione “Crear Bucket.” Se le pedirá que asigne un nombre a su bucket y establezca la región; asegúrese de usar la misma región que su ALB y función de lambda. Cuando se cree su bucket de S3, estará vacío; si desea organizar los datos dentro de una carpeta, puede crear el directorio deseado ahora, o el directorio se creará cuando su función de lambda almacene el archivo. En este ejemplo, nombramos nuestro bucket de S3 “bird-webhooks” y creamos una carpeta llamada “B Datos de Evento” para almacenar nuestros datos de eventos; verá que estos nombres se mencionan en nuestra función de lambda a continuación.


Crear una Función Lambda para Consumir los Datos


El procesamiento y almacenamiento real de los datos será realizado por una función de lambda que es invocada por nuestro balanceador de carga de aplicación (ALB). 


El primer paso es crear su función de lambda navegando al servicio de Lambda dentro de AWS y haciendo clic en “Crear Función.” Se le pedirá que asigne un nombre a su función de lambda y seleccione qué lenguaje de programación usar para escribir su función. Para este ejemplo, usamos Python como el lenguaje de tiempo de ejecución.


Ahora necesitamos desarrollar nuestra función de lambda. Por un momento, supongamos que nuestro balanceador de carga de aplicación ha sido configurado y está enviando la carga útil del webhook a nuestra función de lambda; la lambda recibirá una carga útil que incluye los encabezados y el cuerpo completos. La carga útil se pasa a nuestra función de lambda utilizando el objeto “event” como un diccionario. Puede hacer referencia a los encabezados y al cuerpo de la carga útil de forma independiente accediendo a los objetos “headers” y “body” dentro de la carga útil. En este ejemplo, simplemente vamos a leer el encabezado “x-messagesystems-batch-id”, donde el ID del lote es un valor único creado por Bird para el lote de webhook, y lo usaremos como el nombre del archivo al almacenar el cuerpo como un archivo plano en S3; sin embargo, puede querer agregar funcionalidades adicionales, como verificaciones de autenticación o manejo de errores, según sea necesario.


Al almacenar la carga útil en un archivo plano en S3, necesitaremos definir el nombre del bucket de S3, la ubicación, y el nombre del archivo donde se almacenarán los datos de carga útil. En nuestra función de lambda de muestra, hacemos esto dentro de la función “store_batch”. En este ejemplo, almacenaremos todo el lote como un solo archivo, lo que ayuda a asegurar que los datos se recojan y almacenen antes de que la conexión HTTP entre Bird y su punto final se agote. Si bien podría ajustar la configuración de tiempo de espera de conexión en su balanceador de carga, no hay garantías de que la conexión no se agote en el lado de la transmisión (en este caso, Bird) o que la conexión no se termine antes de que su función de lambda termine de ejecutarse. Es una buena práctica mantener su función consumidora lo más eficiente posible y reservar actividades de procesamiento de datos para procesos downstream cuando sea posible, como convertir la carga útil formateada en JSON en un archivo CSV, o cargar los datos de eventos en una base de datos.


Es importante señalar que es posible que necesite actualizar los permisos de su función de lambda. Su rol de ejecución necesitará permisos PutObject y GetObject para S3. Es una buena práctica aplicar el principio de privilegio mínimo, por lo que recomiendo establecer estos permisos solo para el bucket de S3 donde se almacenarán las cargas útiles del webhook.


Una muestra de nuestra función de lambda consumidora se puede encontrar aquí.


Como una nota rápida sobre el ID del lote:  Bird agrupa eventos en una sola carga útil, donde cada lote puede contener de 1 a 350 o más registros de eventos.  Se le dará un ID de lote único al lote, que se puede usar para ver el estado del lote aprovechando la API de Webhooks de Eventos o dentro de su cuenta de Bird haciendo clic en un stream de webhook y seleccionando “Estado del Lote.” En el caso de que no se pueda entregar una carga útil de webhook, como durante un tiempo de espera de conexión, Bird automáticamente reintentará el lote utilizando el mismo ID de lote. Esto puede suceder cuando su función de lambda está funcionando cerca del tiempo máximo de ida y vuelta de 10 segundos y es una razón para optimizar la función consumidora para reducir el tiempo de ejecución.


Para manejar todas las actividades de procesamiento de datos, recomiendo crear una función lambda separada que se ejecute cada vez que se crea un nuevo archivo en el bucket de S3; de esta manera, el procesamiento de datos se realiza de manera asíncrona a la transmisión de los datos, y no hay riesgo de perder datos debido a una conexión terminada. Discuto la función lambda de procesamiento en una sección posterior.


Crear un Balanceador de Carga de Aplicación


Para recibir una carga útil de webhook, necesitamos proporcionar un punto final al que enviar las cargas útiles. Hacemos esto creando un balanceador de carga de aplicación dentro de AWS al navegar a EC2 > Balanceadores de Carga y haciendo clic en “Crear Balanceador de Carga.” Se le pedirá que elija qué tipo de balanceador de carga desea crear; para esto, queremos crear un balanceador de carga de aplicación. Necesitamos usar un balanceador de carga de aplicación (ALB) para construir nuestro consumidor porque los webhooks de eventos serán enviados como una solicitud HTTP, y los ALBs se utilizan para enrutar solicitudes HTTP dentro de AWS. Podríamos implementar un Gateway HTTP como alternativa; sin embargo, usamos un ALB para este proyecto porque es más ligero y rentable que un Gateway HTTP. Es importante señalar que si elige usar un Gateway HTTP, el formato del evento puede ser diferente al de un ALB, y por lo tanto, su función de lambda necesitará manejar el objeto de solicitud en consecuencia.


Una vez que se ha creado su ALB, se le pedirá que asigne un nombre a su ALB y configure el esquema y la configuración de acceso/seguridad; ya que planeamos recibir datos de eventos de una fuente externa (Bird), queremos que nuestro ALB tenga acceso a Internet.  Bajo “Listeners y enrutamiento,” el ALB debería escuchar HTTPS en el puerto 443, y queremos crear un grupo de objetivos que apunte a nuestra función de lambda para que nuestro ALB reenvíe las solicitudes de entrada a la función de lambda de consumo que creamos arriba.  También necesita asegurarse de que el grupo de seguridad tenga permisos para aceptar tráfico a través del puerto 443.


Crear un Registro DNS para el Balanceador de Carga


Para que nos sea más fácil usar nuestro ALB como un punto final, crearemos un registro A en DNS que apunte a nuestro ALB. Para esto, podemos usar el servicio AWS Route 53 (o su proveedor de DNS actual) y crear un registro A para el nombre de host que desea usar para su punto final (por ejemplo, spevents.<your_domain>). El registro A debe configurarse para apuntar al ALB que creamos. Si está utilizando Route 53 para administrar los registros DNS, puede referenciar directamente la instancia de ALB habilitando “Alias” y seleccionando el ALB; de lo contrario, si está utilizando un proveedor de DNS externo, debe apuntar el registro A a la dirección IP pública de la instancia de ALB.


Recomiendo utilizar una herramienta como Postman para probar que todo se ha configurado correctamente antes de habilitar su webhook de Bird. Puede realizar una solicitud POST a su punto final y confirmar que se recibe una respuesta. Si su solicitud POST no devuelve una respuesta, es posible que necesite verificar que su ALB esté escuchando el puerto correcto.


Crear un Webhook de Bird


Ahora estamos listos para crear el webhook en Bird y utilizar el nombre de host definido por el registro A anterior como nuestro punto final de destino. Para crear el webhook, navegue a la sección de Webhooks dentro de su cuenta de Bird y haga clic en “Crear Webhook.” Se le pedirá que asigne un nombre a su webhook y proporcione una URL de destino; el destino debe ser el nombre de host del registro A que creó anteriormente. Tenga en cuenta que la URL de destino puede requerir que se incluya “HTTPS://” en la URL.  


Una vez completado, verifique que se seleccionen la subcuenta y los eventos correctos, y presione “Crear Webhook” para guardar su configuración. Los datos de eventos de todos los tipos de eventos seleccionados ahora se transmitirán a nuestra URL de destino y serán consumidos por nuestro ALB para procesamiento downstream.


Procesamiento de Datos de Eventos de Webhook


Dependiendo del propósito previsto para almacenar los datos de eventos de Bird, sus requisitos pueden ser satisfechos simplemente almacenando la carga útil JSON como un archivo plano. También puede tener un proceso ETL downstream ya establecido que sea capaz de consumir y cargar datos en un formato JSON. En ambos casos, es posible que pueda utilizar el archivo plano creado por nuestra lambda de procesamiento que creamos arriba tal cual.


Alternativamente, puede necesitar transformar los datos, como convertir de un formato JSON a un formato CSV, o cargar los datos directamente en una base de datos. En este ejemplo, crearemos una función lambda simple que convertirá los datos del webhook del formato JSON original a un archivo CSV que podría ser cargado en una base de datos. 


Crear una Lambda para Procesar los Datos


Al igual que con la función de lambda para consumir los datos del webhook, necesitamos crear una nueva función de lambda navegando al servicio de Lambda dentro de AWS y presionando “Crear Función.” Esta nueva función de lambda se activará cuando se cree un nuevo archivo en nuestro bucket de S3; leerá los datos y los convertirá en un nuevo archivo CSV.  


La función de lambda acepta la información del archivo como un evento. En la función de lambda de muestra, verá que primero tenemos una serie de verificaciones de validación para asegurar que los datos estén completos y formateados como se espera. A continuación, convertimos la carga útil JSON en un archivo CSV utilizando la biblioteca “csv” y escribiéndolo en un archivo temporal. Las funciones de lambda solo pueden escribir archivos locales en el directorio “/tmp”, así que creamos un archivo CSV temporal y lo nombramos con la convención <batch_id>.csv. La razón por la que usamos el batch_id aquí es para asegurar que cualquier proceso paralelo que se esté ejecutando como resultado de recibir múltiples cargas útiles de webhook no interfiera entre sí, ya que cada lote de webhook tendrá un batch_id único.  


Una vez que los datos se han convertido completamente a CSV, leemos los datos CSV como un flujo de bytes, eliminamos el archivo temporal y guardamos los datos CSV como un nuevo archivo en S3. Es importante tener en cuenta que se necesita un bucket de S3 diferente para la salida; de lo contrario, corremos el riesgo de crear un bucle recursivo que puede resultar en un aumento del uso de lambda y costos aumentados. Necesitaremos identificar en qué bucket de S3 y ubicación queremos que se almacene nuestro archivo CSV dentro de nuestra función de lambda.  Siga el mismo procedimiento que antes para crear un nuevo bucket de S3 para almacenar nuestro archivo CSV.


Tenga en cuenta que el directorio tmp está limitado a 512 MB de espacio, por lo que es importante que el archivo temporal se elimine posteriormente para asegurar suficiente espacio para futuras ejecuciones. La razón por la que usamos un archivo temporal, en lugar de escribir directamente en S3, es para simplificar la conexión a S3 mediante una única solicitud.


Al igual que con la función de lambda de consumo, es posible que necesite actualizar los permisos para su función lambda de procesamiento. Esta función de lambda requiere que el rol de ejecución tenga permisos GetObject para el bucket de entrada de S3, y tanto PutObject como GetObject para el bucket de salida de S3.


Una muestra de nuestra función de lambda de procesamiento se puede encontrar aquí.


Configurar una Lambda para Ejecutar Cuando se Almacenen Nuevos Datos en S3


Ahora que nuestra función de lambda para convertir el archivo de formato JSON a CSV ha sido creada, necesitamos configurarla para que se active cuando se cree un nuevo archivo en nuestro bucket de S3. Para hacer esto, necesitamos agregar un trigger a nuestra función de lambda abriendo nuestra función de lambda y haciendo clic en “Agregar Trigger” en la parte superior de la página.  Seleccione “S3” y proporcione el nombre del bucket de S3 donde se almacenan las cargas útiles crudas del webhook. También tiene la opción de especificar un prefijo y/o sufijo de archivo para filtrar. Una vez que se hayan configurado los ajustes, puede agregar el trigger haciendo clic en “Agregar” en la parte inferior de la página. Ahora su función lambda de procesamiento se ejecutará cada vez que se agregue un nuevo archivo a su bucket de S3.


Cargando los Datos en una Base de Datos


En este ejemplo, no cubriré la carga de datos en una base de datos en detalle, pero si ha estado siguiendo este ejemplo, tiene un par de opciones:


  1. Cargar los datos directamente en su base de datos dentro de su función lambda de procesamiento

  2. Consumir su archivo CSV utilizando un proceso ETL establecido


Ya sea que esté utilizando un servicio de base de datos de AWS, como RDS o DynamoDB, o tenga su propia base de datos de PostgreSQL (o similar), puede conectarse a su servicio de base de datos directamente desde su función lambda de procesamiento. Por ejemplo, de la misma manera en que llamamos al servicio S3 usando “boto3” en nuestra función lambda, también podría usar “boto3” para llamar a RDS o DynamoDB. El servicio de AWS Athena también podría utilizarse para leer los archivos de datos directamente de los archivos planos y acceder a los datos utilizando un lenguaje de consulta similar a SQL. Recomiendo consultar la documentación respectiva para el servicio que está utilizando para obtener más información sobre cómo lograr esto dentro de su entorno.


Del mismo modo, hay muchos servicios disponibles que pueden ayudar a consumir archivos CSV y cargar los datos en una base de datos. Es posible que ya tenga un proceso ETL establecido que pueda aprovechar.


Esperamos que este guía le haya sido útil; ¡feliz envío!

Sign up

La plataforma potenciada por IA para Marketing, Soporte y Finanzas

Al hacer clic en "Obtener una demostración" aceptas los términos de Bird's

Sign up

La plataforma potenciada por IA para Marketing, Soporte y Finanzas

Al hacer clic en "Obtener una demostración" aceptas los términos de Bird's

Sign up

La plataforma potenciada por IA para Marketing, Soporte y Finanzas

Al hacer clic en "Obtener una demostración" aceptas los términos de Bird's

Channels

Grow

Engage

Automate

APIs

Resources

Company

Socials

Crecer

Gestionar

Automatizar

Crecer

Gestionar

Automatizar