簡訊上行 API
透過設定 Webhook,您可以即時接收終端用戶發送至您號碼的回覆內容,即 上行 (MO)。本文件詳細介紹了如何設定 Webhook URL、解析負載參數,並提供了多種語言的接收處理範例,助您快速實現與用戶的雙向簡訊互動。
1. Webhook 設定與說明
Webhook 說明
- 請求方法 (HTTP Method):
GET - Webhook URL:您在 PaaSoo 控制台中預先設定的接收端點(由您提供並維護)。
- 觸發時機:當 PaaSoo 接收到來自營運商的上行 (MO) 時,系統會立即向您的 Webhook URL 發起
GET請求,推播該條訊息詳情。 - 重試機制:如果您的伺服器未正確返回
HTTP 200 OK,PaaSoo 將在 5 分鐘、10 分鐘、30 分鐘 後分別嘗試重新推播。
2. Webhook 請求範例
當上行訊息產生後,PaaSoo 平台會以下列形式呼叫您的 Webhook URL:
GET https://USER_CALLBACK_URL?type=mo&messageid=015bd4-d6dfa7-58w&to=886912345678&from=1234&text=Hello+World
3. 請求參數
在收到的 GET 請求中,URL Query 包含以下參數:
| 參數 | 類型 | 描述 | 範例 |
|---|---|---|---|
| type | string | 訊息類型。上行 (MO) 固定為 mo。 | mo |
| messageid | string | 簡訊 ID,該條上行訊息的全域唯一識別碼。 | 015bd4-d6dfa7-58w |
| to | string | 上行號碼,通常為您在 PaaSoo 平台申請的虛擬號碼。 | 10691234 |
| from | string | 終端用戶的手機號碼。 | 886912345678 |
| text | string | 簡訊正文內容。 | Hello World |
4. 接收與處理範例
以下範例展示了如何在伺服器端接收並處理 Webhook 推播。在實際應用中,請將監聽的 URL 修改為您在 PaaSoo 平台設定的 USER_CALLBACK_URL 對應路徑,並根據實際業務增加安全校驗(如 IP白名單、簽名校驗等)和入庫邏輯。
以下程式碼假設您的 Webhook URL 為:https://example.com/mo-callback。
- Python
- Node.js
- PHP
- Java
- Go
import requests
# 您的 Webhook URL
url = "https://example.com/mo-callback"
# 模擬接收到的上行 (MO) 查詢參數
params = {
"type": "mo", # 訊息類型,固定為 mo
"messageid": "015bd4-d6dfa7-58w", # 簡訊 ID (全域唯一)
"to": "10691234", # 上行號碼
"from": "886912345678", # 終端用戶的手機號碼
"text": "Hello World" # 簡訊正文內容
}
try:
# 模擬平台向您的 Webhook 發送 HTTP GET 請求
response = requests.get(url, params=params)
response.raise_for_status()
print(f"Webhook 模擬成功。伺服器回應狀態碼: {response.status_code}")
print(f"回應體: {response.text}")
except requests.exceptions.RequestException as e:
print(f"模擬失敗: {e}")
const axios = require('axios'); // 執行: npm install axios
// 您的 Webhook URL
const url = 'https://example.com/mo-callback';
// 模擬接收到的上行 (MO) 查詢參數
const params = {
type: 'mo', // 訊息類型,固定為 mo
messageid: '015bd4-d6dfa7-58w', // 簡訊 ID (全域唯一)
to: '10691234', // 上行號碼
from: '886912345678', // 終端用戶的手機號碼
text: 'Hello World', // 簡訊正文內容
};
// 模擬平台向您的 Webhook 發送 HTTP GET 請求
axios.get(url, { params })
.then((response) => {
console.log(`Webhook 模擬成功。伺服器回應狀態碼: ${response.status}`);
console.log(`回應體: ${response.data}`);
})
.catch((error) => {
console.error('模擬失敗:', error.message || error);
});
<?php
// 您的 Webhook URL
$url = "https://example.com/mo-callback";
// 模擬接收到的上行 (MO) 查詢參數
$params = [
"type" => "mo", // 訊息類型,固定為 mo
"messageid" => "015bd4-d6dfa7-58w", // 簡訊 ID (全域唯一)
"to" => "10691234", // 上行號碼
"from" => "886912345678", // 終端用戶的手機號碼
"text" => "Hello World" // 簡訊正文內容
];
// 建構查詢字串並附加到 URL
$queryString = http_build_query($params);
$requestUrl = $url . '?' . $queryString;
// 初始化 cURL 會話以模擬 Webhook 請求
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $requestUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// 執行請求
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if($e = curl_error($ch)) {
echo "模擬失敗: " . $e;
} else {
echo "Webhook 模擬成功。伺服器回應狀態碼: " . $httpCode . "\n";
echo "回應體: " . $response . "\n";
}
// 關閉 cURL 會話
curl_close($ch);
?>
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.HttpUrl;
import java.io.IOException;
// 確保在您的 pom.xml 或 build.gradle 中添加了 OkHttp 依賴
public class MoWebhookSimulation {
public static void main(String[] args) {
OkHttpClient client = new OkHttpClient();
// 建構帶有查詢參數的 Webhook URL
HttpUrl.Builder urlBuilder = HttpUrl.parse("https://example.com/mo-callback").newBuilder();
urlBuilder.addQueryParameter("type", "mo"); // 訊息類型,固定為 mo
urlBuilder.addQueryParameter("messageid", "015bd4-d6dfa7-58w"); // 簡訊 ID (全域唯一)
urlBuilder.addQueryParameter("to", "10691234"); // 上行號碼
urlBuilder.addQueryParameter("from", "886912345678"); // 終端用戶的手機號碼
urlBuilder.addQueryParameter("text", "Hello World"); // 簡訊正文內容
String url = urlBuilder.build().toString();
// 建構請求
Request request = new Request.Builder()
.url(url)
.get()
.build();
// 執行請求以模擬平台 Webhook
try (Response response = client.newCall(request).execute()) {
System.out.println("伺服器回應狀態碼: " + response.code());
if (response.body() != null) {
System.out.println("回應體: " + response.body().string());
}
} catch (IOException e) {
System.err.println("模擬失敗: " + e.getMessage());
}
}
}
package main
import (
"fmt"
"io/ioutil"
"net/http"
"net/url"
)
func main() {
// 您的 Webhook URL
baseURL, err := url.Parse("https://example.com/mo-callback")
if err != nil {
fmt.Println("解析 URL 出錯:", err)
return
}
// 添加模擬接收到的上行 (MO) 查詢參數
params := url.Values{}
params.Add("type", "mo") // 訊息類型,固定為 mo
params.Add("messageid", "015bd4-d6dfa7-58w") // 簡訊 ID (全域唯一)
params.Add("to", "10691234") // 上行號碼
params.Add("from", "886912345678") // 終端用戶的手機號碼
params.Add("text", "Hello World") // 簡訊正文內容
// 編碼參數並附加到 URL
baseURL.RawQuery = params.Encode()
// 模擬平台向您的 Webhook 發送 HTTP GET 請求
resp, err := http.Get(baseURL.String())
if err != nil {
fmt.Println("模擬失敗:", err)
return
}
defer resp.Body.Close()
// 讀取回應體
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("讀取回應出錯:", err)
return
}
fmt.Printf("Webhook 模擬成功。伺服器回應狀態碼: %d\n", resp.StatusCode)
fmt.Printf("回應體: %s\n", string(body))
}
5. 回應要求與重試策略
- 成功回應:您的伺服器在成功接收並處理請求後,必須返回
HTTP 200 OK或類似的 2xx 成功狀態碼,以向 PaaSoo 確認該條回呼已被正確接收。 - 重試機制:如果 PaaSoo 未接收到有效的 2xx 回應(如伺服器超時或返回 4xx/5xx),系統會在 5 分鐘、10 分鐘、30 分鐘間隔時各重試推播一次。若仍未收到
HTTP 200,系統將放棄後續重試。
6. 安全與最佳實踐
- 資料傳輸安全:
- 強烈建議您的 Webhook URL 採用 HTTPS 協定進行加密,以保障簡訊內容在傳輸過程中的安全性。
- 存取控制:
- 建議在您的伺服器或閘道設定 IP白名單,僅放行來自 PaaSoo 官方伺服器 IP 段的請求,防止惡意探測與偽造呼叫。
- 冪等性設計:
- 由於網路抖動或重試機制的存在,您的伺服器可能會多次接收到同一條上行 (MO)。請務必使用
messageid(簡訊 ID)作為唯一識別碼實現資料庫插入或業務邏輯的去重處理(冪等性)。
- 由於網路抖動或重試機制的存在,您的伺服器可能會多次接收到同一條上行 (MO)。請務必使用
技術支援
如在 API 對接過程中遇到任何技術問題或業務疑問,歡迎隨時聯絡我們的開發者支援團隊:support@paasoo.com。我們將竭誠為您提供技術協助。