! RAIACHAT - ILLUSTRATIVE EXCERPT, NOT A TESTED PROGRAM
!
! raia Live Chat in a PxPlus *BROWSER (Chromium) control.
! Docs adaptation of a supplied starter. It has not been run on any PxPlus
! version. *BROWSER, NAVIGATE, EXECJS and DELETE OBJECT come from the PxPlus
! manual (https://manual.pvxplus.com/PXPLUS/utilities/browser.htm). Syntax,
! return values and events depend on your PxPlus version: check each line
! against the manual for the version you run before using it.
!
! EXECJS runs the script in the loaded page and returns its result, if any.
! It does not by itself wait for raia's asynchronous acknowledgement of a
! command: its return value is NOT a raia acknowledgement and does not mean
! the agent received anything.
!
! Call:  CALL "RAIACHAT",FNAME$,LNAME$,EMAIL$,ACCT$
!
ENTER FNAME$,LNAME$,EMAIL$,ACCT$
!
! CHANGE THIS: the exact HTTPS URL where you host web/raia-chat.html.
LET CHAT_URL$="https://support.example.com/raia-chat.html"
!
! Browser history: *BROWSER runs incognito by default (system parameter 'BI'
! On). Keeping history means a later user of the same Windows account may see
! the earlier chat. Decide deliberately. If you change 'BI', do it before the
! first browser object is created; see the PxPlus manual for the exact syntax.
! With 'BI' Off, closing and recreating the object does NOT clear stored chat
! state: confirm it is cleared, or give each user a fresh isolated profile.
!
PRINT 'WINDOW'(0,0,80,25,"Support chat"),
DEF OBJECT RAIA,@(0,0,80,25),"*BROWSER"
RAIA'NAVIGATE(CHAT_URL$)
!
! Bounded readiness check: at most 50 tries x 0.2 s (about 10 seconds).
LET READY=0
FOR I=1 TO 50
 LET READY=RAIA'EXECJS("typeof window.raiaHost==='object'?1:0")
 IF READY=1 THEN BREAK
 WAIT .2
NEXT I
IF READY<>1 THEN GOTO NOT_READY
!
! Pass the signed-in user as context (not sign-in or access control).
! Every value goes through FN_JS$ so names like O'Brien don't break the call.
LET JS$="window.raiaHost.setUser({firstName:"+FN_JS$(FNAME$)+",lastName:"+FN_JS$(LNAME$)
LET JS$=JS$+",email:"+FN_JS$(EMAIL$)+",customData:{accountId:"+FN_JS$(ACCT$)
LET JS$=JS$+",source:'PxPlus app'}})"
LET X=RAIA'EXECJS(JS$)
! X is only the immediate EXECJS result. Confirm in the chat that the agent
! uses the name, and ask a question to see a real reply.
!
! Optional: short, non-sensitive screen context.
! LET X=RAIA'EXECJS("window.raiaHost.setContext("+FN_JS$("Screen: Billing")+")")
!
! ... your application's own event loop runs here. Handle the *BROWSER events
! your PxPlus version documents (navigation, new windows, links) using the
! manual; this excerpt does not define them. Before PxPlus 2026 Update 1, a
! BeforeNavigate or BeforeNavigate2 handler must not call EXECJS or use the
! Document, Location, Window or related properties: the manual warns the
! system will hang.
!
! Sign-out on a shared PC: ask the page to clear the user and context and
! reset, then close the object. EXECJS does not wait for the page's
! asynchronous sign-out to finish, so do not reuse this browser object for
! the next user. Test that the next user's chat starts without the earlier
! name, context or conversation.
! LET X=RAIA'EXECJS("window.raiaHost.signOut('pxplus-signout')")
DELETE OBJECT RAIA
PRINT 'POP',
EXIT
!
NOT_READY:
 DELETE OBJECT RAIA
 PRINT 'POP',
 MSGBOX "Chat is unavailable. Check your internet connection and try again.","Support chat"
 EXIT
!
! Quote a value as a JavaScript string literal: escapes \ and ', removes
! carriage returns and turns line feeds into spaces.
DEF FN_JS$(V$)
 LET V$=SUB(V$,"\","\\")
 LET V$=SUB(V$,"'","\'")
 LET V$=SUB(V$,$0D$,"")
 LET V$=SUB(V$,$0A$," ")
 RETURN "'"+V$+"'"
END DEF
