feat(gateway): webhook 渠道 InboundHandler 挂载到网关(渠道遗留2)
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled

让 webhook 渠道的入站 HTTP 回调真正进运行时(此前 handler 建了但未挂载,回调不达 runtime)。

- channelbridge:Bridge.WebhookHandlers() map[string]http.Handler——遍历适配器,对暴露
  InboundHandler()/Config() 的(*webhook.Adapter)收集 endpointPath→handler。
- gateway/server.go:Deps 加 Webhooks map[string]http.Handler;Server 存 webhooks;
  Handler() 挂载到 mux(无网关鉴权,各 handler 自带 HMAC 签名校验)。
- gateway/static.go:spa 加 isWebhookRoute——已注册的 webhook 路径交给 API mux(否则被 SPA
  fallback 吞成 index.html,webhook 回调不达)。
- wire.go:gateway.Deps 传 Webhooks: a.channelBridge.WebhookHandlers()(wireChannels 在
  wireFrontend 前执行,bridge 已建好)。

实机验证:POST /webhook 空体→bad_request(400,webhook 解码响应非 SPA)、带 JSON→accepted(200)、
GET /webhook 被 webhook 路由处理。go build/vet/test 全绿。
This commit is contained in:
Aska committed 2026-09-06 20:40:49 +08:00
1 parent adad4e1f62
commit 76134ed47e
4 files changed
+70 -1

No files matched your search

+12 -1
View File
@@ -13,7 +13,7 @@ import (
func (s *Server) spa(api http.Handler) http.Handler {
fileServer := s.spaFileServer()
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if isAPIRoute(r.URL.Path) {
if isAPIRoute(r.URL.Path) || s.isWebhookRoute(r.URL.Path) {
api.ServeHTTP(w, r)
return
}
@@ -21,6 +21,17 @@ func (s *Server) spa(api http.Handler) http.Handler {
})
}
// isWebhookRoute reports whether path is a registered external webhook callback
// route. Such paths must reach the API mux (where the webhook handler is
// mounted) rather than the SPA file fallback, so inbound callbacks are served.
func (s *Server) isWebhookRoute(p string) bool {
if len(s.webhooks) == 0 {
return false
}
_, ok := s.webhooks[p]
return ok
}
// spaFileServer serves static assets, falling back to index.html for paths that
// are not real files in the embedded/external dist.
func (s *Server) spaFileServer() http.Handler {