社群自動回覆:只用正式 API 的接法與界線
社群PythonAPI
常見需求:希望串接 Instagram、Facebook、LINE 或類似平台,讀取留言或私訊,再自動回覆。這件事能做的前提,是平台有提供正式介面,而且你的用法符合該平台條款。本篇不示範如何規避登入、也不提供爬蟲或非官方自動化。
這次測試到哪裡
reply_router.py 已在本機用四則示範訊息測過:營業時間、價格、客訴與其他,分類結果符合預期,且全部標記為「只產生草稿、不自動送出」。沒有向任何平台註冊應用程式、沒有取得權杖,也沒有送出真實訊息。下文的 API 範例是請求格式說明,尚未對真實端點執行。
三層怎麼分工
| 層 | 做什麼 |
|---|---|
| 收集 | 只用該平台正式提供的 Webhook 或讀取介面接收訊息。 |
| 決策 | 先做意圖分類,決定要草稿回覆、轉人工,還是不回。 |
| 送出 | 僅在條款允許的範圍內,用正式發送介面送出;客訴與不確定的內容不自動送。 |
先看平台允不允許
Meta 為粉絲專頁與 Instagram 專業帳號提供 Messaging 相關文件,包含標準訊息時間窗等限制,詳細規則以 Messenger Platform 文件 與當下政策為準。LINE 則有官方的 Messaging API,設定與限制以 LINE Developers 文件為準。TikTok 等平台能用哪些官方介面、能不能自動回覆,同樣只能以該平台開發者文件為準;沒有正式、被允許的方法,就不要做。
不要用未授權的方式登入他人帳號、不要用自動化操控一般使用者的個人頁,也不要把蒐集到的對話拿去訓練模型或轉賣。個人資料的收集、保存與刪除,要符合《個人資料保護法》與你的隱私政策。
先做分類器,再談發送
下面這個程式只讀本機的 JSON,寫出回覆草稿。客訴會標成需要人工。把它接到正式 API 之前,先在本機看分類對不對。
#!/usr/bin/env python3
"""依關鍵字做意圖分類,只產出回覆草稿,不向任何平台送出訊息。"""
from __future__ import annotations
import argparse
import json
import sys
from pathlib import Path
RULES = [
("hours", ("營業", "幾點", "時間", "休息", "假期"), "我們的營業時間請見主頁置頂或官方網站,不便之處請見諒。"),
("price", ("價格", "多少錢", "便宜", "折扣", "優惠"), "價格與方案請見置頂說明。這裡先不報未經確認的數字。"),
("complaint", ("壞了", "退", "沒收到", "客訴", "抱怨"), "這則涉及訂單或客訴,請轉交人工處理,不要自動結案。"),
]
def classify(text: str) -> dict:
lowered = text.lower()
for intent, keywords, draft in RULES:
if any(key in lowered or key in text for key in keywords):
return {
"intent": intent,
"draft": draft,
"auto_send": False,
"needs_human": intent == "complaint",
}
return {
"intent": "other",
"draft": "已收到訊息,稍後由專人回覆。",
"auto_send": False,
"needs_human": True,
}
def main() -> int:
parser = argparse.ArgumentParser(description="社群回覆草稿分類器")
parser.add_argument("input", type=Path)
parser.add_argument("-o", "--output", type=Path, required=True)
args = parser.parse_args()
messages = json.loads(args.input.read_text(encoding="utf-8"))
results = []
for item in messages:
text = item.get("text", "")
result = classify(text)
result["id"] = item.get("id")
result["text"] = text
results.append(result)
flag = "需人工" if result["needs_human"] else "僅草稿"
print(f"{item.get('id')} [{result['intent']}] {flag}")
args.output.parent.mkdir(parents=True, exist_ok=True)
args.output.write_text(json.dumps(results, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
print(f"寫出 {len(results)} 筆草稿到 {args.output}。本程式不會連線到任何平台。")
return 0
if __name__ == "__main__":
sys.exit(main())[
{"id": "m1", "text": "請問營業時間到幾點?"},
{"id": "m2", "text": "這個價格可以再便宜嗎"},
{"id": "m3", "text": "我上次買的東西壞了,要怎麼退"},
{"id": "m4", "text": "今天天氣真好"}
]本機執行
python reply_router.py sample_messages.json -o replies.json若之後要用官方介面發送,格式會依平台而異。下面只是請求格式的示意檔,請把端點、權杖與欄位換成該平台文件中的版本;本環境沒有實際送出。
#!/usr/bin/env bash
# 示意:端點、權杖與欄位以該平台官方文件為準。請勿直接拿去打真實端點。
curl -X POST "https://api.example.com/official-messages" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"to":"USER_ID","text":"這是已審核的回覆草稿"}'常見錯誤
- 用瀏覽器自動化或非官方套件去「幫忙登入」並大量回訊息,這通常違反平台條款。
- 把所有訊息都自動回,包含客訴、議價與私人資料。
- 在允許的時間窗外還持續發送行銷訊息。
- 把對話紀錄存到沒有存取控制的地方,或拿去訓練模型。