Conversation Extensions

Conversation Extensions are a mechanism to send custom experiences for users to interact with as part of an on-going conversation. They are intended for workflows that would be inefficient if done by exchanging messages back and forth. Below are some examples of Conversation Extensions you could send to end users.

Multi step flow (Hotel room booking)

Webview Survey

Multi select (Insurance policy selection)

Webview Survey

Survey (NPS score)

Webview Survey

Example code

Conversation Extensions are powered by Web technologies and are implemented using Javascript, CSS and HTML. They are sent to end users by including a Webview action when sending a message.

To help you get started, we’ve created an example application for you to see how you can implement a Conversation Extension end to end. It implements an in-conversation date picker using Node.js + express in the backend and React in the frontend.

Webview date picker

The smooch-core API library is used to send the extension to the client and to echo the selected date in the conversation.

The Webview SDK is used to programmatically set the title of the extension header and to close it once the user completes their action.

Implementation

  1. To start, create your node server and listen for webhook calls:

    // server/app.js
    const path = require('path');
    const express = require('express');
    const bodyParser = require('body-parser');
    const SmoochCore = require('smooch-core');
    
    const app = express();
    
    app.use('*', bodyParser.json());
    
    app.post('/appuser-message', (req, res) => {
        console.log('received appuser message');
    });
    
    module.exports = app;
    
  2. In your frontend code, initialize the Web Messenger with the appId of your choice:

    // src/components/App.js
    Smooch.init({
      appId: '<your_app_id>'
    })
    
  3. Setup your webhook in the Smooch dashboard (or via API call):

    Create a webhook

  4. Include the Webview SDK script in your page:

    <!-- public/index.html -->
    <script>
        (function(d, s, id) {
            var js,
                fjs = d.getElementsByTagName(s)[0];
            if (d.getElementById(id)) {
                return;
            }
            js = d.createElement(s);
            js.id = id;
            js.src = 'https://cdn.smooch.io/webview-sdk.min.js';
            fjs.parentNode.insertBefore(js, fjs);
        }(document, 'script', 'WebviewSdkScript'));
    </script>
    
  5. Respond to messages with a webview action, adding appUserId to the query:

    // server/app.js
    const smooch = new SmoochCore({
        jwt: 'your_jwt'
    });
    
    app.post('/appuser-message', (req, res) => {
        smooch.appUsers.sendMessage(appUserId, {
            role: 'appMaker',
            type: 'text',
            text: 'Please select your flight date.',
            actions: [{
                type: 'webview',
                text: 'Select Date',
                size: 'tall',
                uri: `http://localhost:3000/webview?appUserId=${appUserId}`,
                fallback: 'https://no-thanks.html'
            }]
        })
    });
    
  6. In your extension, have your user complete their required action and then notify the server:

    // src/components/DatePicker.js
    fetch('/date-selected', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        date: this.state.date.toString(),
        appUserId: qs.parse(window.location.search.replace('?', '')).appUserId
      })
    }).then(() => {
      window.WebviewSdk.close(
        () => console.log("success!"),
        e => console.log("failure", e)
      );
    });
    
  7. Listen for the call from the extension and react to it in the server:

    // server/app.js
    app.post('/date-selected', (req, res) => {
        smooch.appUsers.sendMessage(req.body.appUserId, {
            role: 'appMaker',
            type: 'text',
            text: `You have selected ${req.body.date}. Enjoy your flight!`
        }).then(() => {
            console.log('success!');
            res.end();
        });
    });
    

Webview SDK

The Webview SDK library extends the functionality of Conversation Extensions to allow you to perform additional actions like setting the Extension header title and closing it programmatically.

To use the Webview SDK, add the following script tag to your html page:

<script>
    (function(d, s, id) {
        var js,
            fjs = d.getElementsByTagName(s)[0];
        if (d.getElementById(id)) {
            return;
        }
        js = d.createElement(s);
        js.id = id;
        js.src = 'https://cdn.smooch.io/webview-sdk.min.js';
        fjs.parentNode.insertBefore(js, fjs);
    }(document, 'script', 'WebviewSdkScript'));
</script>

To know when the library is fully loaded, you can define a webviewSdkInit like this in your <body>

<script>
    window.webviewSdkInit = function(WebviewSdk) {
        // the SDK is passed in parameter to this callback
        // and is also available at `window.WebviewSdk` for convenience
    }
</script>

Once loaded, the library is available in the global scope as WebviewSdk.

API

hasFeature(name)

hasFeature lets you check if a feature is implemented/available or not for the platform the sdk is currently running in. For instance, you could do WebviewSdk.hasFeature('close') before calling WebviewSdk.close() in order to adjust your webview behavior in case the feature is not supported. This method is important as not all platforms will support features as we add them.

close()

close tells the platform to close the current webview.

setTitle(title)

setTitle tells the platform to update the container header title. You should not have to call this on your own as your document title will be used automatically as the webview title. It will also be updated automatically on some platforms. You can call this function if you want to do something special with the title of the webview.