fix whatsapp

This commit is contained in:
LPF
2026-03-10 00:00:01 +08:00
parent 938e762c6b
commit e9a47ac02a
7 changed files with 384 additions and 52 deletions

View File

@@ -71,6 +71,8 @@ type Server struct {
liveRuntimeOn bool
liveSubagentMu sync.Mutex
liveSubagents map[string]*liveSubagentGroup
whatsAppBridge *channels.WhatsAppBridgeService
whatsAppBase string
}
var nodesWebsocketUpgrader = websocket.Upgrader{
@@ -311,6 +313,42 @@ func (s *Server) SetNodeWebRTCTransport(t *nodes.WebRTCTransport) {
func (s *Server) SetNodeP2PStatusHandler(fn func() map[string]interface{}) {
s.nodeP2PStatus = fn
}
func (s *Server) SetWhatsAppBridge(service *channels.WhatsAppBridgeService, basePath string) {
s.whatsAppBridge = service
s.whatsAppBase = strings.TrimSpace(basePath)
}
func (s *Server) handleWhatsAppBridgeWS(w http.ResponseWriter, r *http.Request) {
if s.whatsAppBridge == nil {
http.Error(w, "whatsapp bridge unavailable", http.StatusServiceUnavailable)
return
}
s.whatsAppBridge.ServeWS(w, r)
}
func (s *Server) handleWhatsAppBridgeStatus(w http.ResponseWriter, r *http.Request) {
if s.whatsAppBridge == nil {
http.Error(w, "whatsapp bridge unavailable", http.StatusServiceUnavailable)
return
}
s.whatsAppBridge.ServeStatus(w, r)
}
func (s *Server) handleWhatsAppBridgeLogout(w http.ResponseWriter, r *http.Request) {
if s.whatsAppBridge == nil {
http.Error(w, "whatsapp bridge unavailable", http.StatusServiceUnavailable)
return
}
s.whatsAppBridge.ServeLogout(w, r)
}
func joinServerRoute(base, endpoint string) string {
base = strings.TrimRight(strings.TrimSpace(base), "/")
if base == "" || base == "/" {
return "/" + strings.TrimPrefix(endpoint, "/")
}
return base + "/" + strings.TrimPrefix(endpoint, "/")
}
func (s *Server) rememberNodeConnection(nodeID, connID string) {
nodeID = strings.TrimSpace(nodeID)
@@ -440,6 +478,16 @@ func (s *Server) Start(ctx context.Context) error {
mux.HandleFunc("/webui/api/logs/stream", s.handleWebUILogsStream)
mux.HandleFunc("/webui/api/logs/live", s.handleWebUILogsLive)
mux.HandleFunc("/webui/api/logs/recent", s.handleWebUILogsRecent)
if strings.TrimSpace(s.whatsAppBase) != "" {
base := strings.TrimRight(strings.TrimSpace(s.whatsAppBase), "/")
if base == "" {
base = "/whatsapp"
}
mux.HandleFunc(base, s.handleWhatsAppBridgeWS)
mux.HandleFunc(joinServerRoute(base, "ws"), s.handleWhatsAppBridgeWS)
mux.HandleFunc(joinServerRoute(base, "status"), s.handleWhatsAppBridgeStatus)
mux.HandleFunc(joinServerRoute(base, "logout"), s.handleWhatsAppBridgeLogout)
}
s.server = &http.Server{Addr: s.addr, Handler: mux}
go func() {
<-ctx.Done()

View File

@@ -120,6 +120,53 @@ func TestHandleWebUIWhatsAppQR(t *testing.T) {
}
}
func TestHandleWebUIWhatsAppStatusWithNestedBridgePath(t *testing.T) {
t.Parallel()
bridge := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case "/whatsapp/status":
_ = json.NewEncoder(w).Encode(map[string]interface{}{
"state": "connected",
"connected": true,
"logged_in": true,
"bridge_addr": "127.0.0.1:7788",
"user_jid": "8613012345678@s.whatsapp.net",
"qr_available": false,
"last_event": "connected",
"updated_at": "2026-03-09T12:00:00+08:00",
})
default:
http.NotFound(w, r)
}
}))
defer bridge.Close()
tmp := t.TempDir()
cfgPath := filepath.Join(tmp, "config.json")
cfg := cfgpkg.DefaultConfig()
cfg.Logging.Enabled = false
cfg.Channels.WhatsApp.Enabled = true
cfg.Channels.WhatsApp.BridgeURL = "ws" + strings.TrimPrefix(bridge.URL, "http") + "/whatsapp/ws"
if err := cfgpkg.SaveConfig(cfgPath, cfg); err != nil {
t.Fatalf("save config: %v", err)
}
srv := NewServer("127.0.0.1", 0, "", nil)
srv.SetConfigPath(cfgPath)
req := httptest.NewRequest(http.MethodGet, "/webui/api/whatsapp/status", nil)
rec := httptest.NewRecorder()
srv.handleWebUIWhatsAppStatus(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("expected 200, got %d: %s", rec.Code, rec.Body.String())
}
if !strings.Contains(rec.Body.String(), `"bridge_running":true`) {
t.Fatalf("expected bridge_running=true, got: %s", rec.Body.String())
}
}
func TestHandleWebUIConfigRequiresConfirmForProviderAPIBaseChange(t *testing.T) {
t.Parallel()