Help Center Vérifier l'état du message

Vérifier l'état du message

Suivez l’état de livraison de vos messages à l’aide du point de terminaison de vérification de l’état.

Point de terminaison

GET /bat/message/{messageId}

Demande

Paramètres d’URL

ParamètreTapezObligatoireDescriptif
messageIdchaîneOuiIdentificateur de message unique provenant de la réponse d’envoi

Authentification

Utilisez l’une des trois méthodes d’authentification :

=== “En-tête de clé API”

```bash
curl -X GET https://restapi.smsbat.com/bat/message/abc123def456 \
  -H "X-Authorization-Key: your-api-key"
```

=== “Authentification HTTP de base”

```bash
curl -X GET https://restapi.smsbat.com/bat/message/abc123def456 \
  -u "username:password"
```

=== “Clé API comme mot de passe”

```bash
curl -X GET https://restapi.smsbat.com/bat/message/abc123def456 \
  -u "@:your-api-key"
```

Réponse

Réponse de base

{
  "messagelistId": 123456,
  "messageId": "abc123def456",
  "deliverystatus": "delivered",
  "partscount": 1,
  "cost": 0.05
}

Champs de réponse

ChampTapezDescriptif
messagelistIdentierIdentifiant du lot
messageIdchaîneIdentifiant unique du message
état de livraisonchaîneÉtat de livraison actuel
compte de piècesentierNombre de parties du message
coûtnuméroCoût du message en unités monétaires

Réponse étendue (avec repli)

Lorsque la solution de secours est configurée, la réponse inclut des champs supplémentaires :

{
  "messagelistId": 123456,
  "messageId": "abc123def456",
  "deliverystatus": "delivered",
  "partscount": 1,
  "cost": 0.05,
  "fallbacks": [
    {
      "type": "sms",
      "status": "not_used"
    }
  ],
  "extendedStatuses": {
    "viber": "delivered",
    "sms": "not_used"
  },
  "rate": 0.05,
  "rateAmount": 0.05,
  "rateCurrency": "USD",
  "billAmount": 0.05,
  "billCurrency": "USD"
}

Valeurs de l’état de livraison

StatutDescriptif
programméEn file d’attente pour l’envoi
traitementEn cours d’envoi
livréLivré avec succès
non livrableÉchec de la livraison, message rejeté
erreur permanenteSupprimé de la file d’attente en raison d’une erreur persistante

## Cycle de vie du statut

graph LR
    A[scheduled] --> B[processing]
    B --> C[delivered]
    B --> D[undeliverable]
    B --> E[permanenterror]

Planifié

Le message est accepté et mis en file d’attente pour livraison :

{
  "deliverystatus": "scheduled",
  "partscount": 1
}

Traitement

Le message est actuellement envoyé au destinataire :

{
  "deliverystatus": "processing",
  "partscount": 1
}

Livré

Message transmis avec succès au destinataire :

{
  "deliverystatus": "delivered",
  "partscount": 1,
  "cost": 0.05
}

Non livrable

Le message n’a pas pu être délivré (numéro invalide, erreur réseau) :

{
  "deliverystatus": "undeliverable",
  "partscount": 1,
  "cost": 0.00
}

Erreur permanente

Message supprimé de la file d’attente en raison de problèmes de livraison persistants :

{
  "deliverystatus": "permanenterror",
  "partscount": 1,
  "cost": 0.00
}

Vérifier plusieurs messages

Vérifiez l’état de plusieurs messages dans votre application :

// JavaScript example
async function checkMessageStatuses(messageIds) {
  const statuses = await Promise.all(
    messageIds.map(async (messageId) => {
      const response = await fetch(
        `https://restapi.smsbat.com/bat/message/${messageId}`,
        {
          headers: {
            'X-Authorization-Key': 'your-api-key'
          }
        }
      );
      return response.json();
    })
  );

  return statuses;
}

// Usage
const messageIds = ['abc123', 'def456', 'ghi789'];
const statuses = await checkMessageStatuses(messageIds);

statuses.forEach(status => {
  console.log(`Message ${status.messageId}: ${status.deliverystatus}`);
});

Sondage pour les mises à jour de statut

Interrogez le point de terminaison d’état pour suivre la livraison :

// Poll every 5 seconds until delivered
async function waitForDelivery(messageId, maxAttempts = 12) {
  for (let i = 0; i < maxAttempts; i++) {
    const response = await fetch(
      `https://restapi.smsbat.com/bat/message/${messageId}`,
      {
        headers: { 'X-Authorization-Key': 'your-api-key' }
      }
    );

    const status = await response.json();

    if (status.deliverystatus === 'delivered') {
      return { success: true, status };
    }

    if (status.deliverystatus === 'undeliverable' ||
        status.deliverystatus === 'permanenterror') {
      return { success: false, status };
    }

    // Wait 5 seconds before next check
    await new Promise(resolve => setTimeout(resolve, 5000));
  }

  // Timeout after 60 seconds
  return { success: false, timeout: true };
}

Alternative aux webhooks

Au lieu d’interroger, utilisez des webhooks pour les mises à jour de statut en temps réel :

POST https://your-server.com/webhook
{
  "messageId": "abc123def456",
  "deliverystatus": "delivered",
  "timestamp": "2025-01-23T10:30:00Z",
  "cost": 0.05
}

Contactez votre responsable de compte pour configurer l’URL du webhook.

Exemples de mise en œuvre

###Python

import requests
import time

def check_status(message_id, api_key):
    url = f"https://restapi.smsbat.com/bat/message/{message_id}"
    headers = {"X-Authorization-Key": api_key}

    response = requests.get(url, headers=headers)
    return response.json()

def wait_for_delivery(message_id, api_key, timeout=60):
    """Poll until delivered or timeout"""
    start_time = time.time()

    while time.time() - start_time < timeout:
        status = check_status(message_id, api_key)

        if status['deliverystatus'] == 'delivered':
            return {'success': True, 'status': status}

        if status['deliverystatus'] in ['undeliverable', 'permanenterror']:
            return {'success': False, 'status': status}

        time.sleep(5)

    return {'success': False, 'timeout': True}

# Usage
message_id = "abc123def456"
result = wait_for_delivery(message_id, "your-api-key")

if result['success']:
    print(f"Message delivered! Cost: {result['status']['cost']}")
else:
    print("Message delivery failed or timeout")

###PHP

<?php

function checkStatus($messageId, $apiKey) {
    $url = "https://restapi.smsbat.com/bat/message/" . $messageId;

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        "X-Authorization-Key: " . $apiKey
    ]);

    $response = curl_exec($ch);
    curl_close($ch);

    return json_decode($response, true);
}

function waitForDelivery($messageId, $apiKey, $timeout = 60) {
    $startTime = time();

    while (time() - $startTime < $timeout) {
        $status = checkStatus($messageId, $apiKey);

        if ($status['deliverystatus'] === 'delivered') {
            return ['success' => true, 'status' => $status];
        }

        if (in_array($status['deliverystatus'],
                    ['undeliverable', 'permanenterror'])) {
            return ['success' => false, 'status' => $status];
        }

        sleep(5);
    }

    return ['success' => false, 'timeout' => true];
}

// Usage
$messageId = "abc123def456";
$result = waitForDelivery($messageId, "your-api-key");

if ($result['success']) {
    echo "Message delivered! Cost: " . $result['status']['cost'];
} else {
    echo "Message delivery failed or timeout";
}

Node.js

const axios = require('axios');

async function checkStatus(messageId, apiKey) {
  const response = await axios.get(
    `https://restapi.smsbat.com/bat/message/${messageId}`,
    {
      headers: { 'X-Authorization-Key': apiKey }
    }
  );

  return response.data;
}

async function waitForDelivery(messageId, apiKey, timeout = 60000) {
  const startTime = Date.now();

  while (Date.now() - startTime < timeout) {
    const status = await checkStatus(messageId, apiKey);

    if (status.deliverystatus === 'delivered') {
      return { success: true, status };
    }

    if (['undeliverable', 'permanenterror'].includes(
      status.deliverystatus
    )) {
      return { success: false, status };
    }

    // Wait 5 seconds
    await new Promise(resolve => setTimeout(resolve, 5000));
  }

  return { success: false, timeout: true };
}

// Usage
const messageId = 'abc123def456';
const result = await waitForDelivery(messageId, 'your-api-key');

if (result.success) {
  console.log(`Message delivered! Cost: ${result.status.cost}`);
} else {
  console.log('Message delivery failed or timeout');
}

## meilleures pratiques

Fréquence d’interrogation

  • ✅ Sondage toutes les 5 à 10 secondes
  • ✅ Implémenter un recul exponentiel
  • ✅ Définir un délai d’attente raisonnable (60-120 secondes)
  • ❌ N’interrogez pas plus d’une fois par seconde
  • ❌ Ne sondez pas indéfiniment

Gestion des erreurs

async function checkStatusWithRetry(messageId, apiKey, retries = 3) {
  for (let i = 0; i < retries; i++) {
    try {
      const response = await fetch(
        `https://restapi.smsbat.com/bat/message/${messageId}`,
        {
          headers: { 'X-Authorization-Key': apiKey }
        }
      );

      if (!response.ok) {
        throw new Error(`HTTP ${response.status}`);
      }

      return await response.json();
    } catch (error) {
      if (i === retries - 1) throw error;

      // Wait before retry (exponential backoff)
      await new Promise(resolve =>
        setTimeout(resolve, Math.pow(2, i) * 1000)
      );
    }
  }
}

Mise en cache

Mettre en cache les résultats de l’état pour réduire les appels d’API :

const statusCache = new Map();

async function getCachedStatus(messageId, apiKey, cacheTTL = 30000) {
  const cached = statusCache.get(messageId);

  if (cached && Date.now() - cached.timestamp < cacheTTL) {
    return cached.status;
  }

  const status = await checkStatus(messageId, apiKey);

  statusCache.set(messageId, {
    status,
    timestamp: Date.now()
  });

  return status;
}

Traitement par lots

Lors de la vérification de nombreux messages, les requêtes groupées :

async function checkBatchStatus(messageIds, apiKey, batchSize = 10) {
  const results = [];

  for (let i = 0; i < messageIds.length; i += batchSize) {
    const batch = messageIds.slice(i, i + batchSize);
    const batchResults = await Promise.all(
      batch.map(id => checkStatus(id, apiKey))
    );
    results.push(...batchResults);

    // Rate limiting
    if (i + batchSize < messageIds.length) {
      await new Promise(resolve => setTimeout(resolve, 1000));
    }
  }

  return results;
}

Cas d’utilisation

Confirmation de commande

Suivre la livraison des messages de confirmation de commande :

const orderMessage = await sendMessage({
  to: customer.phone,
  text: `Order #${orderId} confirmed`
});

// Wait for delivery
const result = await waitForDelivery(orderMessage.messageId, apiKey);

if (result.success) {
  await updateOrder(orderId, { notificationSent: true });
} else {
  await scheduleRetry(orderId);
}

Authentification à deux facteurs

Vérifiez la livraison OTP avant l’expiration du délai :

const otpMessage = await sendOTP(userPhone, otpCode);

// Poll for delivery
const delivered = await waitForDelivery(
  otpMessage.messageId,
  apiKey,
  30 // 30 second timeout
);

if (!delivered.success) {
  // Send via alternative channel
  await sendEmailOTP(userEmail, otpCode);
}

Campagnes marketing

Suivez les taux de livraison des messages de campagne :

const messageIds = await sendCampaign(recipientList);

// Check all statuses after 5 minutes
setTimeout(async () => {
  const statuses = await checkBatchStatus(messageIds, apiKey);

  const delivered = statuses.filter(s =>
    s.deliverystatus === 'delivered'
  ).length;

  console.log(`Delivery rate: ${delivered / statuses.length * 100}%`);
}, 5 * 60 * 1000);

Prochaines étapes