I-skip tungo sa nilalaman

Suriin ang Katayuan ng Mensahe

Subaybayan ang katayuan ng paghahatid ng iyong mga mensahe gamit ang endpoint ng pagsusuri sa katayuan.

Endpoint

GET /bat/message/{messageId}

Kahilingan

Mga Parameter ng URL

Parameter Uri Kinakailangan Paglalarawan
messageId string Oo Natatanging identifier ng mensahe mula sa pagpapadala ng tugon

Pagpapatotoo

Gumamit ng alinman sa tatlong paraan ng pagpapatunay:

curl -X GET https://restapi.smsbat.com/bat/message/abc123def456 \
  -H "X-Authorization-Key: your-api-key"
curl -X GET https://restapi.smsbat.com/bat/message/abc123def456 \
  -u "username:password"
curl -X GET https://restapi.smsbat.com/bat/message/abc123def456 \
  -u "@:your-api-key"

Tugon

Pangunahing Tugon

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

Mga Patlang ng Tugon

Patlang Uri Paglalarawan
messagelistId integer Batch identifier
messageId string Natatanging identifier ng mensahe
deliverystatus string Kasalukuyang katayuan ng paghahatid
partscount integer Bilang ng mga bahagi ng mensahe
gastos numero Gastos ng mensahe sa mga unit ng pera

Pinalawak na Tugon (na may Fallback)

Kapag na-configure ang fallback, kasama sa tugon ang mga karagdagang field:

{
  "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"
}

Mga Halaga ng Katayuan ng Paghahatid

Katayuan Paglalarawan
naka-iskedyul Nakapila para sa pagpapadala
pinoproseso Kasalukuyang ipinapadala
naihatid Matagumpay na naihatid
hindi maihahatid Nabigo ang paghahatid, tinanggihan ang mensahe
permanenterror Inalis sa pila dahil sa patuloy na error

Status Lifecycle

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

Naka-iskedyul

Ang mensahe ay tinatanggap at nakapila para sa paghahatid:

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

Pinoproseso

Kasalukuyang ipinapadala ang mensahe sa tatanggap:

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

Naihatid

Matagumpay na naihatid ang mensahe sa tatanggap:

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

Hindi maihahatid

Hindi maihatid ang mensahe (di-wastong numero, error sa network):

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

Permanenteng Error

Inalis ang mensahe sa pila dahil sa patuloy na mga isyu sa paghahatid:

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

Suriin ang Maramihang Mensahe

Suriin ang katayuan para sa maraming mensahe sa iyong aplikasyon:

// 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}`);
});

Pagboto para sa Mga Update sa Katayuan

I-poll ang endpoint ng katayuan upang subaybayan ang paghahatid:

// 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 };
}

Alternatibong Webhook

Sa halip na botohan, gumamit ng mga webhook para sa real-time na mga update sa status:

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

Makipag-ugnayan sa iyong account manager upang i-configure ang URL ng webhook.

Mga Halimbawa ng Pagpapatupad

Sawa

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');
}

Pinakamahuhusay na Kasanayan

Dalas ng Pagboto

  • ✅ Poll bawat 5-10 segundo
  • ✅ Ipatupad ang exponential backoff
  • ✅ Magtakda ng makatwirang timeout (60-120 segundo)
  • ❌ Huwag mag-poll ng higit sa isang beses bawat segundo
  • ❌ Huwag mag-poll nang walang katapusan

Error sa Paghawak

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)
      );
    }
  }
}

Pag-cache

Mga resulta ng katayuan ng cache upang bawasan ang mga tawag sa 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;
}

Batch Processing

Kapag tumitingin sa maraming mensahe, humihiling ng batch:

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;
}

Mga Kaso ng Paggamit

Kumpirmasyon ng Order

Subaybayan ang paghahatid ng mga mensahe sa pagkumpirma ng order:

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);
}

Two-Factor Authentication

I-verify ang paghahatid ng OTP bago mag-timeout:

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);
}

Mga Kampanya sa Marketing

Subaybayan ang mga rate ng paghahatid ng mensahe ng kampanya:

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);

Mga Susunod na Hakbang