Aller au contenu

Recherchez un mot complet ou une expression exacte.

Recettes Node.js et Python

Ces recettes utilisent les bibliothèques standard de Node.js 22.12 ou plus et de Python 3.10 ou plus. Ce sont des exemples HTTP lisibles, pas des SDK officiels. Ils couvrent l’envoi, la programmation, les lots, le statut d’un message et toutes les pages d’un lot.

Téléchargez le client de votre choix et les fichiers JSON dans un même dossier privé :

Les numéros fournis illustrent uniquement le format. Avant toute requête réelle, remplacez-les par des destinataires que vous êtes autorisé à contacter, vérifiez le texte et choisissez une date future. Faites ces changements avant la première soumission de l’opération.

Les commandes suivantes utilisent Bash. Renseignez l’identifiant de votre organisation et un répertoire privé persistant, hors du dépôt et de tout dossier publié. La clé est saisie sans affichage et passe uniquement par l’environnement du processus.

Fenêtre de terminal
export BEFIANA_SMS_BASE_URL='http://127.0.0.1:8000/api/sms/v2/'
export BEFIANA_SMS_ORGANIZATION='replace-with-your-organization-id'
export BEFIANA_SMS_JOURNAL="$HOME/.local/state/befiana-sms/replace-with-your-organization-id"
read -r -s -p 'Organization API key: ' BEFIANA_SMS_API_KEY
export BEFIANA_SMS_API_KEY
printf '\n'

L’URL par défaut est une API locale de test que vous devez fournir. Elle ne crée aucun environnement de test BEFIANA. Le client n’appelle jamais la production par défaut. Lorsque votre intégration est prête, cette modification sélectionne explicitement la production :

Fenêtre de terminal
export BEFIANA_SMS_BASE_URL='https://api.befiana.cloud/api/sms/v2/'

BEFIANA_SMS_ORGANIZATION sert à séparer votre suivi local ; ce champ n’est pas envoyé à l’API. L’organisation réelle est déduite de la clé Bearer. Vérifiez donc que la clé appartient à l’organisation indiquée, y compris après une rotation. Utilisez un journal distinct par organisation et environnement. Aucun secret d’authentification n’est enregistré dans le journal ni imprimé par les clients.

Choisissez une commande selon votre langage. appointment-0001 désigne une opération métier stable dans votre application. Réutilisez ce même identifiant, le même fichier et le même journal lors d’une reprise ; n’inventez pas un nouvel identifiant à chaque tentative.

Fenêtre de terminal
node client.mjs submit appointment-0001 messages immediate.json
python client.py submit appointment-0001 messages immediate.json

Ces commandes créent réellement un SMS quand elles ciblent une API active avec une clé valide. Elles nécessitent sms.send et peuvent consommer des crédits. Une réponse accepted ne prouve pas la livraison. Le résultat affiché contient l’identifiant et le statut, sans numéro de téléphone ni texte du SMS.

Pour une programmation, préparez scheduled.json avec send_at et utilisez une autre opération volontaire :

Fenêtre de terminal
node client.mjs submit appointment-0002 messages scheduled.json
python client.py submit appointment-0002 messages scheduled.json

Pour un lot, préparez les destinataires distincts et la date dans batch.json :

Fenêtre de terminal
node client.mjs submit event-0001 message-batches batch.json
python client.py submit event-0001 message-batches batch.json

La programmation et les lots nécessitent sms.schedule. Leur acceptation réserve des crédits et leur traitement peut envoyer de vrais SMS. Consultez les guides de programmation, de lots, de segments et de crédits pour préparer vos requêtes et calculer les crédits requis. Ces clients ne fournissent aucune opération d’annulation.

Avant le premier appel réseau, le client enregistre durablement l’opération, son organisation déclarée, l’URL, la ressource, une Idempotency-Key UUID et le corps JSON exact. Toute différence ultérieure de corps ou de portée est refusée localement.

Défilement horizontal si nécessaire. Au clavier : Tab, puis les flèches gauche et droite.

État localComportement
pendingAu plus trois tentatives par invocation, toujours avec la même clé et le même corps.
completeRetour du résultat enregistré ; aucun nouveau POST. Utilisez status pour un état actualisé.
follow_upUne réponse a fourni message_id. Les reprises font uniquement un GET de statut.
review_requiredArrêt des POST. Examinez l’erreur et le suivi métier avant toute décision.

Une réponse perdue reste pending, même si le serveur a accepté le SMS. Relancer la commande avec son journal permet le rejeu idempotent. Les erreurs réseau, 429, 500, 503 sans identifiant et 409 idempotency_in_progress ont des reprises bornées. Les délais augmentent entre les essais ; Retry-After est respecté. Si le délai demandé dépasse 60 secondes, la commande s’arrête au lieu de réessayer trop tôt ; attendez avant une reprise manuelle.

Un 410 personal_data_erased est enregistré en review_required et arrête les POST. Conservez l’opération et sa clé dans le journal ; ne réinitialisez pas ce suivi et ne renvoyez pas le message avec une nouvelle clé. Voir le cas d’effacement.

Un provider_result_unknown avec message_id est enregistré avant la consultation du statut. Même si cette lecture échoue, l’invocation suivante ne fait que lire le message. Toute autre erreur avec message_id, y compris dispatch_unavailable, suit cette règle prudente. Sans identifiant, un résultat fournisseur incertain ou une erreur 502/504 arrête les POST et demande une vérification manuelle. N’interprétez jamais unknown comme « non envoyé ».

Remplacez l’UUID d’exemple par celui retourné pour votre message. Ces commandes GET exigent delivery.read et ne créent aucun SMS :

Fenêtre de terminal
node client.mjs status 00000000-0000-4000-8000-000000000001
python client.py status 00000000-0000-4000-8000-000000000001

Pour un lot, utilisez son UUID :

Fenêtre de terminal
node client.mjs batch-messages 00000000-0000-4000-8000-000000000001
python client.py batch-messages 00000000-0000-4000-8000-000000000001

Le client lit toutes les pages jusqu’à next_cursor: null, encode le curseur comme valeur du paramètre cursor, puis affiche les identifiants et statuts. Il s’arrête explicitement sur une erreur HTTP, une page invalide, un curseur répété ou plus de 1 000 pages ; il ne présente pas une liste partielle comme complète. Les résultats peuvent évoluer pendant la pagination : ce n’est pas un instantané transactionnel des livraisons.

Le fichier JSON par opération contient le destinataire et le texte nécessaires à une reprise exacte : protégez ce contenu personnel, les sauvegardes et les accès au répertoire. Les clients créent des fichiers privés sur les systèmes compatibles ; sous Windows, configurez également les ACL du dossier. Ne placez aucune clé API dans le texte du message. Les sorties d’erreur donnent le statut HTTP et un code stable, sans recopier les corps d’erreur ou les secrets.

Un verrou exclusif empêche deux processus partageant ce répertoire de soumettre simultanément la même opération. Un arrêt brutal ou toute écriture de journal échouée laisse le fichier .lock. Le JSON peut encore indiquer pending alors que l’API a déjà accepté le SMS ou communiqué un résultat incertain. L’arrêt des processus ne suffit pas à autoriser le retrait du verrou. Avant toute récupération manuelle, confirmez leur arrêt, diagnostiquez le résultat réel et la cohérence du journal privé, puis faites enregistrer durablement la décision correcte. Consultez le statut si vous connaissez l’identifiant ; sinon, demandez l’aide du support pour clarifier l’opération. Tant que le résultat reste indéterminé, conservez le verrou, la clé et le corps d’origine sans nouveau POST. Aucun délai n’efface automatiquement le verrou. Un JSON corrompu arrête le client ; il ne génère jamais une nouvelle clé en silence.

L’écriture utilise un fichier temporaire, fsync, puis un remplacement atomique ; le répertoire est aussi synchronisé là où l’OS le permet. Cette recette suppose un disque local persistant et un seul hôte, avec un stockage respectant ces opérations. Elle ne garantit pas la survie à toute panne matérielle, ne gère pas les disques réseau et ne remplace pas une base transactionnelle pour plusieurs serveurs. La perte du journal fait perdre la protection locale contre une nouvelle intention. Ne supprimez ni ne réinitialisez une opération pour contourner une erreur.

Node limite chaque requête à 30 secondes ; Python configure un timeout de 30 secondes sur les opérations réseau bloquantes, sans garantir une durée totale face à un flux très lent. Les redirections sont refusées et les GET ne tournent pas dans une boucle de surveillance. Les méthodes acceptent un transport injecté pour vos tests ; les recettes du dépôt sont vérifiées hors ligne, sans contacter la production. Adaptez-les à votre stockage, vos permissions et votre suivi métier avant de les automatiser.