一、整體架構
方案 A:直連模式(默認)
方案 B:反向代理模式(推薦)
核心原則:前端不直接調用微信 API,所有微信接口調用都通過 Supabase Edge Functions 代理,避免在客戶端暴露AppSecret。用戶可以選擇直連模式或反向代理模式解決 IP 白名單問題。
二、前置準備
2.1 微信開發者平台後台配置
在 微信開發者平台 完成以下操作:-
獲取開發者憑證
- 訪問 微信開發者平台
- 選擇對應的公眾號
- 在「基礎信息」中查看或重置
- 記錄
AppID(開發者 ID) - 記錄或重置
AppSecret(開發密鑰)
-
配置 IP 白名單
- 在「基礎信息 → 開發密鑰 → API IP白名單」中添加 Edge Function 的出口 IP
- ⚠️ 重要:Supabase Edge Functions 使用動態 IP,首次調用會返回
errcode: 40164,從錯誤信息中提取 IP 並添加到白名單 - 提取方式:解析
errmsg中的invalid ip x.x.x.x
-
確認公眾號類型
- 已認證的服務號擁有全部接口權限
- 訂閱號部分接口受限(如自定義菜單、數據統計)
2.2 Supabase 項目配置
-
環境變數 / Edge Function Secrets
需要配置以下 Secrets(通過 Supabase Dashboard 或 CLI):
Secret 名称 說明 示例 SUPERUN_WECHAT_APP_ID公眾號 AppID wx1234567890abcdefSUPERUN_WECHAT_APP_SECRET公眾號 AppSecret a1b2c3d4e5f6...SUPERUN_WECHAT_API_PROXY_URL反向代理地址(可選) https://wechat-proxy.example.comSUPABASE_URLSupabase 項目 URL(內置) https://xxxxx.supabase.coSUPABASE_ANON_KEYSupabase 匿名密鑰(內置) eyJhbG...SUPABASE_SERVICE_ROLE_KEYSupabase 服務角色密鑰(內置) eyJhbG...其中
SUPABASE_URL、SUPABASE_ANON_KEY、SUPABASE_SERVICE_ROLE_KEY是 Supabase 內置的,無需手動配置。SUPERUN_WECHAT_API_PROXY_URL為可選項,不配置則直連微信 API(需手動維護 IP 白名單),配置後所有微信請求走代理服務器。 -
Edge Function 配置(
supabase/config.toml)verify_jwt = false允許 Edge Function 之間互相調用。認證邏輯在函數內部通過解析 JWT 手動實現。
三、數據庫表結構
3.1 wechat_tokens — 令牌緩存表
3.2 articles — 圖文內容表
3.3 menu_configs — 菜單配置表
3.4 auto_reply_rules — 自動回復規則表
四、Edge Functions 詳解
4.1 wechat-token — 令牌管理服務
職責:獲取並緩存微信 access_token,所有其他 Edge Function 通過調用此服務獲取令牌。
請求方式:GET 或 POST
核心邏輯:
4.2 wechat-data — 數據統計服務
職責:代理微信數據統計接口(datacube)和粉絲 / 菜單查詢。
請求方式:POST
TokenResult 模式(所有需要 access_token 的函數統一使用):
關鍵設計:當令牌獲取失敗(如 IP 被封)時,不拋異常,而是返回 { blocked_ip } 給前端,讓前端展示友好提示。
支持的 action:
| action | 微信 API | 說明 | 日期限制 |
|---|---|---|---|
get-menu | GET /cgi-bin/menu/get | 獲取當前菜單 | 无 |
get-follower-count | GET /cgi-bin/user/get | 獲取粉絲總數 | 无 |
user-summary | POST /datacube/getusersummary | 用戶增減數據 | 最多 7 天 |
user-cumulate | POST /datacube/getusercumulate | 累計用戶數據 | 最多 7 天 |
article-summary | POST /datacube/getarticlesummary | 圖文群發日數據 | 最多 1 天 |
article-total | POST /datacube/getarticletotal | 圖文群發總數據 | 最多 1 天 |
upstream-msg | POST /datacube/getupstreammsg | 消息概況 | 最多 7 天 |
interface-summary | POST /datacube/getinterfacesummary | 接口分析 | 最多 30 天 |
4.3 wechat-articles — 圖文管理服務
職責:圖文 CRUD、發布到微信、從微信同步已發布文章。
支持的 action:
| action | 說明 | 需要認證 |
|---|---|---|
save-draft | 保存 / 更新草稿 | ✅ |
publish | 發布到微信(草稿 → 群發) | ✅ |
delete | 軟刪除文章 | ✅ |
sync-published | 從微信同步已發布文章 | ✅ |
4.4 wechat-menu — 自定義菜單服務
職責:將本地菜單配置同步到微信、清空微信菜單。
支持的 action:
| action | 說明 | 参数 |
|---|---|---|
publish | 發布菜單到微信 | menu_config_id (必填) |
delete | 清空微信菜單 | menu_config_id (可選) |
publish 時發現菜單為空(button.length === 0),自動調用 delete 接口清空微信菜單,而非創建一個空菜單。
菜單數據結構(微信標準格式):
五、前端集成模式
5.1 統一的 Hook 封裝
所有微信 API 調用都封裝為 React Query hooks:5.2 IP 白名單錯誤處理(通用模式)
所有與微信交互的頁面都實現了統一的 IP 白名單錯誤處理:5.3 手動同步(連通性檢查)
六、關鍵注意事項
6.1 IP 白名單問題 — 兩種解決方案
Supabase Edge Functions 使用動態出口 IP,無法預先配置白名單。用戶可根據自身情況選擇以下任一方案:方案 A:IP 白名單(手動維護)
適合場景:快速驗證、臨時使用、沒有服務器資源。 步驟:- 首次調用微信 API 會返回
errcode: 40164 - 從
errmsg中提取被拒絕的 IP:invalid ip x.x.x.x - 將該 IP 添加到公眾號白名單
- 應用前端會展示橙色提示條,支持一鍵複製 IP
- Edge Function IP 可能會變動,需要重新添加
- 需要手動操作微信後台
方案 B:反向代理(推薦,一勞永逸)
適合場景:生產環境、長期使用、不想每次 IP 變動都手動加白名單。 原理:在一台有固定公網 IP 的服務器上部署 Nginx 反向代理,所有微信 API 請求都經過這台服務器轉發。微信只看到代理服務器的固定 IP,加一次白名單就永久生效。 步驟 1:部署代理服務器 準備一台有固定公網 IP 的服務器(雲服務器即可,最低配置就行),安裝 Nginx,配置如下:也可以用 HTTP(端口 80),但建議使用 HTTPS 保證傳輸安全。步驟 2:配置微信 IP 白名單 將代理服務器的固定公網 IP 添加到微信開發者平台「基礎信息 → 開發密鑰 → API IP白名單」。 步驟 3:配置 Edge Function Secret 在 Supabase 後台添加 Edge Function Secret:
| Secret 名称 | 值 | 示例 |
|---|---|---|
SUPERUN_WECHAT_API_PROXY_URL | 代理服務器地址 | https://wechat-proxy.your-domain.com |
注意:地址末尾不要加 /。
步驟 4:驗證
配置完成後重新部署 Edge Functions,調用任意微信接口驗證連通性。
代碼層面的實現:
所有 Edge Function 均通過以下一行代碼自動切換直連 / 代理模式:
- 未配置
SUPERUN_WECHAT_API_PROXY_URL→ 直連api.weixin.qq.com(方案 A) - 已配置 → 所有請求走代理地址(方案 B)
wechat-token(1 處)wechat-data(8 處)wechat-articles(3 處)wechat-menu(3 處)
- 從方案 A 切到方案 B:添加
SUPERUN_WECHAT_API_PROXY_URLSecret 並重新部署 - 從方案 B 切回方案 A:刪除該 Secret 並重新部署
- 切換無需修改任何代碼
兩種方案對比
| 方案 A:IP 白名單 | 方案 B:反向代理 | |
|---|---|---|
| 配置難度 | 無需額外服務器 | 需要一台雲服務器 + 域名 |
| 維護成本 | IP 變動時需手動更新 | 配置一次後無需維護 |
| 穩定性 | 依賴 Edge Function IP 不變 | 始終穩定 |
| 適合場景 | 開發測試、臨時使用 | 生產環境、長期運行 |
| 切換方式 | 默認 | 添加/刪除 Secret 即可 |
6.2 Access Token 管理
- 微信 access_token 有效期 2 小時,每日調用次數有限
- 通過
wechat_tokens表緩存,提前 5 分鐘刷新 - 所有 Edge Function 都通過調用
wechat-token函數獲取令牌,避免重複請求 - 定期清理過期令牌記錄
6.3 微信 API 常見 errcode
| errcode | 含義 | 處理方式 |
|---|---|---|
40001 | access_token 無效 | 清除緩存重新獲取 |
40164 | IP 不在白名單 | 提取 IP 提示用戶添加 |
42001 | access_token 過期 | 自動刷新 |
46003 | 菜單不存在 | 正常情況,返回空菜單 |
61501 | 日期範圍超限 | 檢查日期區間是否超過 API 限制 |
45047 | 超出發布頻率限制 | 提示用戶稍後重試 |
6.4 數據統計日期限制
- 微信數據有 1 天延遲,
end_date最早只能是昨天 getusersummary/getusercumulate:最大跨度 7 天(含首尾)getarticlesummary/getarticletotal:最大跨度 1 天getupstreammsg:最大跨度 7 天getinterfacesummary:最大跨度 30 天- 日期格式:
YYYY-MM-DD
6.5 freepublish/batchget 字段注意
- 該接口返回的每條記錄中,標識字段名為
article_id,不是media_id media_id是草稿箱接口(draft/add)返回的字段- 混淆這兩個字段會導致同步時所有值為
undefined,數據無法寫入
6.6 Edge Function 間調用
wechat-data、wechat-articles、wechat-menu都通過 HTTP 調用wechat-token- 調用時使用
SUPABASE_ANON_KEY或SUPABASE_SERVICE_ROLE_KEY做 Bearer Token config.toml中設置verify_jwt = false以允許跨函數調用
6.7 錯誤返回策略
所有涉及微信 API 的 Edge Function 統一遵循:- 令牌獲取失敗 + IP 被封:返回 HTTP
200+{ blocked_ip: "x.x.x.x" }- 返回 200 是為了讓前端
supabase.functions.invoke()能正確讀取data(非 200 會被放入error)
- 返回 200 是為了讓前端
- 微信 API 業務錯誤:返回 HTTP
200+{ error: "...", errcode: xxx } - 系統錯誤:返回 HTTP
500+{ error: "..." }
七、部署清單
第一次部署前檢查
通用步驟(兩種方案都需要):- 微信開發者平台已獲取
AppID和AppSecret - Supabase Edge Function Secrets 已配置
SUPERUN_WECHAT_APP_ID和SUPERUN_WECHAT_APP_SECRET - 數據库已創建
wechat_tokens、articles、menu_configs、auto_reply_rules表 -
supabase/config.toml中所有微信相關函數已設置verify_jwt = false
- 部署後首次調用,從錯誤響應中獲取 Edge Function 出口 IP
- 將出口 IP 添加到微信開發者平台 IP 白名單
- 再次調用驗證連通性
- 部署代理服務器(Nginx 配置見 6.1 節)
- 將代理服務器的固定 IP 添加到微信 IP 白名單
- 配置 Edge Function Secret
SUPERUN_WECHAT_API_PROXY_URL - 重新部署並驗證連通性

