Bỏ qua

Kiểm tra trạng thái tin nhắn

Theo dõi trạng thái gửi tin nhắn của bạn bằng cách sử dụng điểm cuối kiểm tra trạng thái.

Điểm cuối

GET /bat/message/{messageId}

Yêu cầu

Tham số URL

Tham số Loại Bắt buộc Mô tả
messageId chuỗi Mã nhận dạng tin nhắn duy nhất từ ​​phản hồi gửi

Xác thực

Sử dụng bất kỳ phương pháp xác thực nào trong ba phương pháp sau:

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"

Phản hồi

Phản hồi cơ bản

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

Trường phản hồi

Lĩnh vực Loại Mô tả
danh sách tin nhắn số nguyên Mã định danh hàng loạt
messageId chuỗi Mã định danh tin nhắn duy nhất
trạng thái giao hàng chuỗi Tình trạng giao hàng hiện tại
đếm bộ phận số nguyên Số phần tin nhắn
chi phí số Giá tin nhắn tính theo đơn vị tiền tệ

Phản hồi mở rộng (có Dự phòng)

Khi dự phòng được định cấu hình, phản hồi sẽ bao gồm các trường bổ sung:

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

Giá trị trạng thái giao hàng

Trạng thái Mô tả
theo lịch Xếp hàng chờ gửi
xử lý Hiện đang được gửi
đã giao Đã giao hàng thành công
không thể gửi được Giao hàng không thành công, tin nhắn bị từ chối
lỗi thường trực Bị xóa khỏi hàng đợi do lỗi liên tục

Vòng đời trạng thái

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

Đã lên lịch

Tin nhắn được chấp nhận và xếp hàng chờ gửi:

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

Đang xử lý

Tin nhắn hiện đang được gửi đến người nhận:

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

Đã giao hàng

Tin nhắn được gửi thành công tới người nhận:

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

Không thể gửi được

Không thể gửi tin nhắn (số không hợp lệ, lỗi mạng):

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

Lỗi vĩnh viễn

Tin nhắn đã bị xóa khỏi hàng đợi do sự cố gửi liên tục:

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

Kiểm tra nhiều tin nhắn

Kiểm tra trạng thái của nhiều tin nhắn trong ứng dụng của bạn:

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

Bỏ phiếu để cập nhật trạng thái

Thăm dò điểm cuối trạng thái để theo dõi quá trình phân phối:

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

Webhook thay thế

Thay vì bỏ phiếu, hãy sử dụng webhook để cập nhật trạng thái theo thời gian thực:

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

Hãy liên hệ với người quản lý tài khoản của bạn để định cấu hình URL webhook.

Ví dụ triển khai

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

Các phương pháp hay nhất

Tần suất bỏ phiếu

  • ✅ Thăm dò ý kiến 5-10 giây một lần
  • ✅ Thực hiện lùi lại theo cấp số nhân
  • ✅ Đặt thời gian chờ hợp lý (60-120 giây)
  • ❌ Không thăm dò ý kiến nhiều lần mỗi giây
  • ❌ Không poll vô thời hạn

Xử lý lỗi

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

Bộ nhớ đệm

Kết quả trạng thái bộ đệm để giảm lệnh gọi 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;
}

Xử lý hàng loạt

Khi kiểm tra nhiều tin nhắn, yêu cầu hàng loạt:

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

Trường hợp sử dụng

Xác nhận đơn hàng

Theo dõi việc gửi tin nhắn xác nhận đơn hàng:

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

Xác thực hai yếu tố

Xác minh việc gửi OTP trước khi hết thời gian chờ:

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

Chiến dịch tiếp thị

Theo dõi tỷ lệ gửi tin nhắn của chiến dịch:

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

Các bước tiếp theo