Files
MATTERMOST_OPENCLAW_LIVESTATUS/plugin/server/websocket.go
sol 09441b34c1 fix: persistent daemon startup, plugin integration, mobile fallback
- Hook handler now loads .env.daemon for proper config (plugin URL/secret, bot user ID)
- Hook logs to /tmp/status-watcher.log instead of /dev/null
- Added .env.daemon config file (.gitignored - contains tokens)
- Added start-daemon.sh convenience script
- Plugin mode: mobile fallback updates post message field with formatted markdown
- Fixed unbounded lines array in status-watcher (capped at 50)
- Added session marker to formatter output for restart recovery
- Go plugin: added updatePostMessageForMobile() for dual-render strategy
  (webapp gets custom React component, mobile gets markdown in message field)

Fixes: daemon silently dying, no plugin connection, mobile showing blank posts
2026-03-08 07:42:27 +00:00

39 lines
1.1 KiB
Go

package main
import (
"encoding/json"
"github.com/mattermost/mattermost/server/public/model"
)
// broadcastUpdate sends a WebSocket event to all clients viewing the given channel.
// The event is auto-prefixed by the SDK to "custom_com.openclaw.livestatus_update".
// All values must be gob-serializable primitives (string, int64, []string, etc.).
// Complex types like []SessionData must be JSON-encoded to a string first.
func (p *Plugin) broadcastUpdate(channelID string, data SessionData) {
// Serialize children to JSON string — gob cannot encode []SessionData
var childrenJSON string
if len(data.Children) > 0 {
b, err := json.Marshal(data.Children)
if err == nil {
childrenJSON = string(b)
}
}
payload := map[string]interface{}{
"post_id": data.PostID,
"session_key": data.SessionKey,
"agent_id": data.AgentID,
"status": data.Status,
"lines": data.Lines,
"elapsed_ms": data.ElapsedMs,
"token_count": data.TokenCount,
"children_json": childrenJSON,
"start_time_ms": data.StartTimeMs,
}
p.API.PublishWebSocketEvent("update", payload, &model.WebsocketBroadcast{
ChannelId: channelID,
})
}