@stackchat/proactive-messaging
    TypeScript icon, indicating that this package has built-in type declarations

    1.0.8 • Public • Published

    @stackchat/proactive-messaging

    A utility library for @stackchat/web-messenger to display proactive messages to a user above the Stackchat Web Messenger button or tab.

    Table of Contents

    Introduction

    This library allows you to handle the creation, display and manipulation of messages that are proactively displayed to the user. A user can also interact with these messages eliminating the need of guesswork from the user.

    Proactive messages can be triggered automatically during an ongoing conversation in the Stackchat Web Messenger or can be manually triggered as the need arises.

    Each proactive message looks like this(when default styles are used)

    Proactive Message

    or like this with actions:

    Proactive Message With Actions

    Note: Proactive messages are only displayed if and only if the messenger widget is not open. If it is open, then all the proactive messages are silently ignored.

    Usage

    Note: This library works in conjuction with and requires @stackchat/web-messenger so as to be able to display proactive messages.

    Script

    If your project does not use a bundler or package manager, you can use our cdn hosted assets:

    <!--
    Copy and paste the following script right below
    the 'script' tag for Stackchat Web Messenger
    -->
    <script async type="text/javascript" src="https://assets.au.stackchat.com/sdk/proactive-messaging/1.0.4/index.js"></script>

    Optionally, if you would to include our default styles, also add the following:

    <link type="text/css" src="https://assets.au.stackchat.com/sdk/proactive-messaging/1.0.4/main.css">

    Now you have access to Stackchat Web Messenger(exposed as window.stackchat) and ProactiveMessaging(exposed as window.ProactiveMessaging)

    <script>
    	let messageStack;
    
    	// add an event listener to initialise Proactive
    	// Messaging once Stackchat Web Messenger has
    	// finished initialising
    	window.stackchat.on('ready', initialiseProactiveMessaging)
    
    	window.stackchat.init({
    		appId: "YOUR_APP_ID_HERE"
    	})
    
    	function initialiseProactiveMessaging() {
    		// This step is required before calling
    		// messageStack.start()
    		messageStack = new window.ProactiveMessaging({
    			messenger: window.stackchat,
    			ttl: 4000 // default
    			author: "Test Bot"
    		})
    
    		// start 
    		messageStack.start();
    	}
    </script>

    Package Manager

    Install the dependencies via npm or yarn:

    # NPM
    npm install --save @stackchat/web-messenger@latest @stackchat/proactive-messaging@latest
    
    # Yarn
    yarn add @stackchat/web-messenger@latest @stackchat/proactive-messaging@latest

    To include our default styles, also include the following:

    import "@stackchat/proactive-messaging/dist/main.css"

    Now in your JavaScript code:

    import Stackchat from "@stackchat/web-messenger";
    import { ProactiveMessaging } from "@stackchat/proactive-messaging";
    
    let messageStack
    
    // Add an event listener to know when Web Messenger 
    // is ready to go
    Stackchat.on('ready', initialiseProactiveMessaging)
    
    //
    const initialiseProactiveMessaging() => {
    	// This step is required before calling
    	// messageStack.start()
    	messageStack = new ProactiveMessaging({
    		messenger: Stackchat,
    		ttl: 4000 // default
    		author: "Test Bot"
    	})
    
    	// start 
    	messageStack.start();
    }
    
    // Initialise Web Messenger
    Stackchat.init({
    	appId: "YOUR_APP_ID_HERE"
    })

    API

    This library exposes a single class - ProactiveMessaging - which is used to handle proactives messages and to manipulate them.

    const messageStack = new ProactiveMessaging(options) //see below

    Initialisation Options

    • options

      Property Optional Default Value Description
      messenger No - An initialised instance of the StackChat Web Messenger. This is required to be able to display the proactive messages above the message bubble/tab
      ttl Yes 2000 The amount of time each message should live on the screen in milliseconds. By default, its 2s i.e. 2000ms
      author No - The name displayed at the top of each message. This is what will be used as author name for each proactive message
      maxMessages No - The maximum number of messages that are displayed on the screen at any given time. By default, it is 3
      singularCloseButton No - Determines whether to show one close button for all messages or one for each message

    Methods

    • start()

      Triggers the ProactiveMessaging instance to start listening for incoming messages in a conversation. As long as the messenger widget is not open, ProactiveMessaging will ensure that any message which contains the following in its metadata property will be displayed proactively.

       {
       	proactive: true
       }
      
       // Therefore the message object should look like this
       message = {
       	metadata: {
       		proactive: true,
       		...otherMetaProps
       	},
       	...otherMessageProps
       }
    • addMessage(text, actions?)

      Allows the developer to simulate or display a proactive message to the user without it becoming a part of the ongoing conversation.

      For e.g.

       // Without actions
       messageStack.addMessage("Hello, world!")
       
       // With actions
       messageStack.addMessage(
       	"Hello, world!",
       	[
       		{
       			text: "Hello there!",
       			openMessengerOnReply: false
       		},
       		{
       			text: "Hi! What are you up to?",
       			openMessengerOnReply: true
       		}
       	]
       )
    • stop()

      Triggers the ProactiveMessaging instance to stop listening to incoming messages and removes all associated DOM elements from the page.

    Event Binding

    ProactiveMessaging offers two special methods to allow developers to react to events as they occur.

    Note: You can add and remove event binding at any time.

    • on(event, handler)

      Allows you to specify a callback for a event which is called when that aforesaid event occurs.

    • off(event?, handler?)

      Allows you to remove a callback tied to an event. If no handler is specfied, it removes all the callbacks associated with the event. If no event has been specified, all callbacks for all events are cleared.

    Events

    This is the list of events that you can use with on and off methods as described above.

    • ready

      This event is fired when your ProactiveMessaging instance is ready. From this point on, it can start displaying proactive messages.

      messageStack.on("ready", () => {
        console.log("Proactive Messaging is ready!");
      });
    • proactive-message:clicked

      This event is fired when a user clicks on a proactive message. This event is not fired when a user dismisses a message or clicks on a quick reply.

      messageStack.on("proactive-message:clicked", (event) => {
        console.log("Proactive Message clicked > message", event.message);
      });
    • proactive-message:dismissed

      This event is fired when a user dismisses a proactive message. It is not fired if the message auto dismisses after the ttl.

      messageStack.on("proactive-message:dismissed", (event) => {
        console.log("Proactive Message dismissed > message", event.message);
      });
    • quick-reply:clicked

      This event is fired when a user clicks on one of the quick replies in a proactive message.

      messageStack.on("quick-reply:clicked", (event) => {
        console.log("Quick reply clicked");
        console.log("Message", event.message);
        console.log("Quick reply", event.quickReply);
      });
    • messenger:opened

      This event is fired whenever the Stackchat Web Messenger is opened by your ProactiveMessaging instance. Stackchat Web Messenger is opened when a user clicks on a message or clicks on one of the quick replies. Refer to the first part of the API section above.

      messageStack.on("messenger:opened", () => {
        console.log("Stackchat Web Messenger opened");
      });
    • clear

      This event is fired when all the proactive messages have been cleared - by user interaction or otherwise. Consider this as a blank slate similar to right after the ready event has occured.

      messageStack.on("clear", () => {
        console.log("All proactive messages cleared!");
      });

    Styling

    Default Styles

    This library includes some base styles that display proactive messages in the nice UI as shown above here and here.

    Consuming default styles depends on the way you integrate this library:

    • Script

      You can use our CDN hosted stylesheet via a script tag

       <link type="text/css" src="https://assets.au.stackchat.com/sdk/proactive-messaging/1.0.4/main.css">
    • Package Manager

      When using a package manager like npm or yarn, the default styles are automatically imported when you import ProactiveMessaging.

      In this case, you need only provide additional styles to suit your organisation's branding requirements. Please look at the custom styles section below.

    Custom Styles

    The module mostly uses classes to apply styles to the individual components and they are named logically so to enable easy overrides.

    Important

    Some base styles are required to display proactive messages properly. These styles are added to the elements inline and therefore, can not be overridden.


    Animations

    If you plan on overriding the default animation behaviour, please ensure you provide styles for two selectors i.e. @keyframes and @webkit-keyframes to account for compatibility with different browsers.


    The default stylesheet is provided below for your reference. Use it as a reference point for classes you would like to add custom styles to.

    /** The base container for all proactive messages **/
    .proactive-container {
      overflow-y: hidden;
      display: flex;
      align-items: flex-end;
      justify-content: flex-end;
      flex-direction: column;
      z-index: 9998;
    }
    
    .proactive-container * {
    	outline: none;
    }
    
    /** Singular close button to dismiss all messages **/
    .proactive-container .external-close-button {
      width: 32px;
      height: 32px;
      border-radius: 50%;
      display: flex;
      align-items: center;
      justify-content: center;
      border: none;
      background-color: #d8d8d8;
      cursor: pointer;
    }
    
    /** The container for individual proactive message **/
    .proactive-container .proactive-message {
    	margin-bottom: 8px;
    	padding: 4px;
    }
    
    /** The message inside each proactive message **/
    .proactive-container .proactive-message .message {
      background-color: white;
      border-radius: 8px;
      overflow: hidden;
      display: flex;
      flex-direction: column;
      align-items: flex-start;
      justify-content: flex-start;
      box-shadow: 0 0 4px 1px rgba(0, 0, 0, 0.2);
      width: 232px;
    }
    
    .proactive-container .proactive-message .message .header {
    	position: relative;
    	width: 100%;
    	height: 40px;
    	display: flex;
    	align-items: center;
    	justify-content: flex-start;
    }
    
    /** The author of the proactive message **/
    .proactive-container .proactive-message .message .header .name {
    	margin: 0;
    	margin-left: 16px;
    	margin-right: 8px;
    	font-weight: 600;
    	font-size: 14px;
    	color: #8c1aff;
    }
    
    /** The close button inside each proactive message **/
    .proactive-container .proactive-message .message .header .close-button {
    	position: absolute;
    	right: 0;
    	top: 0;
    	width: 40px;
    	height: 100%;
    	display: flex;
    	align-items: center;
    	justify-content: center;
    	background-color: transparent;
    	border: none;
    	cursor: pointer;
    }
    
    /** The content of the proactive message **/
    .proactive-container .proactive-message .message .content {
    	padding: 8px 16px 16px 16px;
    }
    
    .proactive-container .proactive-message .message .content .text {
    	margin: 0;
    	font-size: 14px;
    }
    
    /** The container for quick actions(if any) for each individual message **/
    .proactive-container .proactive-message .actions {
    	margin-top: 4px;
    	display: flex;
    	flex-wrap: wrap;
    	align-items: center;
    	justify-content: flex-end;
    }
    
    /** Each indidivual action of a proactive message **/
    .proactive-container .proactive-message .actions .action {
    	background: linear-gradient(
    			0,
    			rgba(140, 26, 255, 0.45) 60%,
    			rgba(140, 26, 255, 0.45) 60%
    		), linear-gradient(0, #fff 100%, #fff 0);
    	box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.25);
    	border: 1px solid #8c1aff;
    	border-radius: 4px;
    	margin-left: 4px;
    	font-size: 14px;
    	padding: 11px;
    	min-width: 64px;
    	font-weight: 600;
    	cursor: pointer;
    	line-height: 16px;
    	color: #000;
    }
    
    /**
     * Classes to handle animating in and out
     * of individual proactive messages
     */
    .show-message,
    .hide-message {
    	-webkit-animation-name: animGenie;
    	animation-name: animGenie;
    	-webkit-animation-duration: 0.4s;
    	animation-duration: 0.4s;
    }
    
    .hide-message {
    	animation-direction: reverse;
    	-webkit-animation-name: animGenieReverse;
    	animation-name: animGenieReverse;
    }
    
    /**
     * The animation for messaging coming in
     * and being displayed on screen
     */
    @-webkit-keyframes animGenie {
    	0% {
    		opacity: 0;
    		-webkit-transform: translate3d(45%, calc(144%), 0) scale3d(0, 1, 1);
    		transform: translate3d(45%, calc(144%), 0) scale3d(0, 1, 1);
    		-webkit-animation-timing-function: ease-in;
    		animation-timing-function: ease-in;
    	}
    	40% {
    		opacity: 0.5;
    		-webkit-transform: translate3d(27%, 0, 0) scale3d(0.02, 1.1, 1);
    		transform: translate3d(27%, 0, 0) scale3d(0.02, 1.1, 1);
    		-webkit-animation-timing-function: ease-out;
    		animation-timing-function: ease-out;
    	}
    	70% {
    		opacity: 0.6;
    		-webkit-transform: translate3d(9%, -40px, 0) scale3d(0.8, 1.1, 1);
    		transform: translate3d(9%, -40px, 0) scale3d(0.8, 1.1, 1);
    	}
    	100% {
    		opacity: 1;
    		-webkit-transform: translate3d(0, 0, 0) scale3d(1, 1, 1);
    		transform: translate3d(0, 0, 0) scale3d(1, 1, 1);
    	}
    }
    
    @keyframes animGenie {
    	0% {
    		opacity: 0;
    		-webkit-transform: translate3d(45%, calc(144%), 0) scale3d(0, 1, 1);
    		transform: translate3d(45%, calc(144%), 0) scale3d(0, 1, 1);
    		-webkit-animation-timing-function: ease-in;
    		animation-timing-function: ease-in;
    	}
    	40% {
    		opacity: 0.5;
    		-webkit-transform: translate3d(27%, 0, 0) scale3d(0.02, 1.1, 1);
    		transform: translate3d(27%, 0, 0) scale3d(0.02, 1.1, 1);
    		-webkit-animation-timing-function: ease-out;
    		animation-timing-function: ease-out;
    	}
    	70% {
    		opacity: 0.6;
    		-webkit-transform: translate3d(9%, -40px, 0) scale3d(0.8, 1.1, 1);
    		transform: translate3d(9%, -40px, 0) scale3d(0.8, 1.1, 1);
    	}
    	100% {
    		opacity: 1;
    		-webkit-transform: translate3d(0, 0, 0) scale3d(1, 1, 1);
    		transform: translate3d(0, 0, 0) scale3d(1, 1, 1);
    	}
    }
    
    /**
     * The animation for messaging going out
     * and being removed off screen
     */
    @-webkit-keyframes animGenieReverse {
    	0% {
    		opacity: 0;
    		-webkit-transform: translate3d(45%, calc(144%), 0) scale3d(0, 1, 1);
    		transform: translate3d(45%, calc(144%), 0) scale3d(0, 1, 1);
    		-webkit-animation-timing-function: ease-in;
    		animation-timing-function: ease-in;
    	}
    	40% {
    		opacity: 0.5;
    		-webkit-transform: translate3d(27%, 0, 0) scale3d(0.02, 1.1, 1);
    		transform: translate3d(27%, 0, 0) scale3d(0.02, 1.1, 1);
    		-webkit-animation-timing-function: ease-out;
    		animation-timing-function: ease-out;
    	}
    	70% {
    		opacity: 0.6;
    		-webkit-transform: translate3d(9%, -40px, 0) scale3d(0.8, 1.1, 1);
    		transform: translate3d(9%, -40px, 0) scale3d(0.8, 1.1, 1);
    	}
    	100% {
    		opacity: 1;
    		-webkit-transform: translate3d(0, 0, 0) scale3d(1, 1, 1);
    		transform: translate3d(0, 0, 0) scale3d(1, 1, 1);
    	}
    }
    
    @keyframes animGenieReverse {
    	0% {
    		opacity: 0;
    		-webkit-transform: translate3d(45%, calc(144%), 0) scale3d(0, 1, 1);
    		transform: translate3d(45%, calc(144%), 0) scale3d(0, 1, 1);
    		-webkit-animation-timing-function: ease-in;
    		animation-timing-function: ease-in;
    	}
    	40% {
    		opacity: 0.5;
    		-webkit-transform: translate3d(27%, 0, 0) scale3d(0.02, 1.1, 1);
    		transform: translate3d(27%, 0, 0) scale3d(0.02, 1.1, 1);
    		-webkit-animation-timing-function: ease-out;
    		animation-timing-function: ease-out;
    	}
    	70% {
    		opacity: 0.6;
    		-webkit-transform: translate3d(9%, -40px, 0) scale3d(0.8, 1.1, 1);
    		transform: translate3d(9%, -40px, 0) scale3d(0.8, 1.1, 1);
    	}
    	100% {
    		opacity: 1;
    		-webkit-transform: translate3d(0, 0, 0) scale3d(1, 1, 1);
    		transform: translate3d(0, 0, 0) scale3d(1, 1, 1);
    	}
    }

    Keywords

    none

    Install

    npm i @stackchat/proactive-messaging

    DownloadsWeekly Downloads

    24

    Version

    1.0.8

    License

    SEE LICENSE IN LICENSE

    Unpacked Size

    94 kB

    Total Files

    13

    Last publish

    Collaborators

    • mszu
    • marrobin