2.0.11 • Published 1 year ago

page-support-bot v2.0.11

Weekly downloads
-
License
MIT
Repository
github
Last release
1 year ago

Why page.support?

Page.support is a solution for automating customer support. Page.support lets you quickly create chatbots and workflow-enabled websites without writing code. It does this by emulating the primitives that underly human conversation, reducing the amount of work required to design conversations. Rapid iteration based on customer feedback is essential to the adoption of automation, making a no-code solution important - particularly if the support team does not have dedicated software developers. The Page.support publisher lets you define the user interaction by writing markdown with some additional annotations to define the workflow. See the documentation for more.

The Bot client software in this repository and the interface between the client and publisher is MIT licensed open source, providing use case flexibility and reducing dependence on a single vendor. The open source botConfig interface between publisher and client lets an ecosystem of SaaS providers, developers and users interoperate.

Since the page.support bot runs in the user's browser, you can create experiences with a high degree of responsiveness, availability, privacy and security that don't depend on a third party chatbot server. If needed, user data can be read/written to servers you select to save user replies or personalize the experience. However the Bot's basic functionality - dialog, questions, and taking user replies - doesn't need a server to run. This lets you design experiences that protect user privacy and meet regulatory requirements by minimizing data that goes back to servers, particularly third party servers.

Page.Support Bot

This repository contains the open source Bot client component to embed in your website. The Bot client is a javascript component that drives the end user experience. It runs in the user's browser without any server side connection required after the initial page load. Its behavior is customized by a botConfig.js file that is generated by a publisher like the one at publisher.page.support. The configuration file enables the behaviors described in the documentation The src/interface directory in this repository contains the botConfig JSON template that defines the interface between Page.Support publishers and all Bot clients such as this one. This bot client includes basic color and font customization. If you need more customization, fork this repository and customize the Bot client to add functionality or change its look and feel. If your enhancements are generally useful we appreciate your contributions via pull requests. As long as your Bot clients maintain compatibility with the botConfig definition, your customized/forked client can be used with any Page.Support compliant publisher.

If your bot requires reading or writing data from a server, e.g. for authentication, personalization, or saving user replies, see the Server Integration section below.

Adding Bot to your website

There are several ways to integrate Bot into your website. In all cases, Bot needs the following files to function:

  • The Bot javascript component in this repository. You can fork this repo or install the component with npm install page-support-bot or follow the directions below to add it as an iife file.
  • A configuration file (referred to as "botConfig") that defines the bot's behavior. This file is a javascript module that exports a javascript object. The file is produced by a publisher like the one at publisher.page.support. Click the download button to get this file.
  • A page-support-bot.css file. This needs to be added to your website's public folder.
  • If your botConfig includes references to images, you'll need to host them on an server at whatever URLs you used in your markdown.

Bot and website settings:

  • You probably will want to control the height of the Bot. The botHeight property defaults to 30rem. You can either set the setHeight property when attaching Bot to the DOM, or set it with CSS on the Bot's parent div in your site. For example, max-height: 40rem; display: flex; flex-direction: column in the CSS of the Bot's parent container on your website. Bot sets up its own scrolling container. See the description of all the parameters you can set below at Bot instantiation time. The ideal height of Bot depends on the content you are putting into it. Large images and lots of text will require a greater height for usability and less scrolling. If your website layout allows, use as much of the page as you can if you have tall content for better usability. Think of Bot as documentation not as a chatbot.
  • To control Bot's width, set the width of the Bot's parent element in your website, for example max-width: 42rem;. Bot itself does not set a maximum width so will be as wide as the parent element.

Add Bot as an iife file to your HTML

If you don't have a javascript build pipeline or don't have access to a software developer, you can add Bot as an iife file. This scenario requires you to host the three files above and any images you need on your web server or a storage bucket you control. It also requires the ability to add the script below to the header of the web page where you'd like the bot to appear. Edit the paths in the script based on where you uploaded the files so your web server can find them.

Add the index.min.js, page-support-bot.css, and page.support.botconfig.js files to the page where you want to your users to see the bot.

<script src="/index.min.js" ></script>

<script type="module"> 

// Import your Bot client definition.
// 1. download the botconfig file from publisher.page.support 
// 2. save it to your application's repository if you want it under
// version control, or load from static file server if not
import botConfig from "/path/to/page.support.botconfig.js"

// Set to the id of the DOM element you want the bot attached to
const botDOMId = 'netDiaBot';  

document.addEventListener("DOMContentLoaded", function() {

    // The DOM element the Bot will be attached to
    el = document.getElementById(botDOMId);
    if (el) {
      // PageSupportBot is the name of the var exported by page.support.min.js 
      // Bot is the constructor it exports.   
      const bot = new PageSupportBot.Bot({
        target: el,
        props: {
          botConfig: botConfig,
          localStorageKey: 'botNumberOne',
          botHeight='20rem'
        }
      });
    } else {
      console.log(`page.support bot setup script failed to find "${botDOMId}" in DOM`);
    } 
})

</script>

<div id="bot"></div>

See the props section below for configuraiton options you may want to pass into the props object.

Add Bot to your javascript build pipeline

If your already have a build pipeline for your js code, you can add Bot as a dependency via npm, import it into your javascript application, then build and deploy it with the rest of your site. You will also need to add static assets your Bot uses to an asset server you maintain.

npm install page-support-bot

Now add it to your package.json under "dependencies"

"page-support-bot": "x.x.x"

Import into your javascript application

// The Bot client code, installed from npm
import Bot from "page-support-bot"; 

// Your Bot's configuration file that defines its behavior. Download it from  
// publisher.page.support and save to your application's repository if you want 
// it under version control (encouraged), or load from static file server if not. 
import botConfig from "/your-path/to/page.support.botconfig.js"

Next add the Bot component to your page's HTML

<Bot botConfig={botConfig} 
     bind:this={botBinding} 
     localStorageKey={localStorageKey}
     cssFileURI="path/to/the/page-support-bot.css" 
/> 

Or, add attach it to the DOM with javascript:

import botConfig from "./page.support.botconfig.js";

// IIFE creates bot and attaches it to the DOM
(function () {

// Set to the id of the DOM element you want the bot attached to
const botDOMId = 'netDiaBot';  

document.addEventListener("DOMContentLoaded", function() {

    // The DOM element the Bot will be attached to
    el = document.getElementById(botDOMId);
    if (el) {
      // PageSupportBot is the name of the var exported by page.support.min.js 
      // Bot is the constructor it exports.   
      const bot = new PageSupportBot.Bot({
        target: el,
        props: {
          botConfig: botConfig,
          localStorageKey: 'botNumberOne',
          cssFileURI: 'page-support-bot.css'
        }
      });
    } else {
      console.log(`page.support bot setup script failed to find "${botDOMId}" in DOM`);
    } 
})

  
})();  // iife closure

Bot supports the following props:

REQUIRED

  • localStorageKey is the unique key Bot will use to preserve each user's conversation state in the browser. This should be a String unique to each bot in your domain. You can have multiple Bots per domain as long as they have unique keys. This prop is required.

OPTIONAL (required in some circumstances)

  • cssFileURI: URI where the bot's css file is located. The value is used to set the href property of a link that loads the stylesheet. This allows the parent site flexibility about where to put the css file. If not provided, the bot uses the CSS_FILE constant which equals './page-support-bot.css'. The defaults works if the css file is placed at the top level of your web server's /public directory. Otherwise you'll want to set this property relative to the /public folder.
  • botConfig is the js object you imported earlier in your app. Its optional if you are using startNewConversation(botConfig) to initiate Bot. Otherwise required.
  • bind:this={botBinding} is an optional reference to this bot that lets you call functions in the Bot, such as starting a new conversation. If you are not calling startNewConversation() or some other function exported by Bot its not needed.
  • getConfigFromRemote is a optional boolean that is not currently supported - in the future this will let you specify a remote URL from which load the bot definition.
  • waitForStartNewConversation is an optional boolean which if true will cause bot to display nothing until the startNewConversation() function is called. Use when you want your site to control when the bot activates and displays on a page. Defaults to false, which means the bot will display at page load with the first round of conversation displayed.
  • botHeight is an optional String as defined in <length> per https://developer.mozilla.org/en-US/docs/Web/CSS/length. It defaults to "30rem". Enables BotConversation UI to keep currentAsk in the view by controlling scrolling (if Bot exceeds viewpoint height) If Bot doesn't exceed viewport height, does nothing.
  • SSRMode is an optional boolean. If true, Bot will not render the optional introduction section even if present in botConfig. If false, does render it. This lets the parent site render it server side for better SEO. Defaults to false.

The bot component uses the Svelte javascript framework and tailwindcss framework. See the rollup.config.js, tailwind.config.js, babel.config.js and postcss.config.js files for build configuration requirements.

See the static assets section below for how to enable images and the Bot's css files.

Control bot start and botConfig from parent site

Parent sites might want to control when a bot starts a new conversation, for example with a "Run" button. This button would also restart an existing conversation if one was in progress. You might want to do this without reloading the component. You might also want to pass in a new botConfig when the user clicks "Run" in the parent site. This might be useful for Bot markdown authoring scenarios. For this use case, you'd use code something like this

// in your javascript
let botBinding;

// runBot() is run by an onClick event 
function runBot() {
  botBinding.startNewConversation(botConfig);
}

// in your html.


// By setting waitForStartNewConversation to true bot will display nothing
// until startNewConversation is called.
<Bot botConfig={null} 
     bind:this={botBinding}
     getConfigFromRemote={false}
     localStorageKey={localStoragePreviewBotKey} 
     waitForStartNewConversation={true} 
     botHeight='20rem'
/> 

Show / hide bot to save screen real estate

The Parent site can add the bot IIFE or js module to the DOM whenever they want. If the botConfig is being fetched from remote, you might want to load bot after the DOM is loaded, but in a hidden state so it will fetch botConfig and be ready to display. When you want to display the bot, e.g. if a user clicks a button to interact with the bot, unhide the HTML element the bot resides under.

Add static assets - images and css

Any static assets referred to in your bot's markdown, such as image tags, must be uploaded to the URLs you added to the markdown. At this time page.support doesn't maintain any static asset servers, so add static assets to your storage bucket or website public directory.

Add the page-support-bot.css file in this repository to the /public folder of your web server. If the file is not at the top level of your public folder, set the cssFileURI property to the path under your public folder. See the Bot property descriptions above for more. Adding a number or hash to the filename each time you update the file ensures your website and browsers won't use a cached old file, for example page-support-bot3456.css

CSS encapsulation and inheritance

When you add Bot to your website, its CSS is encapsulated so that your website's global styles do not affect it, and its styles won't affect your website. Encapsulation is achieved by using ShadowDOM All of the styles, and nearly all the Bot's UI is attached to the DOM under a shadow host. The shadow host is an empty div added by the Bot component, with the actual Bot html and css attached underneath it. The BotConversationUI.svelte component accomplishes this. That said, there are a few styles than can, and probably should, leak into Bot. See this for what inherits and how to stop it.

Conversation initialization

When your user first loads the page, the Bot will display and start a new conversation by default. Bot will maintain conversation state across page reloads in a tab by using sessionStorage. Closing the tab will end the conversation.

If you want to give your web application control over when the Bot displays, use your web framework's conditional loading/display - usually some type of if block.

If you want give your web application control over starting and restarting a conversation, use botBinding.startNewConversation(botConfig); to start a new conversation with the passed in configuration. It also lets you give the user control over when to engage with the bot instead of launching it by default.

Testing

Since web-client is a Svelte component rather than a fully functioning website, this repo serves multiple configurations of the component for testing. SvelteKit provides the environment to test the component across different user stories without having to first do an integration with your website. This component can be visually tested by running npm run dev and walking through each example in the index shown in the browser at http://localhost:5173. See /src/routes/+page.svelte for how each test is defined and to add more test scenarios.

For automated tests, this component uses Jest. To run automated tests of dialog.js and lower level functions, see tests under src/dialog/tests and follow the instructions in the test file. Tests are sparse now, feel free to submit more with pull requests.

Vitest and Playwright are included in package.json but no tests have been written with them.

Customizing and Building

If you make modifications to the Bot then want to deploy the changes to your website, run $ npm run dist which will 1. extract all the web-component files needed for an npm package into /package and 2. compile js and css files into the /dist directory for use cases that are not using node_modules.

  • index.mjs is an ES6 module file for importation into your build.
  • index.min.js is a IIFE file for websites that do not build js or if the integrator does not have access to the js build.

User engagement tracking and website analytics

A key part of measuring the success of any type of automation is measuring user engagement. You want to know if users are using the automation, and if they are achieving their goals when they use it. Page.support bots will integrate with any user engagement measurement platform that can receive events from the bot, such as Google Analytics. You don't need a new event tracking system, you can use the same one you are using on the bot's parent site (your main website). Bot will send events to it so you can see all your user measurements in one place.

To configure event tracking set the settings.trackUserReplies property in your markdown or botConfig to 'true'. When set to true, bot will call a global javascript function called pageSupportBotTracker() and pass in user events to that function. In markdown this looks like

<!--
settings.trackUserReplies: true
-->

Second, add pageSupportBotTracker() to your parent site's global javascript namespace. This allows you to use your existing event tracking service's function calls to send the data to your event tracking service. The contents of pageSupportBotTracker() will vary based on the user analytics service you are using. For example if you are using Google Analytics GA4 the syntax would be:

  // in your website's <head> tag on all pages where the bot appears
  <script>

    function pageSupportBotTracker(eventName, parameters) {
      gtag('event', eventName, parameters); 
    }

  </script>

The function is called with two arguments, eventName and parameters. eventName is a String uniquely identifying the event your bot will report. Your bot will supply the event name, for example reply_click is the name of the event reported when a user selects a reply in the bot. parameters is a javascript object supplied by the bot with data about the reply. It will include properties that identify the question the bot asked, the user reply, and the status of the conversation. For example:

{
  "ask": "### Router models\nWhat type of router do you have?\n![Router models](/assets/routerModels.png)",
  "userReplyValues": [
    "Brand Beta model Z44"
  ],
  "userReplyIndexes": [
    2
  ],
  "ending": "completed"
}

The bot will call pageSupportBotTracker() when it asks the user a question and when it receives a reply.

There are three eventNames reported:

  • When the bot asks a question, it will use the event name page_support_bot_ask_name_${round.slot.name}
  • When a user replies, it will use the event name page_support_bot_reply_click. It reports both what the bot said in the say property and the reply recieved from the user in the userReplyValues property.
  • At the end of the conversation, if the conversation ended without the user abandoning it midway, a conversation session history is sent with the event name page_support_bot_ended_conversation This allows you to examine specific user sessions that are otherwise not available when collating individual events like with the prior two event types.

Note that with all these events, user input is being sent server side in the userReplyValues property. Take care to ensure user PII is properly handled if there is any information uniquely identifying individuals. You can remove anything you don't want sent to your analytics service by adding a filter to the pageSupportBotTracker() function.

Depending on the user analytics service you are using, you may have to translate the eventName and parameter arguments into some other form before sending to your tracking service. With Google Analytics they are the second and third arguments to their gtag function. Note that with GA4 you also have to do some configuration in your Google Analytics account to report custom events.

The script above assumes you already have GA4's tracking setup in another script tag. Substitute the gtag(...) function for whatever function call your analytics system requires.

Depending on your requirements, you might want to setup a new tracking "site" for the bot, separate from the rest of your website. The steps would be the same as above, except when you call your tracking service you'd use a different tracking id.

Server integration and Data Persistence

By default Bot only relies on the botConfig to drive its behavior so doesn't need to talk to a server. However if you want to personalize Bot's behavior, for example by loading user data, we will be adding simple integrations with arbitrary URLs and APIs in the next release. Those integrations will also enable saving user replies to an API on your server.

If you want to do this now, you can customize the bot to load user data. Call out to your server right before the loadUI() function in Bot.svelte. To save individual user replies see the saveReply() function in dialog.js. To save an updated version of the entire conversation after every user reply see saveConversation() in state.js.

Versioning and Compatibility

The bot client and the botConfig file it uses must be on the same major version. The version of the bot client is the same as the version in package.json, and there's a check in state.js's versionCompatible() that will surface a user-visible error if bot reads a botConfig that's not compatible. botConfig files also have a version property that is used to determine compatibility. If you are adding the bot client to your website with your own build pipeline,ensure that the botConfigVersion constant in state.js is set to the same major version as the botConfig files you plan to use with the client. (and of course make whatever updates to the code you need to maintain compatibility) If you are adding bot client by copying in the index.min.js file the version will already be set by the rollup build process.

Browser support

This package supports most modern browsers including Chrome, Safari, Edge and Firefox. It does not support IE.

For package maintainers

Developing

Once you've created a project and installed dependencies with npm install (or pnpm install or yarn), start a development server:

npm run dev

# or start the server and open the app in a new browser tab
npm run dev -- --open

Building

Note: this section is generally not used by itself since web-client is distributed as a component. See the Publishing to npm section below for most component distribution scenarios.

To create a production version of your app:

npm run build

This will copy the files needed for production into the /package directory. Note these are not minified or built into one file like the files in the /dist directory. The package directly is strictly for scenarios where some other service which has its own build step is running a build using the package.json file and installing all the dependencies.

Testing

Visual manual testing

At the command line: npm run dev Then visit http://localhost:5173/ and walk though the menu of tests in the UI. This uses SvelteKit to load Bot and then run it with different props to exercise the UI.

Automated unit testing

publishing/updating web-client repo on github

  1. git commit -am ... to main
  2. update the dist and package directories with npm run dist. This will ensure that minified versions use the latest code
  3. git push

Publishing to npm

  1. Complete visual tests - see above testing section
  2. Run automated tests
  3. update CHANGELOG.md
  4. update documentation if needed
  5. update README
  6. npm run dist # first extracts all web-client files into /package, then writes iife, js, mjs versions that concatenate all the files needed to run the component and places them in /dist
  7. merge feature branch
  8. in main git commit ..
  9. git push
  10. npm publish # to npm registry
  11. update publisher and home app if needed

Build and other Errors

`rollup-plugin-svelte The following packages did not export their package.json file so we could not check the "svelte" field. If you had difficulties importing svelte components from a package, then please contact the author and ask them to export the package.json file.

  • ramda
Ignore this error, its irrelevant to components that don't export svelte modules. See
https://github.com/sveltejs/rollup-plugin-svelte/issues/181
2.0.11

1 year ago

2.0.9

1 year ago

2.0.8

1 year ago

2.0.5

2 years ago

2.0.4

2 years ago

2.0.7

2 years ago

2.0.6

2 years ago

2.0.3

2 years ago

2.0.2

2 years ago

2.0.1

2 years ago

2.0.0

2 years ago

1.0.3

2 years ago

1.0.2

2 years ago

1.0.1

2 years ago

1.0.0

2 years ago