feat: granular WebSocket message.new events
- WebSocket now detects new ContactMessages and broadcasts message.new events with contactId, text, channel, direction - Frontend handles message.new: refreshes timeline for open chat, refreshes contacts for sidebar preview update - dashboard.changed still fires for non-message changes Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,18 @@
|
||||
import { ref } from "vue";
|
||||
|
||||
export type RealtimeNewMessage = {
|
||||
contactId: string;
|
||||
contactName: string;
|
||||
text: string;
|
||||
channel: string;
|
||||
direction: string;
|
||||
at: string;
|
||||
};
|
||||
|
||||
export function useCrmRealtime(opts: {
|
||||
isAuthenticated: () => boolean;
|
||||
onDashboardChanged: () => Promise<void>;
|
||||
onNewMessage?: (msg: RealtimeNewMessage) => void;
|
||||
}) {
|
||||
const crmRealtimeState = ref<"idle" | "connecting" | "open" | "error">("idle");
|
||||
let crmRealtimeSocket: WebSocket | null = null;
|
||||
@@ -99,10 +109,13 @@ export function useCrmRealtime(opts: {
|
||||
const raw = typeof event.data === "string" ? event.data : "";
|
||||
if (!raw) return;
|
||||
try {
|
||||
const payload = JSON.parse(raw) as { type?: string };
|
||||
const payload = JSON.parse(raw) as { type?: string; [key: string]: any };
|
||||
if (payload.type === "dashboard.changed") {
|
||||
scheduleCrmRealtimeRefresh();
|
||||
}
|
||||
if (payload.type === "message.new" && opts.onNewMessage) {
|
||||
opts.onNewMessage(payload as unknown as RealtimeNewMessage);
|
||||
}
|
||||
} catch {
|
||||
// ignore malformed realtime payloads
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user