Chatbots: to implement or not to implement?

12 min

Author: Branko Ajzele, Certified Magento Developer

The great majority of modern web shops still rely on mouse and keyboard, or analogous mobile device touch input to interact with the customer. This way of interaction, while certainly established and technically well supported, could appeal less to certain audiences or situations; be it for technical, medical or simply generational reasons.

Choosing the Right Birthday Gift

You look for the perfect gift for a 6 years old boy. But you are completely out of touch with any toy trends or anything alike.

You find a webshop that sells toys and try to type something into the search bar, helped by some Google-ing for trendy stuff. Is it working? How much time are you spending?

Admittedly, search engines nowadays are quite powerful, and would likely provide satisfactory results for many of the customers. But, wouldn’t it be nice if we can converse in a way as we converse with a human being, through natural conversation, e.g.

I am off to a birthday party, in 3 days. Looking for something cute for a 6 year old who adores dinosaurs, especially the flying ones. Unfortunately I am a little short on cash, like 20$ tops short, so I am not sure what to buy?”.

These human-like expressions, would then trigger human-to-computer conversation, based on which more personalized details would feed the underlying products database, that might yield completely different results, ultimately leading to increased conversion rate for your web shop.

From the start, this conversation reveals couple of crucial details:

  • party in 3 days, so that web shop could react by suggesting only products on stock and deliverable within 3 days
  • age of the gift reviver, so that web shop could react by suggesting only products suitable for that age group
  • gender or a gift receiver, so that web shop could react by fully filtering out, or at least sorting products in a gender like fashion
  • type of toy a gift receiver likes; dinosaur, flying one; which are two pieces of relevant information; web shop can use with relevance to filtering and  sorting
  • Maximum budget for a gift, relevant for filtering out products.

Chat / Voice Platforms

With ever increasing mobile user base, if we supplement text conversation with voice conversation, not only do we ease the user input, we essentially turn shopping into a friendly and personalized voice conversation experience.

So, technically speaking, how do we go from an average web shop to one powered by text and/or voice conversation? Because text and voice “breakdown and understanding” is not really something we can easily code in a few lines of code, from scratch.

This is where cloud services landscape kicks in; already providing decent choice of chat/voice bot platforms, some of which include:

  • Google Dialogflow - gives users new ways to interact with your product by building engaging voice and text-based conversational apps.
  • Facebook Wit.ai - Easily create text or voice based bots that humans can chat with on their preferred messaging platform.
  • Azure Cognitive Service for Language - enables developers to integrate AI into your applications that can extract information, classify text, understand conversational language, answer questions and more
  • Amazon Lex - service for building conversational interfaces into any application using voice and text
  • IBM Watson Conversation - Build chatbots that understand natural language and deploy them on messaging platforms and websites, on any device
  • etc.

Example Implementation

Moving forward, we will briefly touch on one such possible implementation, that might be built on some of the best technologies and platforms market has to offer at the moment:

  • Magento 2 / Adobe Commerce platform
  • Google Dialog Flow

Adobe Commerce offers powerful tools that let us reliably launch, manage, and scale your business, including the ability to host multiple instances on one platform, and cloud deployment, while native integrations with Adobe products like Analytics, Target, Experience Manager, and Creative Cloud help take personalization to the next level. 

Furthermore, the Adobe Commerce PWA Studio project provides a set of developer tools that allow for the development, deployment, and maintenance of a Progressive Web App (PWA) storefront on top of Adobe Commerce.

To simplify terminology, Adobe Commerce offers a powerful, all round solution for your web shop; both backend and storefront wise.

Google Dialogflow, on the other hand, offers a comprehensive development platform for chatbots and voicebots, empowering your customers to establish rich and lifelike conversation through their state-of-the-art virtual agents. The strength of which lies in the powerful BERT-based natural language understanding (NLU) models that are capable of recognizing intent and context accurately and efficiently in more complex use cases; thus vastly improving the chat/call containment rate; which in turn can turn tides in your favor when it comes to your shop’s conversion rate.

Dialogflow provides two different virtual agent services, each of which has its own agent type, user interface, API, client libraries, and documentation:

  • Dialogflow Trial Edition - is a free edition that provides most of the features of the standard ES agent type. It offers limited quota and support by community and e-mail. This edition is suitable to experiment with Dialogflow.
  • Dialogflow ES - The Dialogflow Essentials (ES) Edition is a pay-as-you-go edition that provides the standard ES agent type. The Essentials Edition offers production-ready quotas and support from Google Cloud support.
  • Dialogflow CX - The Dialogflow Customer Experience (CX) Edition is a pay-as-you-go edition that provides the advanced CX agent type. The CX Edition offers production-ready quotas and support from Google Cloud support.

As we move forward with our solution, We won’t go into the actual details of implementation on a code level, rather it’s breakdown; or one variant of it in terms of higher level specification.

Backend Requirements

Terminology wise, by backend we imply anything not accessible on the client side, through the browser.

Dialogflow

For the purpose of this article, we can use Dialogflow trial edition; that alone would get us far enough. Dialogflow agent is our starting point. We can think of a Dialogflow agent much like a call center agent, or sales person. We can easily define and use multiple agents with your webshop; whereas one agent might be proficient in electronics type of conversation, while the other one might be more suited for wearables, toys, or alike. Technically, an agent is a natural language understanding module that translates chat/call conversation into structured data that your apps and services can understand.

As we open Dialogflow for the first time, the service asks us to create a new Agent.

Dialogflow dashboard

We start off by naming our chat/voice agent, e.g. Alice.

Creating a new Agent

Once we are past the point of agent creation, we are exposed to the inners of each agent; where we come across terms such as:

  • Intents
  • Entities
  • Actions and parameters
  • Rich messages
  • Context
  • Events
  • Dialog
  • Fulfillment

Moving forward we will briefly touch upon intents, actions and parameters, and fulfillment., as a bare minimum to get our agent doing something.

Understanding Intents

The act of human conversation happens in turns, e.g.

  1. End-User (Anna): Hey there 
  2. Agent (Alice): Hi, my name is Alice. What shall I call you?
  3. End-User (Anna): I am Anna
  4. Agent (Alice): Welcome to our shop Anna. How may I help you?
  5. End-User (Anna): I am looking for a birthday present.
  6. Agent (Alice): Lovely, we got plenty of those to go around. Anything particular you have in mind?
  7. End-User (Anna): Not really to be honest. I could really use some suggestions.
  8. Agent (Alice): Sure, let see; is it a boy, girl or a more neutral type of gift you are looking for?
  9. End-User (Anna): His name is Adam, the cutest, 6 year old boy
  10. Agent (Alice): Do you know if Adam prefers any particular type of board games, action figures, sport games, etc?
  11. End-User (Anna): He loves dinosaurs, especially the flying ones.
  12. Agent (Alice): Great, we have plenty of those in our store. Mind you; some of our products have a longer delivery time than others. We might help you narrow them down if you give us Adam’s birthday date?
  13. End-User (Anna): His birthday is on May 16th
  14. Agent (Alice): Thanks Anna. Below are some readily available toys that Adam might enjoy.

While this might not be the best scripted type of conversation, it demonstrates a series of intents. An intent categorizes an end-user's (Anna) intention for one conversation turn. In these simple 14 conversation turns, 7 of them are end-user's (Anna) dialog; so let’s try and deduct the intent for each of them:

  • #1 - the intent is merely to say hello, to kick off a conversation
  • #3 - the intent is to give Agent (Alice) her (Anna’s) name
  • #5 - the intent is to give Agent (Alice) a sort of reason to be here on shop, a type of product that she (Anna) is looking for
  • #7 - the intent is give Agent (Alice) a starting point in underlying product search; which in this case is hinting Agent (Alice) to further continue with inquiry on type of products
  • #9 - the intent is to give a gift receiver information (name, age, gender)
  • #11 - the intent is to give hints on products of interest (dinosaurs, flying)
  • #13 - the intent is to determine latest potential delivery date, which would enable underlying logic to filter only products deliverable before the said date

Intents are the key ingredient to breaking down all the back and forth conversation between Agent and End-User into meaningful and usable variables later on.

Any meaningful intent has to contain the following:

  • Training phrases - lots and lots of training phrases; example phrases for what end-users might type or say. E.g. “He loves dinosaurs, especially the flying ones.” is merely one possible end-user expression. Other might be “I think he likes flying dinosaurs”; whereas third one might be “he is into dinosaurs, big time”, etc. For an agent to be able to really understand the end-user and extract the needed variables from end-user expression, we need to write lots of these end-user expression variations, which are then fed into Dialogflow's built-in machine learning.
  • Action: When an intent is matched, Dialogflow provides the action to your system, and we can use the action to trigger certain actions defined in your system. E.g. If we think in terms of Magento and its layered navigation search, an intent that resolves the type of toy would trigger an action that sets the category of some other product attribute flag to on the layered navigation, and thus narrow down the search results.
  • Parameters: Parameters go hand in hand with actions. When an intent is matched at runtime, Dialogflow provides the extracted values from the end-user expression as parameters. Each parameter has a type, called the entity type, which dictates exactly how the data is extracted. Unlike raw end-user input, parameters are structured data that can easily be used to perform some logic or generate responses.

Responses: We define text, speech, or visual responses to return to the end-user. These may provide the end-user with answers, ask the end-user for more information, or terminate the conversation.

Implementing the fulfillment business logic

The fulfillment logic is essentially about getting Dialogflow structured data into our system (e.g. shop), doing something with it, and returning some response based on it.

In our Agent (Alice) <-> End-User (Anna) conversation, the end result is for the agent to break down the conversation into parameters (customer_gender, toy_type, delivery_date, …) and push those parameters to our shop. The shop will then use those parameters and feed them to product repository interface, to fetch the results that filter based on these values.

If we ignore the visual details; the overall flow of communication goes as follows:

  • End-User (Anna) loads our web shop, e.g. http://shop.app/
  • On load, web shop shows Agent (Alice)
  • End-User (Anna) converses with Agent (Alice)
  • The Agent (Alice) chat window pushes the data to Dialogflow service
  • Each line of conversation is data going back and forth between Agent (Alice) and End-User (Anna), through Dialogflow service
  • The Dialogflow service works to resolve intents based of conversation
  • Once intent is resolved (parameters, actions), the webhook request is made towards fulfillment webhook URL, e.g. our Magento web shop that exposes URL http://shop.app/index.php/ai/webhook/index
  • Within this request, there is structured data that Dialogflow service extracted for us, from the conversation
  • The Magento webhook code is doing something with that data, and returning something as a response. This “something”; can easily be a JSON list of matching products.
  • The Dialogflow service then processes webhook response (e.g. list of matching products) and shows it to end-user

To get this flow working, we need to enable webhook in Dialogflow and point the URL to our Magento webshop.

Enabling the webhook

The fulfillment webhook URL might be something like http://shop.app/index.php/ai/webhook/index, whereas the code behind webhook might read as something like:

<?php
namespace Ancord\AiAssistant\Controller\Webhook;

use Magento\Catalog\Model\Product\Attribute\Repository;
use Magento\Catalog\Model\ProductRepository;
use Magento\Framework\Api\FilterBuilder;
use Magento\Framework\Api\Search\FilterGroupBuilder;
use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;

class Index extends Action
{
    private $productRepository;
    private $productAttributeRepository;
    private $filterBuilder;
    private $filterGroupBuilder;
    private $searchCriteriaBuilder;
    public function __construct(

       Context $context,
        ProductRepository $productRepository,
        Repository $productAttributeRepository,
        FilterBuilder $filterBuilder,
        FilterGroupBuilder $filterGroupBuilder,
        SearchCriteriaBuilder $searchCriteriaBuilder
      )
   {
       parent::__construct($context);
        $this->productRepository = $productRepository;
        $this->productAttributeRepository = $productAttributeRepository;
        $this->filterBuilder = $filterBuilder;
        $this->filterGroupBuilder = $filterGroupBuilder;
        $this->searchCriteriaBuilder = $searchCriteriaBuilder;
   }
   /**
     * URL like http://shop.app/index.php/ai/webhook/index
    */
    public function execute()
   {
       $parameters = [];
        $groups = [];
        $data = [];
        $entityBody = \json_decode(\file_get_contents('php://input'), true);

       // Go through each of the context and their parameters, and merge them

       foreach ($entityBody['result']['contexts'] as $context) {
             if (!empty($context['parameters'])) {
                $_parameters = array_filter($context['parameters'], function ($k) {
                    if (strstr($k, '.original')) {
                       return false;
                   }
                   return true;
               }, ARRAY_FILTER_USE_KEY);
               $parameters = array_merge($parameters, $_parameters);
           }
       }
       // Add "customer_gender" to filter if any

       if (!empty($parameters['customer_gender'])) {
            $customerGenderAttr = $this->productAttributeRepository->get('customer_gender');
            $customerGenderOptions = $customerGenderAttr->getOptions();
            
            foreach ($customerGenderOptions as $customerGenderOption) {
                if (strtolower($customerGenderOption->getLabel()) === 'any') {
                   continue;
               }
               if (strtolower($customerGenderOption->getLabel()) === strtolower($parameters['customer_gender'])) {
                   $filter = $this->filterBuilder
                       ->setField('customer_gender')
                       ->setConditionType('like')
                       ->setValue($customerGenderOption->getValue())
                       ->create();

                   $group = $this->filterGroupBuilder
                        ->addFilter($filter)
                       ->create();

                   $groups[] = $group;
               }
               }
       }
       // Add "toy_type" to filter if any

       if (!empty($parameters['toy_type'])) {
            $toyTypeAttr = $this->productAttributeRepository->get('toy_type');
            $toyTypeOptions = $toyTypeAttr->getOptions();

           foreach ($toyTypeOptions as $toyTypeOption) {
                if (strtolower($toyTypeOption->getLabel()) === 'any') {
                    continue;
               }
               if (strtolower($toyTypeOption->getLabel()) === strtolower($parameters['toy_type'])) {
                     $filter = $this->filterBuilder
                        ->setField('toy_type')
                        ->setConditionType('like')
                        ->setValue($toyTypeOption->getValue())
                        ->create();

                   $group = $this->filterGroupBuilder
                        ->addFilter($filter)
                        ->create();

                   $groups[] = $group;
               }
           }
       }
       if ($entityBody['result']['action'] == 'toy.search') {
             $searchCriteria = $this->searchCriteriaBuilder
                ->setPageSize(16)
                ->setCurrentPage(1)
                ->setFilterGroups($groups)
                ->create();

           $result = $this->productRepository->getList($searchCriteria);
            $products = $result->getItems();
            foreach ($products as $product) {
                $data[] = $product->toArray();
           }
       }
       $response = [
            'speech' => $entityBody['result']['fulfillment']['speech'],
            'displayText' => $entityBody['result']['fulfillment']['speech'],
            'data' => $data,
            'source' => 'MagentoShop'
       ];

       header('Content-Type: application/json;charset=utf-8');
        echo \json_encode($response);
        exit;
   }
}

Mind you, this is an utterly simplified example. The example demonstrates processing of incoming requests, looking for two particular product attribute filters to apply on top of product search results; customer_gender and toy_type; whenever toy.search action is found in the incoming request. As we said earlier; actions are triggered when an intent is matched; so we can specify all sorts of custom actions we want to trigger based on the matched intents. In this case, let’s imagine we specified toy.search action whenever intent for gender and toy_type have been resolved.

See https://cloud.google.com/dialogflow/es/docs/fulfillment-overview for more information about fulfillment.

Frontend requirements

Terminology wise, by frontend we imply anything accessible on the client side, through the browser.

There are multiple ways we can embed agents into our own storefront.

The simpler one  is as easy as going under Dialogflow’s Integration > Text Based > Dialogflow Messenger.

This gives us a simple HTML chunk of code we would embed into our web shop.


     <script src="https://www.gstatic.com/dialogflow-console/fast/messenger/bootstrap.js?v=1"></script>

     <df-messenger

       intent="WELCOME"
       chat-title="Alice"
       agent-id="6df255cc-1b16-43e9-842e-6c75ff073069"
       language-code="en"

     ></df-messenger>
     

In its simplest form, this manifests as per below.

Once the user starts typing into the input field, the chat expands and the conversation starts.

With our minimal agent up and running, and communicating with our Magento web shop, we are now finally ready to further expand its intentions and actions in a backend side of things, as well as utilize the Dialogflow’s rich response messages, to make our presentation more user friendly.

See https://cloud.google.com/dialogflow/es/docs/intents-rich-messages for more information about rich response messages.

Summary

To briefly recap on what we’ve just talked about. The chat/call bots are a powerful and in a way affordable mechanism of introducing new types of interaction with your customer base. However, chat/call bot implementation can easily fire back, in a sense of degrading your user experience if the intents are not suited for the task at hand. This means we really need to put effort into writing intents that truly understand most of the back and forth communication between agent and the end-user; otherwise the user will just give up on using the agent. Thus, In terms of development hours spent on the project, intents are likely one area that will consume most of the time.

Share your thoughts with us. Let's talk!