Présentation de la configuration des callbacks
Cette section explique comment configurer l'adresse de callback d'EngageLab OTP, ainsi que les mécanismes de vérification de sécurité associés, afin de garantir la fiabilité et la sécurité des données de callback.
Configuration et vérification de l'adresse de callback
Une fois l'adresse de callback configurée, EngageLab OTP envoie automatiquement une requête HTTP POST à cette adresse afin de vérifier la disponibilité de l'interface. Votre service doit renvoyer un code de statut HTTP 200 dans un délai de 3 secondes, faute de quoi le système considérera l'adresse comme indisponible.
Remarque :
Pour garantir la bonne réception des données de callback, veuillez ajouter 119.8.170.74 et 114.119.180.30 à la liste blanche du pare-feu de votre serveur.
Exemple de requête
En supposant que votre adresse de callback soit https://example.engagelabotp.callback.com, le système enverra la requête suivante :
curl -X POST https://example.engagelabotp.callback.com -d '{}'
Exigences de réponse
Votre service doit uniquement renvoyer un code de statut HTTP 200, sans avoir à renvoyer de contenu. Par exemple :
HTTP/1.1 200 OK
Content-Length: 0
Remarque :
La vérification de l'adresse de callback ne contrôle que le code de statut HTTP et n'exige pas le renvoi d'un contenu de message spécifique. Veuillez vous assurer que l'interface de votre service peut répondre correctement avec un code 200 dans un délai de 3 secondes.
Mécanisme de sécurité des callbacks
Pour garantir la sécurité des données de callback et la fiabilité de leur source, EngageLab OTP prend en charge plusieurs méthodes de vérification de sécurité.
Vérification par nom d'utilisateur et clé secrète (facultatif)
- Configuration facultative. Si un nom d'utilisateur est défini, une clé secrète doit également être définie.
- Une fois configuré, EngageLab ajoute un champ
X-CALLBACK-IDdans l'en-tête HTTP de chaque requête de callback, au format suivant :
X-CALLBACK-ID: timestamp={timestamp};nonce={nonce};username={username};signature={signature}
- Où :
timestamp: l'horodatage de l'envoi du callbacknonce: nombre aléatoireusername: le nom d'utilisateur que vous avez configurésignature: les informations de signature, calculées comme suit
Méthode de calcul de la signature (exemple en Python)
import hashlib, hmac
def verify(username, secret, timestamp, nonce, signature):
return signature == hmac.new(
key=secret.encode(),
msg=f'{timestamp}{nonce}{username}'.encode(),
digestmod=hashlib.sha256
).hexdigest()
- Le serveur peut utiliser la méthode ci-dessus pour vérifier la légitimité de la requête de callback.
Authentification par Authorization (facultatif)
- Si votre interface de callback nécessite une authentification (telle que Basic Auth, Bearer Token, etc.), vous pouvez renseigner les informations d'Authorization lors de la configuration.
- EngageLab transmettra automatiquement ce champ Authorization lors de la requête, ce qui permet à votre service de vérifier l'identité de la requête.
Description des événements de callback
Statut du message
Le statut du message permet de suivre l'évolution du statut de chaque message tout au long de son cycle de vie. Il sert à connaître en temps réel la progression de chaque étape : envoi, livraison, vérification, etc., ce qui facilite l'analyse statistique, le traitement des anomalies et l'optimisation de l'expérience utilisateur.
| Identifiant d'événement | Description |
|---|---|
| plan | Message planifié pour l'envoi, placé dans la file d'attente |
| target_valid | Numéro de destination valide |
| target_invalid | Numéro de destination invalide |
| sent | Message envoyé avec succès |
| sent_failed | Échec de l'envoi du message |
| delivered | Message livré sur l'appareil de l'utilisateur |
| delivered_failed | Message envoyé, mais non livré sur l'appareil de l'utilisateur |
| verified | L'utilisateur a effectué avec succès la vérification OTP |
| verified_failed | Échec de la vérification par l'utilisateur |
| verified_timeout | L'utilisateur n'a pas effectué la vérification dans le délai imparti ; expiration du délai |
Structure des données de callback
Structure externe
{
"total": 1,
"rows": [
{
// ReportLifecycle object
}
]
}
| Nom du champ | Type | Description |
|---|---|---|
| total | int | Nombre d'éléments de données dans ce callback |
| rows | array | Tableau des données de statut du cycle de vie |
Objet ReportLifecycle
| Nom du champ | Type | Description |
|---|---|---|
| message_id | string | ID unique du message |
| to | string | Numéro du destinataire |
| server | string | Type de service (par ex. otp) |
| channel | string | Type de canal |
| itime | int64 | Horodatage du callback (secondes) |
| custom_args | object | Paramètres personnalisés (renvoyés s'ils ont été transmis) |
| status | object | Objet détaillant le statut |
Objet status
| Nom du champ | Type | Description |
|---|---|---|
| message_status | string | Statut actuel du message (voir le tableau ci-dessous) |
| status_data | object | Objet des données de statut |
| billing | object | Objet des informations de facturation (renvoyé en cas de facturation) |
| error_code | int | Code d'erreur, 0 signifie aucune erreur |
| error_detail | object | Détails de l'erreur (renvoyés en cas d'erreur) |
Objet status_data
| Nom du champ | Type | Description |
|---|---|---|
| msg_time | int64 | Horodatage de création du message (secondes) |
| message_id | string | ID du message |
| current_send_channel | string | Nom du canal d'envoi actuel |
| template_key | string | Clé de configuration du modèle |
| business_id | string | ID métier |
Objet billing (renvoyé en cas de facturation)
| Nom du champ | Type | Description |
|---|---|---|
| cost | float64 | Montant des frais |
| currency | string | Devise, fixée à « USD » |
En général, seuls les messages au stade sent contiennent des informations de facturation.
Objet error_detail (renvoyé en cas d'erreur)
| Nom du champ | Type | Description |
|---|---|---|
| message | string | Description du message d'erreur |
Exemple : message envoyé avec succès
{
"total": 1,
"rows": [
{
"message_id": "123456789",
"to": "+6598765432",
"server": "sms",
"channel": "sms",
"itime": 1701234567,
"custom_args": {
"order_id": "ORDER123",
"user_id": "USER456"
},
"status": {
"message_status": "sent",
"status_data": {
"msg_time": 1701234560,
"message_id": "123456789",
"current_send_channel": "CHANNEL_A",
"template_key": "verify_code",
"business_id": "1001"
},
"billing": {
"cost": 0.005,
"currency": "USD"
},
"error_code": 0
}
}
]
}
Exemple : échec de l'envoi du message
{
"total": 1,
"rows": [
{
"message_id": "123456790",
"to": "+6598765433",
"server": "sms",
"channel": "sms",
"itime": 1701234568,
"status": {
"message_status": "sent_fail",
"status_data": {
"msg_time": 1701234561,
"message_id": "123456790",
"current_send_channel": "CHANNEL_B",
"template_key": "verify_code",
"business_id": "1001"
},
"error_code": 4001,
"error_detail": {
"message": "Invalid phone number"
}
}
}
]
}
Notification de message
Les notifications de message désignent des événements métier ou des alertes de niveau système. Elles servent à attirer l'attention des équipes métier sur des informations importantes telles que l'état de fonctionnement du service, le solde, l'audit des modèles, etc., afin de faciliter un traitement rapide et l'anticipation des risques.
| Identifiant d'événement | Description |
|---|---|
| insufficient_verification_rate | Taux de vérification inférieur au seuil défini |
| insufficient_balance | Solde du compte insuffisant |
| template_audit_result | Notification du résultat de l'audit du modèle |
Exemple
{
"total": 1,
"rows": [{
"server": "otp",
"itime": 1712458844,
"notification": {
"event": "insufficient_balance",
"notification_data": {
"business_id": "1744569418236633088",
"remain_balance": -0.005, // Solde actuel ;
"balance_threshold": 2 // Seuil d'alerte ;
}
}
}]
}
Réponse de message
La réponse de message désigne principalement les événements de réponse de callback lors des interactions avec les utilisateurs ou des systèmes externes.
| Identifiant d'événement | Description |
|---|---|
| uplink_message | Contenu du message entrant envoyé en réponse par l'utilisateur (par SMS, etc.) |
Exemple
{
"total": 1,
"rows": [
{
"server": "otp",
"itime": 1741083306,
"message_id": "0",
"business_id": "0",
"response": {
"event": "uplink_message",
"response_data": {
"message_sid": "SM1234567890",
"account_sid": "AC1234567890",
"from": "+1234567890",
"to": "+0987654321",
"body": "Hello, it's time to struggle!"
}
}
}
]
}
Événements système
Les événements système couvrent les actions opérationnelles liées aux comptes, aux modèles, aux appels d'API, etc. Ils facilitent la surveillance, l'audit et le traitement automatisé d'opérations clés telles que la connexion au compte, la modification des clés, les appels d'API, etc.
| Identifiant d'événement | Description |
|---|---|
| account_login | Notification d'opération liée à la connexion au compte |
| key_manage | Notification d'opération liée à la modification et à la gestion des clés |
| msg_history | Notification d'opération liée à la consultation de l'historique des messages |
| template_manage | Notification d'opération d'ajout, de modification ou de suppression de modèle |
| api_call | Notification d'opération liée à l'appel d'une interface API |
Structure des données de callback
Structure externe
{
"total": 1,
"rows": [
{
// System event object
}
]
}
| Champ | Type | Description |
|---|---|---|
| total | int64 | Nombre total d'événements dans ce callback |
| rows | array | Tableau des objets d'événement système |
Objet d'événement système
| Champ | Type | Description |
|---|---|---|
| server | string | Fixé à « otp » |
| itime | int64 | Horodatage de survenue de l'événement (secondes) |
| system_event | object | Contenu de l'événement système |
Objet system_event
| Champ | Type | Description |
|---|---|---|
| event | string | Type d'événement |
| data | object | Données de l'événement |
Objet data
| Champ | Type | Description |
|---|---|---|
| business_id | string | ID métier |
| org_id | string | ID de l'organisation |
| operator | object | Informations sur l'opérateur |
Objet operator
| Champ | Type | Description |
|---|---|---|
| string | E-mail de l'opérateur (le cas échéant) | |
| api_key | string | API Key (le cas échéant) |
| ip_address | string | IP de l'opération |
Structure de la requête
{
"total": 1,
"rows": [
{
"server": "otp",
"itime": 1694012345,
"system_event": {
"event": "account_login",
"data": {
"business_id": "123",
"org_id": "org-abc",
"operator": {
"email": "foo@example.com",
"api_key": "api-xxxx",
"ip_address": "1.2.3.4"
},
"account_login": {
"action": "login_success"
}
}
}
}
]
}
Événement de connexion au compte
| Champ | Type | Description |
|---|---|---|
| action | string | Connexion réussie / Échec de connexion / Déconnexion |
| fail_reason | string | Motif de l'échec de connexion, renvoyé uniquement en cas de login_failed |
Exemple
{
"event": "account_login",
"data": {
"business_id": "123",
"org_id": "org-abc",
"operator": {
"email": "foo@example.com",
"ip_address": "1.2.3.4"
},
"account_login": {
"action": "login_success"
}
}
}
Événement de gestion des modèles
| Champ | Type | Description |
|---|---|---|
| action | string | Créer un modèle / Mettre à jour un modèle / Supprimer un modèle |
| template_id | string | ID du modèle |
| template_name | string | Nom du modèle |
Exemple
{
"event": "template_manage",
"data": {
"business_id": "123",
"org_id": "org-abc",
"operator": {
"email": "foo@example.com",
"ip_address": "1.2.3.4"
},
"template_manage": {
"action": "update template",
"template_id": "tmpl-456",
"template_name": "Verification Code"
}
}
}
Événement de gestion des clés
| Champ | Type | Description |
|---|---|---|
| action | string | Valeurs énumérées :create api_key : créer une API Keyupdate api_key : mettre à jour une API Keydelete api_key : supprimer une API Keyview api_secret : consulter l'API Secret |
| api_key | string | API Key |
| description | string | Description (facultatif) |
Exemple
{
"event": "key_manage",
"data": {
"business_id": "123",
"org_id": "org-abc",
"operator": {
"email": "foo@example.com",
"ip_address": "1.2.3.4"
},
"key_manage": {
"action": "create",
"api_key": "apikey-789",
"description": "Nouvelle clé"
}
}
}
Événement d'appel d'API
| Champ | Type | Description |
|---|---|---|
| api_path | string | Chemin de l'interface |
| method | string | Méthode HTTP |
Exemple
{
"event": "api_call",
"data": {
"business_id": "123",
"org_id": "org-abc",
"operator": {
"api_key": "apikey-789",
"ip_address": "1.2.3.4"
},
"api_call": {
"api_path": "/api/v1/messages/send",
"method": "POST"
}
}
}










