
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.
Los webhooks de eventos en tiempo real de Bird son una herramienta increíblemente valiosa para que los remitentes puedan hacer que los datos se envíen automáticamente a sus sistemas. Esto puede impulsar la automatización posterior, como la actualización de listas de correo, el inicio de viajes de correo electrónico automatizados o la populación de paneles internos. Aunque los mismos datos de eventos se pueden acceder a través de la interfaz de usuario de Bird utilizando Event Search, o de manera programática aprovechando la Events API de Bird, las limitaciones impuestas en el número de registros devueltos en una sola solicitud o las limitaciones de tasa en el endpoint 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 endpoint al que Bird transmite los datos, y los datos pueden consumirse sin tener que programar cron jobs que extraen los datos. También existen consideraciones logísticas cuando se extraen los datos en lugar de hacer que los datos se envíen a ti, como tener que identificar qué período de tiempo y parámetros usar para cada solicitud de API. Si los períodos de tiempo no están perfectamente alineados, corres el riesgo de perder datos, y si los períodos de tiempo se superponen, entonces necesitas manejar registros de datos duplicados. Con los webhooks en tiempo real, los datos de eventos simplemente se envían a tu endpoint tan pronto como estén disponibles dentro de Bird.
Aunque los beneficios de recibir datos de eventos en tiempo real para impulsar los procesos de automatización posteriores puedan ser comprendidos de inmediato por muchos remitentes, el proceso real para implementar y consumir webhooks puede ser intimidante. Esto puede ser especialmente cierto si no estás familiarizado con los componentes técnicos de crear un endpoint y manejar los datos de manera programática. Hay servicios disponibles que consumirán los datos de webhook de Bird y realizarán ETL en tu base de datos automáticamente; un ejemplo sería StitchData, sobre el cual hemos blogueado en el pasado. Sin embargo, si deseas tener más control sobre el proceso, puedes construir fácilmente los componentes tú mismo. La 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 de AWS.
Configuración del Endpoint de Webhook objetivo
Cuando se crea un evento de Bird, queremos que los datos del evento se transmitan en tiempo real a un endpoint en AWS para que podamos consumir y usar esos datos de manera programática. Los datos se enviarán desde Bird a un endpoint objetivo, que reenviará la carga útil a una función lambda que procesará y almacenará los datos en un bucket S3. A continuación se puede ver un diagrama de alto nivel del flujo de datos descrito:

Para implementar este flujo de trabajo, vamos a construirlo en orden inverso comenzando con la creación de un bucket S3 donde almacenaremos nuestros datos de eventos y luego trabajaremos hacia atrás, agregando cada componente que alimenta lo que hemos construido.
Crear un Bucket S3 para Almacenar los Datos del Webhook
Antes de crear nuestro equilibrador de carga para aceptar los datos o nuestra función lambda para almacenar los datos, primero necesitamos crear nuestro bucket S3 donde se almacenarán los datos. Aunque S3 proporciona un excelente almacenamiento para datos de webhook, las organizaciones que también usan bases de datos PostgreSQL para el procesamiento de eventos deben implementar procedimientos adecuados de respaldo y restauración para proteger sus datos estructurados junto con su estrategia de almacenamiento en S3. Para hacer esto, navegue al servicio S3 dentro de AWS y presione "Create 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 lambda. Cuando se cree su bucket S3, estará vacío; si desea organizar los datos dentro de una carpeta, puede crear el directorio previsto ahora, o el directorio se creará cuando su función lambda almacene el archivo. En este ejemplo, nombramos nuestro bucket S3 "bird-webhooks" y creamos una carpeta llamada "B Event Data" para almacenar nuestros datos de eventos; verá estos nombres referenciados en nuestra función 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 lambda que es invocada por nuestro equilibrador de carga de aplicación (ALB).
El primer paso es crear su función lambda navegando al servicio Lambda dentro de AWS y haciendo clic en "Create Function." Se le pedirá que asigne un nombre a su función lambda y seleccione en qué lenguaje de programación escribir su función. Para este ejemplo, utilizamos Python como el lenguaje de ejecución.
Ahora necesitamos desarrollar nuestra función lambda. Por un momento, asumamos que nuestro equilibrador de carga de aplicación ha sido configurado y está reenviando la carga útil del webhook a nuestra función lambda; la lambda recibirá una carga útil que incluye todos los encabezados y cuerpo. La carga útil se pasa a nuestra función lambda utilizando el objeto "event" como un diccionario. Puede referenciar los encabezados y el cuerpo de la carga útil independientemente 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 de lote es un valor único creado por Bird para el lote de webhook, y lo utilizaremos como el nombre del archivo al almacenar el cuerpo como un archivo plano en S3; sin embargo, puede que desee agregar funcionalidad adicional 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 S3, la ubicación y el nombre del archivo donde se almacenarán los datos de la carga útil. En nuestra función lambda de ejemplo, hacemos esto dentro de la función "store_batch." En este ejemplo, vamos a almacenar todo el lote como un solo archivo, lo cual ayuda a asegurar que los datos se recolecten y almacenen antes de que la conexión HTTP entre Bird y su endpoint se agote. Aunque podría ajustar la configuración de tiempo de espera de la conexión en su equilibrador de carga, no hay garantías de que la conexión no se agote en el lado de transmisión (en este caso, Bird) o que la conexión no se termine antes de que su función 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 posteriores siempre que sea posible, como convertir la carga útil en formato JSON agrupado en un archivo CSV o cargar los datos de eventos en una base de datos.
Es importante tener en cuenta que puede necesitar actualizar los permisos de su función lambda. Su rol de ejecución necesitará permisos de PutObject y GetObject para S3. Es una buena práctica hacer cumplir el principio de menor privilegio, por lo que recomiendo establecer estos permisos solo para el bucket S3 donde se almacenarán las cargas útiles de webhook.
Una muestra de nuestra función lambda consumidora se puede encontrar aquí.
Una nota rápida sobre el ID de lote: Bird agrupará eventos en una sola carga útil, donde cada lote puede contener 1 a 350 o más registros de evento. Se asignará un ID de lote único, que puede ser utilizado para ver el estado del lote aprovechando la Event Webhooks API o dentro de su cuenta de Bird haciendo clic en un stream de webhook y seleccionando "Batch Status." En el caso de que una carga útil de webhook no pudiera ser entregada, como durante un tiempo de espera de conexión, Bird reintentará automáticamente el lote utilizando el mismo ID de lote. Esto puede suceder cuando su función lambda se está ejecutando 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 gestionar 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 S3; de esta manera, el procesamiento de datos se realiza de forma asíncrona a la transmisión de los datos y no hay riesgo de perder datos debido a una conexión terminada. Discutiré la función lambda de procesamiento en una sección posterior.
Crear un Equilibrador de Carga de Aplicación
Para recibir una carga útil de webhook, necesitamos proporcionar un endpoint para enviar las cargas útiles. Esto lo hacemos creando un equilibrador de carga de aplicación dentro de AWS navegando a EC2 > Load Balancers y haciendo clic en "Create Load Balancer." Se le pedirá que elija qué tipo de equilibrador de carga desea crear; para esto, queremos crear un equilibrador de carga de aplicación. Necesitamos usar un equilibrador de carga de aplicación (ALB) para construir nuestro consumidor, porque los webhooks de evento se enviarán 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 el Gateway HTTP. Es importante tener en cuenta que si elige usar un Gateway HTTP, el formato de evento puede ser diferente al de un ALB, y por lo tanto, su función lambda necesitará manejar el objeto de solicitud en consecuencia.
Una vez que su ALB haya sido creado, se le pedirá que asigne un nombre a su ALB y configure el esquema y los ajustes de acceso/seguridad; dado que planeamos recibir datos de eventos de una fuente externa (Bird), queremos que nuestro ALB esté orientado a Internet. Bajo "Listeners and routing," el ALB debe escuchar HTTPS en el puerto 443, y queremos crear un grupo de destinos que apunte a nuestra función lambda para que nuestro ALB reenvíe las solicitudes entrantes a la función lambda consumidora que creamos anteriormente. También necesita asegurarse de que el grupo de seguridad tenga permiso para aceptar tráfico a través del puerto 443.
Crear un Registro DNS para el Equilibrador de Carga
Para facilitar el uso de nuestro ALB como endpoint, 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 endpoint (por ejemplo, spevents.<su_dominio>). Al trabajar con DNS a escala en AWS, tenga en cuenta que hay límites de DNS no documentados que pueden afectar aplicaciones de alto volumen, especialmente aquellas que manejan grandes cantidades de tráfico saliente como sistemas de entrega de correo electrónico. El registro A debe configurarse para apuntar al ALB que creamos. Si está usando Route 53 para gestionar los registros DNS, puede referenciar la instancia ALB directamente habilitando "Alias" y seleccionando el ALB; de lo contrario, si está usando un proveedor de DNS externo, debe apuntar el registro A a la dirección IP pública de la instancia ALB.
Recomiendo usar una herramienta como Postman para probar que todo ha sido configurado correctamente antes de habilitar su webhook de Bird. Puede hacer una solicitud POST a su endpoint y confirmar que se recibe una respuesta. Si su solicitud POST no devuelve una respuesta, puede que necesite verificar que su ALB esté escuchando en el puerto correcto.
Crear un Webhook de Bird
Ahora estamos listos para crear el webhook en Bird y usar el nombre de host definido por el registro A anteriormente como nuestro endpoint objetivo. Para crear el webhook, navegue a la sección Webhooks dentro de su cuenta de Bird y haga clic en "Create Webhook." Se le pedirá que asigne un nombre a su webhook y proporcione una URL objetivo; el objetivo debe ser el nombre de host del registro A que creó anteriormente. Tenga en cuenta que la URL objetivo puede requerir que se incluya "HTTPS://" en la URL.
Una vez completado, verifique que la subcuenta correcta y los eventos estén seleccionados, y presione "Create Webhook" para guardar su configuración. Los datos de evento para todos los tipos de eventos seleccionados ahora se transmitirán a nuestra URL de destino y serán consumidos por nuestro ALB para el procesamiento posterior.