Visitor Front-End API
Puzzel Contact Centre Chat Visitor Front-End API
This document describes how to control the behavior of the Puzzel Contact Centre Chat Visitor application injected on customer web pages for more complex integrations.
This document covers the front-end API that is available in the browser when Puzzel’s script tag is injected, and our application is started.
Through the front-end API any external script running on the same web page can:
Get information about the current state in the Puzzel application (useful for testing, debugging and custom logic)
Perform actions through exposed functions that can be called by other scripts
Get notified and (optionally) transform data at specific lifecycle points in the Puzzel application by implementing hook-functions (some hooks like the “pzlOnBefore…”-hooks can act as middleware in more advanced scenarios)
Get information
Information about the current application state is exposed in the global browser context under:
window.pzl
(for debugging/testing you can view the content of this object by opening the browser dev tools and just type pzl
in the console).
The pzl
-object is created when Puzzel’s application “pzl_loader.js” has loaded and started (see the “Hooks”-section of this document for more information about how to determine when the API is ready to use).
During runtime, the pzl
-object will be populated with various state information and API-functions.
These are the main properties exposed under window.pzl
:
pzl.version = { ... }
contains an object with versions and build time for all Puzzel modules currently loaded:
Example:
pzl.version
{
"moduleLoader": "1.1.0.154195 (2024-11-13T10:26:51.619Z)",
"renderModule": "1.0.0.153984 (2024-11-12T09:58:47.371Z)",
"chatModule": "1.0.3.153708 (2024-11-07T12:25:59.194Z)"
}
pzl.info = { ... }
contains various information about e.g. which site mapping is currently matching the URL, which configuration is used (id, name and version) and which modules are currently loaded.
pzl.info.loadedModules = { ... }
contains similar info as pzl.version
pzl.info.activeChains = { ... }
contains information about which interaction chains that are currently active on the page, and for each active chain, which interaction is currently loaded/displayed.
An interaction chain is usually identified by the ruleId
of the rule that initially triggered it, i.e. usually chainId
=== ruleId
. But if an interaction chain is started using the API (see “Perform actions” section below), the chainId
can be set manually (or the default value will be “api” if not specified).
Example:
pzl.info
{
"loadedModules": {
"moduleLoader": { ... },
"renderModule": { ... },
"chatModule": { ... }
},
"siteMappingName": "Swedish site",
"configId": "bf960cfa-0154-426a-b785-74f8c3a9725a",
"configVersion": "34",
"configName": "My test config",
"activeChains": {
"74b321a8-6ba2-4f7a-a4da-914e2bf49499": {
"chainId": "74b321a8-6ba2-4f7a-a4da-914e2bf49499",
"ruleId": "74b321a8-6ba2-4f7a-a4da-914e2bf49499",
"ruleName": "Rule for all",
"currentInteractionId": "6394745c-6ab7-40be-b176-1cef22f889d0"
}
}
}
Perform actions
To control the Puzzel visitor application and modules from custom scripts, the application exposes some API-functions under pzl.api = { ... }
. Some types of sub-modules will add their own API-functions under pzl.api
when launched (e.g. chat-module when a visitor starts a chat)
These are the API-functions always available (exposed by “pzl_loader.js”):
pzl.api.triggerRule({...}) | Trigger a specific rule configured in the web engage admin portal, just as if its conditions matched. Its outcome configuration will be evaluated, so if e.g. different start-interactions are set for different timemodule-exits, the outcome will launch different interactions depending on the current time of day, etc. The function takes an object as argument with the following properties:
Either
The property Any other properties in this object will be passed on as input-data to the first interaction (existing properties with the same key will be overridden). pzl.api.triggerRule({ ruleName: 'My rule' });
|
pzl.api.showInteraction({...}) | Show a specific interaction configured in the web engage admin portal. The function takes an object as argument with the following properties:
The property Any other properties in this object will be passed on as input-data to the interaction. Examples: pzl.api.showInteraction({ interactionId: 'some-guid' });
pzl.api.showInteraction({ |
pzl.api.nextInteraction({...}) | This function will transition to the next interaction in an interaction chain. E.g. from “chat” -> “survey”, etc. If there is no next interaction in the chain (i.e. the currently loaded interaction is last in its chain), the chain will be closed. Note: Some interactions may link to more than one next interaction (e.g. a panel with multiple buttons). In that case, next interaction will be the first one with a valid link found in its configuration. The function takes an object as argument with the following properties:
The property The property Any other properties in this object will be passed on as input-data to the next interaction if possible. Note: For some transitions, e.g. from chat with The Examples: // Transition chain "api" to its next interaction // Transition chain "rule-guid" and also add/update the "queueKey"-property |
pzl.api.minimizeInteraction({...}) | This function will set/toggle minimize state of the currently active interaction in chain with Note: Interactions that are rendered injected in the page DOM (i.e. has its “Parent DOM element selector” set to anything else than “body”) will currently ignore this call. The function takes an object as argument with the following properties: { The property The property If Examples: // Toggle minimize state in chain "rule-guid1" // Set minimize state to false in chain "api" |
pzl.api.closeInteraction({...}) | This function will close the currently active interaction and finish the interaction chain, even if linked interactions exist in the current interaction. The function takes an object as argument with the following property: { The property Examples: // Close interaction chainID: "rule-guid1" |
pzl.api.evaluateRules() | This function triggers a re-evaluation of the configured engagement rules. A use case is if the customer’s webpage is a single-page-app that changes state without a page reload. Rules can be configured to trigger on content of the DOM, so if the DOM changes, this function can be used to notify the Puzzel application to re-evaluate rules. |
pzl.api.trackCustomEvent(trackingObject) | This function can be used to send custom tracking events to Puzzel’s statistics service. The function takes an object as property, and it will use it to populate the Example: pzl.api.trackCustomEvent({hello: 'xyz'}); Will generate and POST a tracking event like this: { |
pzl.api.setLoginDetected(<Boolean>) | This function sets the “login detected”-state, just as if a “Detect login” or a “Detect logout”-interaction was triggered by a rule. This state can control how a “visitor identification”-interaction will behave, and this function can be used by an external script to create more complex/custom logic. E.g. when detecting login state is hard to do reliably with engagement rule conditions. The function takes a boolean as parameter (default Examples: // Both these calls will set state to “loggedIn” // This call will clear the “loggedIn”-state |
pzl.api.setClaims({...}) | This function can be called to set visitor claims. The claims will be passed on to the next interaction when transitioning. This function takes an object of keys and string values. If any claims has have already been set, this will overwrite them. Example: // If this is called before starting a chat... Will set the claims “email” and “someCustomId” in the conversation and be visible to the agent. Note: The claims are not stored persistently until next interaction loads. So it may be necessary to call this function on every page load to ensure the claims will be set. |
pzl.api.addClaims({...}) | This function is the same add Example: // After running these two calls: Will make these visitor claims passed to next interaction: { |
pzl.api.registerHooks(<obj>) | This function can be used to register an object containing hook functions (default is the browser’s global All available hooks are listed in the next section “Hooks” Examples: pzl.api.registerHooks({ |
| This function registers a specific hook-function in the current hooks container (default is the global Examples:
// Deregister hook |
The chat module adds these API-functions:
pzl.api.setChatLanguage(langCode) | Switch language of a loaded chat. Use case primarily for testing. Example: pzl.api.setChatLanguage('en') |
Hooks
To let external scripts be notified of specific events in the Puzzel application, a set of hook-functions can be implemented. The application will look for these functions and call them (if they exist) with data relevant to the specific hook. In many hook-functions, the data can be transformed and returned to the Puzzel application, thus acting like a middleware to add or modify the data and alter the flow of the application. A hook may also return a Promise that will be awaited to support asynchronous logic (e.g. a hook could fetch data from a REST-API and inject it as visitor claims into the data before the Puzzel application transitions to the next interaction)
A special hook is called when the Puzzel application is loaded and ready to use:
window.pzlOnStart({...})
The hook will be called with an object as argument:
{
status: "started",
configInfo: {
"siteMappingName": "default site",
"configId": "1234-abcd",
"configVersion": "15",
"configName": "Test configuration"
}
}
or
{
status: "error",
error: <error-obj>
}
Example:
Implement this function before the puzzel script tag is injected/loaded:
window.pzlOnStart(function (obj) {
if (obj.status === 'started') {
// Now it's possible to use the puzzel api.
pzl.api.showInteraction({...});
}
});
If the order of execution for different scripts on the page is not predictable, something like this could be used to detect when the Puzzel application is ready:
function puzzelIsReady(obj) => {
if (obj.status === 'started') {
// Now it's possible to use the puzzel api.
pzl.api.showInteraction({...});
}
}
if (window.pzl && window.pzl.info && window.pzl.info.status === 'started') {
// Puzzel app is already started
puzzelIsReady({ status: 'started' });
} else {
// Puzzel app not yet started
window.pzlOnStart = puzzelIsReady;
}
The above code should work when executed both before and after the Puzzel app is started.
The pzlOnStart()
-hook needs to be implemented in the global window
-object (because it must exist already when the Puzzel application starts).
Other hooks can also be implemented under window
(which is the default context), and they are all prefixed with “pzl” to avoid naming conflicts. But they can also be implemented in an isolated object registered by using the API-function pzl.api.registerHooks({...})
described in the previous section of this document.
These are the hook-functions called by the Puzzel applications at various points of execution:
window.pzlOnStart({ | This hook is described above, and it’s normally the best hook to implement to know when the application is started and ready. If the |
window.pzlOnLoad({ bootstrap }) | This hook is called when the Puzzel application has loaded, but not yet started. Like But if the application has been configured to defer automatic bootstrap (see next section “Manual/deferred bootstrapping”), this hook is called when the application is loaded and ready to be started. In that case, the property The {
Examples: window.pzlOnLoad = ({ bootstrap }) => { The The try { |
pzlOnRuleMatch({ ruleItem }) | This hook is called every time a rule (defined in the web engage configuration) has matched. In the argument-object, the property Note: This object is the internal data-object representing a rule, so there may be properties added or changed in this object in the future. Basic properties like Example of a { After the rule has matched, its By implementing this hook, it is possible to alter the rule-item data before its Example:
The above hook would change the language of the interaction chain started by Note: Transforming data in hooks should only be done for advanced setups and must be done with care! It is easy to break the interaction chain by fiddling with this data! |
pzlOnBeforeEvaluateRules({ ruleItems }) | This hook is called before the rules defined in the web engage admin portal are evaluated. The hook can transform the array and return a new Note: Mutating the items in the array may cause unexpected behavior. If items should be modified, cloning them is preferred. |
pzlOnAfterEvaluateRules({ ruleItems }) | This hook is called after all rules have been evaluated and any triggered interactions are started. This hook is for information only, and any return value is ignored. |
pzlOnBeforeInteractionTransition({ | This hook is called before an interaction-chain transitions to the next interaction (or when the first interaction is triggered from a rule). The argument is an object containing the The This is an example of an
The hook can return a transformed |
pzlOnAfterInteractionTransition(({ | This hook is called after an interaction transition is finished and the next interactions has started. This hook is for information only, and any return value is ignored. |
pzlOnBeforeChainFinished({ | This hook is called when an interaction chain is about to be finished. The argument is an object that contains the The hook can control/override the behavior by returning either a string value or an object. If it returns the string If it returns the string If it returns an object, the finish-operation will be aborted, and the chain will instead transition to a next interaction. The object will be interpreted as an If there’s also a property |
Manual/deferred bootstrapping
The default behavior of the Puzzel application is to automatically start and evaluate the engagement rules as soon as the Puzzel script-tag is loaded.
For advanced setups, it is possible to defer starting the application and bootstrap it manually. This makes it possible to decide exactly when the application should start, and also inject custom visitor claims and hook-functions from start.
To enable deferred bootstrapping, the attribute data-defer-bootstrap
can be added to the script tag.
Example:
<script type="text/javascript"> (function (a, b) { var loader = a.createElement('script'); loader.type = 'text/javascript'; loader.src = 'https://app-cdn.puzzel.com/public/js/pzl_loader.js'; loader.setAttribute('id', 'pzlModuleLoader'); loader.setAttribute('data-customer-id', b); loader.setAttribute('data-defer-bootstrap', true); a.body.append(loader); })(document, '12345'); </script> |
When the Puzzel script is loaded like this, it will load and immediately just call the hook:window.pzlOnLoad({ bootstrap })
The argument to this hook is an object containing the function bootstrap({ ... })
that can be called to launch the application. See description of pzlOnLoad()
in the “Hooks”-section above for details about which bootstrap-options are currently supported.