跳到主要內容
聯絡我們
AMAX · OMNI DESK區 1 / HeroSPEC
區 1 / Hero

SYSTEM / OMNI-DESK · 多平台客服整合中台

訊息從很多個地方進來,只從一個地方回。

客服不用再開五個後台。每個平台的對話進同一個收件匣,可接手、可釋放、可關閉,狀態即時同步到所有線上的客服。

這是一套純人工客服的整合後台。它不會替你回話,它負責讓每一則該進來的訊息真的進得來。

看它怎麼接住失敗約一場技術對談

WEBHOOK
RECEIVING
POLL FALLBACK
STANDBY
DLQ
0 PENDING
CREDENTIALS
AES-GCM

狀態條為介面示意,非即時資料。

區 2 / 全景架構圖

一則訊息從進來到回出去,要經過七個節點。

下面這張圖是整套系統的全部。接下來四個段落會把其中四個節點放大,講清楚它壞掉時會發生什麼事,以及我們用什麼接住它。

● 沿線移動的圓點 = 一則訊息 · 紅線 = 該段失敗 · 藍色徽章 = 排隊中
來源平台

各家第三方客服 / 社群 / 遊戲平台

壞掉會怎樣不受你控制,這是前提不是問題

接收層

驗簽章、驗租戶 token、驗 payload、落地

壞掉會怎樣訊息靜默消失,沒有任何錯誤訊息

正規化

各平台格式 → 單一內部訊息格式

壞掉會怎樣每加一個平台,下游全部要改一次

佇列

排隊處理,失敗的進死信佇列

壞掉會怎樣一則爛訊息卡住整條線

收件匣

會話接手 / 釋放 / 關閉 + 即時同步

壞掉會怎樣兩個客服同時回同一個人

回覆分派

依會話來源路由回正確平台

壞掉會怎樣回錯人、回錯平台

憑證保管

第三方 API key 加密存放與輪替

壞掉會怎樣客戶的帳號被別人拿去用

區 3 / 接收層

NODE 02

平台送了,但你沒收到——而且它不會再送一次。

這是所有 webhook 整合的根本問題,而且它沒有錯誤訊息。第三方平台把事件 POST 給你,收到 2xx 就當作送達;你的服務剛好在重啟、剛好在 GC、剛好網路抖了一下,這則訊息就永遠不存在了。你的系統一切正常,log 乾乾淨淨,客訴半小時後才到。

對策:一條主線,一條補償線。

項目主線:webhook 接收補償線:輪詢 worker
觸發平台主動推送依排程主動去撈
延遲秒級取決於輪詢間隔
前置檢查簽章驗證 → 企業 token 驗證 → payload 驗證 → 持久化只挑活躍會話去撈,不整批掃
保護healthcheck 端點rate-limit 追蹤 + 批次入列
角色正常情況下的唯一路徑webhook 掉了的時候補資料

輪詢不是「無腦重試」。這支 worker 會追第三方平台的速率上限,撈之前先挑出目前活躍的會話、批次入列,避免補償機制自己把你的 API 額度打爆——webhook 補償最常見的翻車方式就是這個。

poll-fallback-worker · poll-loop / rate-limit-tracker / batch-enqueue / select-active-conversations

區 4 / 正規化

NODE 03

每個平台一種訊息格式。下游只該認識一種。

每接一個新平台,就多一種 JSON 結構、多一組欄位命名、多一套時間格式、多一種「已讀」的定義。如果下游直接吃原始 payload,第三個平台接完你就會開始在收件匣的程式碼裡寫 if (platform === 'xxx'),第五個平台接完就沒人敢改它了。

正規化層是唯一知道平台差異的地方。

RAW

平台原始 payload,欄位命名各自為政

NORMALIZE

對映欄位、統一時間、統一會話識別、標記來源平台

INTERNAL

單一內部訊息格式,下游只認識這一種

好處在加平台的時候才會顯現:新增一個來源平台,改動範圍是一個 adapter,不是整個收件匣。 收件匣、即時同步、回覆分派、稽核日誌完全不需要知道今天多了哪一家。

補充卡

等客戶給憑證不該阻塞開發——第三方平台的正式憑證通常要等客戶走完流程才拿得到,而那往往是專案後期。這套系統把 mock 模式做進了資料庫層的開關,另外附一台獨立的 Docker mock server,所以在真實憑證到位之前,正規化、收件匣、即時同步整條線都已經跑完並測過。這是交付方法,不是玩具——它決定了憑證延誤時專案還能不能往前走。

區 5 / 佇列與 DLQ

NODE 04

處理失敗的訊息,不會消失,會排在一個你看得到的地方。

一則格式異常的訊息、一次資料庫短暫斷線、一個沒預期到的欄位型別——在多數自幹的接收端裡,這些情況的處理方式是 catch 起來寫一行 log,然後訊息就沒了。問題不是它失敗,是沒有人知道它失敗過,也沒有辦法在修好之後把它救回來。

死信佇列(DLQ):失敗是一種狀態,不是一次事件。

RECEIVEDVALIDATINGQUEUEDPROCESSED

驗證或處理失敗則轉

DEAD_LETTERREPLAYIGNORE

「重放」聽起來很小,但它決定了修 bug 的姿態:沒有重放,你修完 bug 只能跟客戶說「那段時間的訊息我們遺失了」;有重放,你修完 bug 按一顆按鈕,那段時間的訊息就補回來了。

POST /api/v1/admin/webhook-events/{payload_id}/replay / …/ignore

1失敗有去處

驗證或處理失敗的事件連同原始 payload 一起進死信佇列,不覆寫、不刪除

2後台看得到

後台有 DLQ 頁面,逐筆列出失敗事件與原因,不需要進資料庫查

3修好可以重放

每筆可一鍵重放(用原始 payload 重跑),或標記忽略並留下紀錄

區 6 / 憑證保管

NODE 07

客戶的 API key 不會明文躺在你的資料表裡。

做第三方整合就一定要保管客戶的憑證。最常見的做法是開一個 credentials 欄位直接把 token 存進去——資料庫備份、log、匯出報表、離職的工程師,任何一個環節外洩,受損的是客戶的帳號,而你在合約上是有責任的。

1AES-GCM 加密

憑證加密後才落地。GCM 同時提供機密性與完整性驗證,被竄改過的密文解不開

2master key 分離

加密金鑰不與資料同放,來自部署環境而非資料庫

3金鑰輪替

有專屬輪替流程。「換一把金鑰」是可執行的操作,不是要停機重寫資料

補充段

另外兩件同一等級的事:稽核日誌的寫入權限被單獨收緊過(有一支專門的資料庫層 policy migration 在做這件事,不是靠應用層自律);個資在寫進 log 之前就被遮罩,不是事後清理。登入端另有 IP 速率限制、登入嘗試紀錄與 email 遮罩。

區 7 / 這裡沒有 AI

SCOPE / 誠實區

這一層要的不是聰明,是不掉訊息。

這套系統裡沒有任何一行呼叫大型語言模型的程式碼,我們也不打算含糊帶過。市面上很多「AI 客服」賣的是回話的品質,而客戶上線後最常遇到的問題不是回得不夠好,是訊息根本沒進來同一個客人被兩個客服各回一次掉了的訊息救不回來。這些是佇列問題、狀態問題、憑證問題,不是模型問題。加一顆再聰明的模型也不會變好。

這套系統做的這套系統不做的
訊息可靠接收、失敗可重放自動回覆客戶問題
多平台格式正規化意圖辨識、情緒分析
會話接手 / 釋放 / 關閉與即時同步建議回覆、自動草稿
憑證加密保管與輪替知識庫問答
稽核日誌與 PII 遮罩任何形式的模型推論

那 AI 可以接在哪裡?

可以,但要說清楚它現在不存在:系統內已有一套話術庫(每位客服有自己的擁有範圍與排序),以及一層會話同步流程——這兩者分別是「語料」與「插入點」,未來要加建議回覆或知識庫問答,架構上有位置可以放。但那一層目前一行都還沒寫,需要另行開發與計價。我們寧可現在講清楚,也不想在 POC 的時候被你發現。

所以正確的說法是——這是 AI-ready 的客服基礎設施,不是 AI 客服。

區 8 / 可靠性佐證

可以查證的部分,只寫可以查證的。

1089
單元測試全數通過
30
Playwright 端對端測試通過
18
資料庫 migration,已套用於雲端環境
3
獨立部署的 worker,各有 Dockerfile

以上數字出自來源系統 README 與 repo 內容,非行銷估算。

交付狀態PENDING UAT

目前狀態:開發完成,待客戶端 UAT。 Wave 0–8 全數完成、已部署至雲端環境。尚未進入正式營運的原因在客戶端——真實平台憑證與使用者驗收測試尚未完成。我們不會把這個狀態說成「已上線服務」。

區 9 / CTA

如果你正在接第三個平台,我們可以聊。

最適合開始談的時機有兩個:一是你已經接了兩三個平台、開始感覺到程式碼裡的 if 越來越多;二是你已經被 webhook 掉包咬過一次,正在找有沒有更成熟的做法。

把你現在的平台清單給我們先看架構圖怎麼接

區 9 / 詢問單

本頁描述的系統為客戶專案交付成果,客戶名稱未經授權不予揭露。頁面內所有介面示意為重繪,非客戶實際資料。