PageSourceSearch

https://ali2woo.com/wp-content/plugins/pgn-ai-chatbot-assistant/assets/js/chat-widget-init.js?ver=1.2.0

js ali2woo.com collected 2026-10-01 10:36:37 UTC 5,165 bytes, 149 lines download raw bytes

1function getChatStorageKey(chatbotId) {
2    return 'pgnai_chat_' + chatbotId;
3}
4
5function readChatState(chatbotId) {
6    try {
7        const raw = window.localStorage.getItem(getChatStorageKey(chatbotId));
8        if (!raw) return null;
9        const parsed = JSON.parse(raw);
10        return parsed && typeof parsed === 'object' ? parsed : null;
11    } catch (e) {
12        // ignore private mode / parse errors
13        return null;
14    }
15}
16
17function writeChatState(chatbotId, state) {
18    try {
19        if (!state || !state.conversationId) return;
20        window.localStorage.setItem(getChatStorageKey(chatbotId), JSON.stringify(state));
21    } catch (e) {
22        // ignore private mode / storage errors
23    }
24}
25
26async function getConversation(chatbotConfig) {
27    const chatbotId = chatbotConfig.chatbotId;
28    const useLocalMemory = !!chatbotConfig.useLocalMemory;
29
30    const storedState = readChatState(chatbotId);
31
32    // Cache-first path: skip the server call when local memory is enabled and this
33    // visitor already owns a browser-scoped conversation. The unified key holds the
34    // conversation id, the message history and the lead-captured flag together.
35    if (useLocalMemory && storedState && storedState.conversationId) {
36        return {
37            conversationId: storedState.conversationId,
38            initialMessages: Array.isArray(storedState.messages) ? storedState.messages : [],
39            leadAlreadyCaptured: !!storedState.leadCaptured,
40        };
41    }
42
43    const response = await PGNAIPlugin.ApiWrapper.call(
44        'getConversation',
45        {
46            chatbot_id: chatbotId,
47            public_id: storedState ? storedState.conversationId : '',
48        }
49    );
50
51    if (response.state === 'ok' && response.data && response.data.public_id) {
52        const publicId = response.data.public_id;
53        const initialMessages = Array.isArray(response.data.initialMessages)
54            ? response.data.initialMessages
55            : [];
56        const leadAlreadyCaptured = !!response.data.leadAlreadyCaptured;
57
58        writeChatState(chatbotId, {
59            conversationId: publicId,
60            messages: initialMessages,
61            leadCaptured: leadAlreadyCaptured,
62        });
63
64        return {
65            conversationId: publicId,
66            initialMessages,
67            leadAlreadyCaptured,
68        };
69    }
70
71    return {
72        conversationId: storedState ? storedState.conversationId : '',
73        initialMessages: [],
74        leadAlreadyCaptured: storedState ? !!storedState.leadCaptured : false,
75    };
76}
77
78async function processQueue() {
79    const queue = window.PGNAIChatWidgetQueue || [];
80
81    for (const item of queue) {
82        const root = document.getElementById(item.containerId);
83
84        const chatbotConfig = window.PGNAIChatWidgetConfig
85            ? window.PGNAIChatWidgetConfig[item.scriptId]
86            : null;
87
88        if (!root || !chatbotConfig) continue;
89
90        let Component = null;
91        try {
92            Component = await PGNAIPlugin.Ui.waitForComponent(
93                'PGNAIComp.ChatWidgetContainer.ChatWidgetContainer', 5000, 100
94            );
95        } catch (e) {
96            console.warn('Component not found for ' + item.scriptId + ':', e?.message || e);
97            continue;
98        }
99
100        let conversationId = chatbotConfig.conversationId;
101        let initialMessages = chatbotConfig.initialMessages;
102        let leadAlreadyCaptured = !!chatbotConfig.leadAlreadyCaptured;
103
104        if (!chatbotConfig.isPreviewMode) {
105            // Skip the server call for a brand-new visitor: the conversation is only
106            // created lazily when they send their first message. Returning visitors
107            // reconnect to their existing conversation via its stored public id.
108            const storedState = readChatState(chatbotConfig.chatbotId);
109
110            if (storedState && storedState.conversationId) {
111                const resolved = await getConversation(chatbotConfig);
112                conversationId = resolved.conversationId;
113                initialMessages = resolved.initialMessages;
114                leadAlreadyCaptured = resolved.leadAlreadyCaptured;
115            }
116        }
117
118        const chatRef = wp.element.createRef();
119
120        const sharedProps = {
121            ref: chatRef,
122            apiWrapper: PGNAIPlugin.ApiWrapper,
123            formatDate: PGNAIHelper.formatDate,
124            ...chatbotConfig,
125            initialMessages,
126            conversationId,
127            leadAlreadyCaptured,
128        };
129
130        PGNAIPlugin.Ui.renderReact(Component, sharedProps, root);
131    }
132}
133
134function registerConversationStorageSync() {
135    window.addEventListener('storage', function (event) {
136        if (!event.key) return;
137        if (!/^pgnai_chat_\d+$/.test(event.key)) return;
138
139        // Another tab of the same browser changed the visitor's unified chat state
140        // (conversation id and/or cached messages). Re-resolve and re-render so the
141        // current tab stays in sync without a reload.
142        processQueue();
143    });
144}
145
146document.addEventListener('DOMContentLoaded', async function () {
147    registerConversationStorageSync();
148    processQueue();
149});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.