2026年11月14日

社群自動回覆:只用正式 API 的接法與界線

社群PythonAPI

常見需求:希望串接 Instagram、Facebook、LINE 或類似平台,讀取留言或私訊,再自動回覆。這件事能做的前提,是平台有提供正式介面,而且你的用法符合該平台條款。本篇不示範如何規避登入、也不提供爬蟲或非官方自動化。

這次測試到哪裡

reply_router.py 已在本機用四則示範訊息測過:營業時間、價格、客訴與其他,分類結果符合預期,且全部標記為「只產生草稿、不自動送出」。沒有向任何平台註冊應用程式、沒有取得權杖,也沒有送出真實訊息。下文的 API 範例是請求格式說明,尚未對真實端點執行。

三層怎麼分工

層做什麼
收集只用該平台正式提供的 Webhook 或讀取介面接收訊息。
決策先做意圖分類,決定要草稿回覆、轉人工,還是不回。
送出僅在條款允許的範圍內,用正式發送介面送出;客訴與不確定的內容不自動送。

先看平台允不允許

Meta 為粉絲專頁與 Instagram 專業帳號提供 Messaging 相關文件,包含標準訊息時間窗等限制,詳細規則以 Messenger Platform 文件 與當下政策為準。LINE 則有官方的 Messaging API,設定與限制以 LINE Developers 文件為準。TikTok 等平台能用哪些官方介面、能不能自動回覆,同樣只能以該平台開發者文件為準;沒有正式、被允許的方法,就不要做。

不要用未授權的方式登入他人帳號、不要用自動化操控一般使用者的個人頁,也不要把蒐集到的對話拿去訓練模型或轉賣。個人資料的收集、保存與刪除,要符合《個人資料保護法》與你的隱私政策。

先做分類器,再談發送

下面這個程式只讀本機的 JSON,寫出回覆草稿。客訴會標成需要人工。把它接到正式 API 之前,先在本機看分類對不對。

reply_router.py
#!/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())
sample_messages.json
[
  {"id": "m1", "text": "請問營業時間到幾點?"},
  {"id": "m2", "text": "這個價格可以再便宜嗎"},
  {"id": "m3", "text": "我上次買的東西壞了,要怎麼退"},
  {"id": "m4", "text": "今天天氣真好"}
]

本機執行

python reply_router.py sample_messages.json -o replies.json

若之後要用官方介面發送,格式會依平台而異。下面只是請求格式的示意檔,請把端點、權杖與欄位換成該平台文件中的版本;本環境沒有實際送出。

official-send.example.sh
#!/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":"這是已審核的回覆草稿"}'

常見錯誤

下載