Serverless Webhooks

Avec PHP

Workflow

Workflow

  • On configure un webhook depuis lisa-app
     
  • Chaque lead acquis côté lisa-app est immédiatement poussé vers SQS (message queue)
     
  • Chaque message reçu côté SQS trigger l'exécution immédiate d'une lambda webhook-consume
     
  • La lambda construit, signe et envoie un payload sur l'endpoint HTTP configuré

Configuration

$ bin/console app:webhook:configure dummy-subscriber \
    --url "https://dummy-endpoint.com/webhooks" \
    --lead-type "facebook_form" \
    --lead-type "instagram_form" \
    --erp-shop-id "shop1" \
    --erp-shop-id "shop2"


> WebhookConfig successfully created with secret "25af5d78-572c-4d29-ae42-999d499f43db"

Types de lead supportés:

  • facebook_form
  • instagram_form
  • website_form
  • call

Envoi des leads sur SQS

EventSubscriber Symfony côté lisa-app qui envoie les leads normalisés dans la queue SQS via aws/aws-php-sdk

Trigger lambda

  • Exécute la lambda webhook-consume (CLI command) pour chaque message SQS reçu
     
  • Si la lambda retourne un code OK (exit code 0), le message est considéré comme traîté et est supprimé de la queue SQS
     
  • Si elle retourne un code d'erreur (e.g. 1), le message est requeued et un nouveau trigger est programmé à +15minutes

Construction du payload

{
    "body":{
        "created_at": "2005-08-15T15:52:01+00:00",
        "retry": 0,
        "id": "ee76725c-53e2-5aa9-b5ec-ef4eddfb6f4d",
        "geolid_shop_id": "erp shop id",
        "customer_shop_id": "XXX",
        "lead_type": "facebook_form",
        "first_name": "John",
        "last_name": "Doe",
        "full_name": null,
        "address": "1563 cours bayard",
        "city": "La Clusaz",
        "zip_code": "74220",
        "phone": "0609653214",
        "email": "john@example.com",
        "is_geolid": true,
        "is_organic": false,
        "extra_data": {
            ...
        }
    }
}

Standard JSON document

Signature du payload

Signature HMAC SHA1 crée à partir du payload JSON et du secret généré pendant la configuration du payload

sha1=7d38cdd689735b008b3c702edd92eea23791c5f6

Le secret est transmis à la lambda via le message SQS, encrypté au préalable avec paragonie/halite (basé sur libsodium) et décrypté par la lambda

Envoi du payload

Requête HTTP POST sur l'url configurée au préalable côté lisa-app.

POST /webhooks HTTP/1.1
Host: localhost:4567
X-Hub-Signature: sha1=7d38cdd689735b008b3c702edd92eea23791c5f6
Content-Type: application/json
Content-Length: 6615
{
    "body":{
        "created_at": "2005-08-15T15:52:01+00:00",
        ...
}

Echecs d'envoi et procédure de retry

  • Si la requête HTTP d'envoi retourne un code de réponse != 2xx, l'envoi est considéré échoué
     
  • On détermine la date à laquelle le prochain retry doit avoir lieu
     
  • On renvoie le message sur SQS avec la date du prochain retry en meta
     
  • Si le message revient avant la date du prochain retry, on le requeue.
    Sinon, on retente l'envoi

Délais de retry

  • + 10 minutes
  • + 1 heure
  • + 3 heures
  • + 1 jour
  • Puis 1 fois par jour jusqu'à 7 jours après la première tentative

A partir de la date du premier échec d'envoi, on retry à:

Logging

2 Monolog handlers câblés :

  • Type stream branché sur la sortie standard CLI (stdout)
  • Type sql branché sur une base d'audit MySQL, réservé aux logs d'envoi (success + error) pour débugger et se couvrir en cas de litige

 Monitoring

Merci !

Serverless Webhooks

By Robin Chalas

Serverless Webhooks

  • 812