跳至主要内容
透過 Asgard REST API 發送文字訊息並取得回應的完整範例

發送訊息

本範例展示如何透過 Asgard REST API 向 Bot Provider 發送訊息並取得回應。

API 端點

POST {{base_url}}/generic/ns/{{namespace}}/bot-provider/{{bot_provider_name}}/message/sse

關於 customChannelId

customChannelId 是對話的識別碼,用來維持同一會話的對話記憶。使用相同的 customChannelId 發送多條訊息,Bot 將能記憶先前的對話內容。若要開啟新的對話,請使用不同的 customChannelId


cURL 範例

curl -X POST "https://api.asgard-ai.com/generic/ns/your-namespace/bot-provider/your-bot-provider/message/sse" \
-H "Content-Type: application/json" \
-H "X-API-KEY: your-api-key" \
-d '{
"customChannelId": "channel-001",
"customMessageId": "msg-001",
"text": "請問如何重設密碼?",
"action": "NONE"
}'

JavaScript(fetch)範例

const BASE_URL = 'https://api.asgard-ai.com';
const NAMESPACE = 'your-namespace';
const BOT_PROVIDER = 'your-bot-provider';
const API_KEY = process.env.ASGARD_API_KEY;

async function sendMessage(channelId, messageId, text) {
const url = `${BASE_URL}/generic/ns/${NAMESPACE}/bot-provider/${BOT_PROVIDER}/message/sse`;

const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-KEY': API_KEY,
},
body: JSON.stringify({
customChannelId: channelId,
customMessageId: messageId,
text: text,
action: 'NONE',
}),
});

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

// 讀取 SSE 串流並累積完整回應
const reader = response.body.getReader();
const decoder = new TextDecoder();
let fullText = '';

while (true) {
const { done, value } = await reader.read();
if (done) break;

const chunk = decoder.decode(value, { stream: true });
const lines = chunk.split('\n');

for (const line of lines) {
if (!line.startsWith('data:')) continue;

const jsonStr = line.slice(5).trim();
if (!jsonStr) continue;

try {
const event = JSON.parse(jsonStr);

if (event.eventType === 'asgard.message.delta') {
fullText += event.fact.messageDelta.message.text;
}

if (event.eventType === 'asgard.message.complete') {
console.log('完整回應:', fullText);
}

if (event.eventType === 'asgard.run.done') {
console.log('請求完成');
return fullText;
}
} catch (e) {
// 忽略無法解析的行
}
}
}

return fullText;
}

// 使用範例
sendMessage('channel-001', 'msg-001', '請問如何重設密碼?')
.then((reply) => console.log('Bot 回覆:', reply))
.catch(console.error);

Python(requests)範例

import requests
import json
import os

BASE_URL = "https://api.asgard-ai.com"
NAMESPACE = "your-namespace"
BOT_PROVIDER = "your-bot-provider"
API_KEY = os.environ.get("ASGARD_API_KEY")

def send_message(channel_id: str, message_id: str, text: str) -> str:
url = f"{BASE_URL}/generic/ns/{NAMESPACE}/bot-provider/{BOT_PROVIDER}/message/sse"

headers = {
"Content-Type": "application/json",
"X-API-KEY": API_KEY,
}

payload = {
"customChannelId": channel_id,
"customMessageId": message_id,
"text": text,
"action": "NONE",
}

full_text = ""

with requests.post(url, headers=headers, json=payload, stream=True) as response:
response.raise_for_status()

for line in response.iter_lines():
if not line:
continue

decoded = line.decode("utf-8")
if not decoded.startswith("data:"):
continue

json_str = decoded[5:].strip()
if not json_str:
continue

try:
event = json.loads(json_str)
event_type = event.get("eventType")

if event_type == "asgard.message.delta":
text_chunk = event["fact"]["messageDelta"]["message"]["text"]
full_text += text_chunk

elif event_type == "asgard.message.complete":
print(f"完整回應:{full_text}")

elif event_type == "asgard.run.done":
print("請求完成")
break

except json.JSONDecodeError:
pass

return full_text


if __name__ == "__main__":
reply = send_message("channel-001", "msg-001", "請問如何重設密碼?")
print(f"Bot 回覆:{reply}")

回應事件說明

發送訊息後,API 以 SSE(Server-Sent Events)串流形式回傳一系列事件:

事件類型說明
asgard.run.init請求初始化,包含 runId 等資訊
asgard.message.delta訊息片段,用於實現打字機效果
asgard.message.complete完整訊息,包含 template 渲染資料
asgard.run.done請求結束,串流關閉

詳細事件格式請參考 SSE 回應事件說明

下一步