Fix widget message persistence
This commit is contained in:
@@ -63,6 +63,7 @@ async function route(req, res) {
|
||||
|
||||
if (url.pathname === "/api/widget/config" && req.method === "GET") return widgetConfig(res, url);
|
||||
if (url.pathname === "/api/widget/conversations" && req.method === "POST") return createConversation(req, res);
|
||||
if (url.pathname.match(/^\/api\/widget\/conversations\/[^/]+$/) && req.method === "GET") return getVisitorConversation(res, url);
|
||||
if (url.pathname.match(/^\/api\/widget\/conversations\/[^/]+\/messages$/) && req.method === "POST") return createVisitorMessage(req, res, url);
|
||||
if (url.pathname.match(/^\/api\/widget\/conversations\/[^/]+\/events$/) && req.method === "GET") return eventStream(req, res, url, "visitor");
|
||||
if (url.pathname.match(/^\/api\/widget\/conversations\/[^/]+\/typing$/) && req.method === "POST") return visitorTyping(req, res, url);
|
||||
@@ -325,6 +326,13 @@ function widgetConfig(res, url) {
|
||||
return json(res, 200, { site: formatSite(site), publicBaseUrl: PUBLIC_BASE_URL });
|
||||
}
|
||||
|
||||
function getVisitorConversation(res, url) {
|
||||
const conversation = findConversation(publicIdFrom(url));
|
||||
if (!conversation) return json(res, 404, { error: "conversation_not_found" });
|
||||
if (conversation.visitor_token !== url.searchParams.get("visitorToken")) return json(res, 403, { error: "forbidden" });
|
||||
return json(res, 200, conversationDetails(conversation));
|
||||
}
|
||||
|
||||
async function createConversation(req, res) {
|
||||
const body = await readJson(req, 8_000_000);
|
||||
if (!body.message || !String(body.message).trim()) return json(res, 400, { error: "message_required" });
|
||||
@@ -371,7 +379,7 @@ async function createConversation(req, res) {
|
||||
const conversation = db.prepare("SELECT * FROM conversations WHERE id = ?").get(insert);
|
||||
publish("admin", { type: "conversation:new", conversation: formatConversationSummary(conversation) });
|
||||
publishConversation(conversation, { type: "message:new", payload: conversationDetails(conversation) });
|
||||
return json(res, 201, { conversation: conversationDetails(conversation), visitorToken });
|
||||
return json(res, 201, conversationDetails(conversation));
|
||||
}
|
||||
|
||||
async function createVisitorMessage(req, res, url) {
|
||||
@@ -382,6 +390,7 @@ async function createVisitorMessage(req, res, url) {
|
||||
if (!conversation) return json(res, 404, { error: "conversation_not_found" });
|
||||
const messageId = insertMessage(conversation.id, "visitor", conversation.visitor_name || "Visitor", String(body.message).trim());
|
||||
saveAttachments(conversation.id, messageId, body.attachments || []);
|
||||
updateVisitorContext(conversation.id, body);
|
||||
bumpConversation(conversation.id, conversation.status === "resolved" ? "open" : conversation.status);
|
||||
const updated = findConversation(conversation.public_id);
|
||||
publishConversation(updated, { type: "message:new", payload: conversationDetails(updated) });
|
||||
@@ -482,6 +491,28 @@ function bumpConversation(conversationId, status) {
|
||||
`).run(status, conversationId);
|
||||
}
|
||||
|
||||
function updateVisitorContext(conversationId, body) {
|
||||
db.prepare(`
|
||||
UPDATE conversations
|
||||
SET current_url = COALESCE(?, current_url),
|
||||
referrer = COALESCE(?, referrer),
|
||||
browsing_history_json = COALESCE(?, browsing_history_json),
|
||||
device_json = COALESCE(?, device_json),
|
||||
language = COALESCE(?, language),
|
||||
timezone = COALESCE(?, timezone),
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
WHERE id = ?
|
||||
`).run(
|
||||
nullish(body.currentUrl),
|
||||
nullish(body.referrer),
|
||||
body.browsingHistory ? JSON.stringify(body.browsingHistory) : null,
|
||||
body.device ? JSON.stringify(body.device) : null,
|
||||
nullish(body.language),
|
||||
nullish(body.timezone),
|
||||
conversationId
|
||||
);
|
||||
}
|
||||
|
||||
function conversationDetails(conversation) {
|
||||
const messages = db.prepare("SELECT * FROM messages WHERE conversation_id = ? ORDER BY id ASC").all(conversation.id);
|
||||
const attachments = db.prepare("SELECT * FROM attachments WHERE conversation_id = ? ORDER BY id ASC").all(conversation.id);
|
||||
|
||||
Reference in New Issue
Block a user