<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Bastien Botella</title>
    <description>The latest articles on DEV Community by Bastien Botella (@bastienbot).</description>
    <link>https://dev.to/bastienbot</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F445877%2Ff03bbaad-df68-47c2-8e84-2f07fc4d2ef2.jpeg</url>
      <title>DEV Community: Bastien Botella</title>
      <link>https://dev.to/bastienbot</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bastienbot"/>
    <language>en</language>
    <item>
      <title>Top 5 Advices to Get Started With Programming</title>
      <dc:creator>Bastien Botella</dc:creator>
      <pubDate>Mon, 08 Mar 2021 18:50:30 +0000</pubDate>
      <link>https://dev.to/bastienbot/top-5-advices-to-get-started-with-programming-1hh4</link>
      <guid>https://dev.to/bastienbot/top-5-advices-to-get-started-with-programming-1hh4</guid>
      <description>&lt;p&gt;Learning a new skill is challenging for many reasons.&lt;/p&gt;

&lt;p&gt;First of all, we start investing time in something we know only very little about and it can take days, weeks or even months before we start to understand what it takes to be "good" at it.&lt;br&gt;
Since it takes a great amount of resilience to get from 0 to 1 and knowing where to start is always helpful.&lt;/p&gt;

&lt;p&gt;To help all beginners, we gathered below the 5 things that any beginner should do when starting to learn programming.&lt;/p&gt;
&lt;h1&gt;
  
  
  1 - Pick an "easy" programming language
&lt;/h1&gt;

&lt;p&gt;I know that when starting a new challenge, anyone wants to shoot to the moon and that's fair, but yet it is very helpful to start with a simple programming language in order to focus to what matters most: understanding the basics of programming.&lt;/p&gt;

&lt;p&gt;Here are below programming languages that are nice to get started with programming:&lt;/p&gt;

&lt;p&gt;PHP: this is a very simple and solid programming language, widely used over the internet, it is indeed a very nice language to get started.&lt;br&gt;
CSML: this language is very simple and requires no software to be used, CSML Playground allows beginners to get started online.&lt;br&gt;
Python: widely used among Data Scientists and web developers, Python can be very easy to use and well as very technical for deep use.&lt;/p&gt;
&lt;h1&gt;
  
  
  2 - Find yourself an app or website idea
&lt;/h1&gt;

&lt;p&gt;Learning how to code is much easier when you have a use case in mind: a website for your chess club, a chatbot to book meting rooms, etc...&lt;/p&gt;

&lt;p&gt;Having a target app in mind will help you to find what the next step should be. You will also be able to look hoe other have done the same kind of app.&lt;/p&gt;

&lt;p&gt;For instance, for a chatbot, you'd need to learn the programming basics concepts as well as http requests.&lt;/p&gt;
&lt;h1&gt;
  
  
  3 - Start with conditions, loops and logic
&lt;/h1&gt;

&lt;p&gt;These three concepts are mainly what defines a programming language, therefore they are common to every single programming language out there, even very low level languages like Assembler.&lt;/p&gt;

&lt;p&gt;As a matter of fact when we started developing CSML, we started with conditions and logic, that allowed us to do pretty much anything we wanted right from the start.&lt;/p&gt;
&lt;h1&gt;
  
  
  4 - Be consistent when it comes to writing code
&lt;/h1&gt;

&lt;p&gt;Many languages allow developers to write the same code in different ways. For instance in Javascript, semicolon are not mandatory, so are extra spaces and indentation. In CSML, the following pieces of code have the same behaviour :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 1st way of writing this instruction&lt;/span&gt;
&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="nx"&gt;say&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello how are you?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;goto&lt;/span&gt; &lt;span class="nx"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;// The line below will show the same output&lt;/span&gt;
&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;say&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello how are you?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;goto&lt;/span&gt; &lt;span class="nx"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is really important to be consistent across all pieces of code we write as developers. This is so important that tools exist to make sure developers write code the same way within organizations. At Clevy, we use the Airbnb JavaScript Linter, every code that goes into production respects these guidelines.&lt;/p&gt;

&lt;p&gt;This is solely a habit and the earlier to get it, the better.&lt;/p&gt;

&lt;h1&gt;
  
  
  5 - Get involve in communities
&lt;/h1&gt;

&lt;p&gt;When learning a new skill, it's vital to talk to other people to get help, to help others as well, or even just to read through conversations.&lt;/p&gt;

&lt;p&gt;There are many communities over the internet: subreddits, slack teams, discord channels, dev.to, Facebook groups, etc...&lt;/p&gt;

&lt;p&gt;For instance with CSML, we have a community on Slack that anybody can join. People help each other over there, share their issues, solve others' or just talk about the products they build.&lt;/p&gt;

&lt;h1&gt;
  
  
  Bonus - Don't give up 😉
&lt;/h1&gt;

</description>
      <category>beginners</category>
      <category>csml</category>
    </item>
    <item>
      <title>How to Install a Self-Hosted CSML Engine on Ubuntu 18.04</title>
      <dc:creator>Bastien Botella</dc:creator>
      <pubDate>Mon, 25 Jan 2021 16:16:33 +0000</pubDate>
      <link>https://dev.to/bastienbot/how-to-install-a-self-hosted-csml-engine-on-ubuntu-18-04-1415</link>
      <guid>https://dev.to/bastienbot/how-to-install-a-self-hosted-csml-engine-on-ubuntu-18-04-1415</guid>
      <description>&lt;p&gt;CSML is a compelling open-source language and conversational engine to create rich chatbots. Did you know that you can also install and host it by yourself for free as a standalone web server on your own server? Let's find out how in this article!&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;On &lt;a href="https://github.com/CSML-by-Clevy/csml-engine"&gt;CSML Engine's github repository&lt;/a&gt;, we compile pre-built binaries for MacOS and Linux of the CSML Engine web server, called &lt;strong&gt;CSML Server&lt;/strong&gt;, at &lt;a href="https://github.com/CSML-by-Clevy/csml-engine/releases"&gt;every release&lt;/a&gt;, under the &lt;em&gt;assets&lt;/em&gt; section (&lt;a href="https://hub.docker.com/r/clevy/csml-engine"&gt;we also maintain docker images if you prefer&lt;/a&gt;). As in this example, we are going to install CSML Server on Ubuntu 18.04 (or most recent linux distributions such as Debian, CentOS, Amazon Linux 2...), we will use the &lt;strong&gt;linux-based 64-bit binary&lt;/strong&gt;, called &lt;code&gt;csml-server-linux-amd64&lt;/code&gt;. The latest &lt;a href="https://github.com/CSML-by-Clevy/csml-engine/releases/tag/v1.4.0"&gt;release to date is v1.4.0&lt;/a&gt;: let's &lt;a href="https://github.com/CSML-by-Clevy/csml-engine/releases/download/v1.4.0/csml-server-linux-amd64"&gt;copy the address of the corresponding asset&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eMDnnYr4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.csml.dev/content/images/2021/01/image-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eMDnnYr4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.csml.dev/content/images/2021/01/image-2.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Right Click &amp;gt; Copy Link Address&lt;/p&gt;

&lt;p&gt;To download the CSML Server executable on your own server, type the following command in your terminal:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ wget https://github.com/CSML-by-Clevy/csml-engine/releases/download/v1.4.0/csml-server-linux-amd64
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2U6jWkuU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.csml.dev/content/images/2021/01/image-4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2U6jWkuU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.csml.dev/content/images/2021/01/image-4.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After the file is downloaded, you can simply make it executable, rename it and run it directly:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ chmod +x csml-server-linux-amd64
$ mv csml-server-linux-amd64 csml-server
$ ./csml-server
&amp;gt; CSML Server listening on port 5000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Congratulations! It runs 🎉. Now go visit your server's IP on port 5000, which is in my case &lt;a href="http://34.241.38.167:5000/"&gt;http://34.241.38.167:5000/&lt;/a&gt; (but it will very likely be a different IP for you).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UuM8Wxx---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.csml.dev/content/images/2021/01/image-5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UuM8Wxx---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.csml.dev/content/images/2021/01/image-5.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;CSML Server's default homepage&lt;/p&gt;

&lt;p&gt;If you can see this page, CSML is correctly installed and runs properly on your machine. But we are not there yet! We do have a bit of configuration to do. You can for now simply hit &lt;code&gt;ctrl+C&lt;/code&gt; to kill the process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuration
&lt;/h2&gt;

&lt;p&gt;CSML Server can easily be configured with environment variables. In fact, the environment variables are documented on this very landing page, so it should be easy to do!&lt;/p&gt;

&lt;p&gt;The CSML Engine requires a database, and works either with MongoDB or Amazon DynamoDB. There are advantages and drawbacks to each of these offerings; in this example, we are going to use MongoDB, which is a popular choice.&lt;/p&gt;

&lt;p&gt;We will not cover how to install MongoDB in this article, but you can find instructions on &lt;a href="https://docs.mongodb.com/manual/tutorial/install-mongodb-on-ubuntu/"&gt;how to setup MongoDB&lt;/a&gt; in their documentation, or you can also use one of the many ready-to-use SaaS offerings by some hosting providers. For example, MongoDB themselves have &lt;a href="https://www.mongodb.com/cloud/atlas"&gt;Atlas&lt;/a&gt;, a managed, cloud-based MongoDB service.&lt;/p&gt;

&lt;p&gt;There are many ways to load environment variables in your shell. Let's simply create a simple &lt;code&gt;.env&lt;/code&gt; file next to the server executable and copy-paste the default environment variables in this file for your setup:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ENGINE_DB_TYPE=mongo

MONGODB_HOST=localhost
MONGODB_PORT=27017
MONGODB_DATABASE=csml
MONGODB_USERNAME=
MONGODB_PASSWORD=

ENGINE_SERVER_PORT=5000

ENCRYPTION_SECRET=some-secret-string
DISABLE_SSL_VERIFY=false
DEBUG=true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Of course, you are free to change these variables to accommodate your own setup. Among other things, you should also obviously pick your own &lt;code&gt;ENCRYPTION_SECRET&lt;/code&gt; and not leave the default value!&lt;/p&gt;

&lt;p&gt;Then, you can run this command to export the variables from this file into your shell:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ export $(cat .env | xargs)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;To check that the environment is correctly set, you can use the &lt;code&gt;env&lt;/code&gt; command and verify that everything looks right.&lt;/p&gt;

&lt;p&gt;Then, re-run the &lt;code&gt;./csml-server&lt;/code&gt; command. The result will be the same, but now your server should be correctly connected to your database and ready to use!&lt;/p&gt;

&lt;h2&gt;
  
  
  Using your Self-Hosted CSML Server
&lt;/h2&gt;

&lt;p&gt;To test if your CSML Server installation works properly, you can run a simple query, for example by saying "Hi!" to a sample bot:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -X "POST" "http://YOUR_SERVER_IP:ENGINE_PORT/run" \
     -H 'content-type: application/json' \
     -d $'{
  "bot": {
    "default_flow": "Default",
    "id": "mybot",
    "name": "MySuperBot"
    "flows": [
      {
        "id": "e0a13373-2037-4590-8018-ab14e74b27a1",
        "content": "start:\\n\\tsay \\"Hello from CSML Server!\\"\\ngoto end",
        "commands": [
          "/default"
        ],
        "name": "Default",
        "description": "Default custom flow"
      }
    ]
  },
  "event": {
    "metadata": {
      "some": "info",
      "about": "the current user"
    },
    "payload": {
      "content": {
        "text": "Hi!"
      },
      "content_type": "text"
    },
    "request_id": "67d283bd-35d5-4744-be61-2f063573022f",
    "client": {
      "user_id": "myuser",
      "channel_id": "mychan",
      "bot_id": "mybot"
    }
  }
}'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;A sample request to a CSML Server instance&lt;/p&gt;

&lt;p&gt;The server should respond with something like:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "messages": [
    {
      "payload": {
        "content_type": "text",
        "content": {
          "text": "Hello from CSML Server!"
        }
      },
      "interaction_order": 0,
      "conversation_id": "555416aa-c033-4676-ad64-eaf5c6783617",
      "direction": "SEND"
    }
  ],
  "conversation_end": true,
  "request_id": "67d283bd-35d5-4744-be61-2f063573022f",
  "received_at": "2021-01-22T20:58:40.154Z",
  "interaction_id": "591c2ad1-b540-47b0-bd5c-9a5a3907cd0f",
  "client": {
    "bot_id": "mybot",
    "user_id": "myuser",
    "channel_id": "mychan"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;A sample response from CSML Server&lt;/p&gt;

&lt;p&gt;You can find the full REST API documentation in OpenAPI v3 format &lt;a href="https://github.com/CSML-by-Clevy/csml-engine/blob/master/csml_server/swagger.yaml"&gt;on our Github repository&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next Steps: Prepare For Production
&lt;/h2&gt;

&lt;p&gt;This article gives you an easy starting point to install the CSML Engine on your own server. The instructions are similar if you plan to use your own development machine as well. (By the way, we also provide a MacOS (intel) binary.)&lt;/p&gt;

&lt;p&gt;However, if you need to run your own CSML Server for a production payload, there are probably a few extra steps that you should take (or just use &lt;a href="https://studio.csml.dev"&gt;CSML Studio&lt;/a&gt;, the online CSML development environment that does not need any installation). You will probably need to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  add a reverse-proxy such as nginx and enable HTTPS for secure exchanges&lt;/li&gt;
&lt;li&gt;  add some redundancy to make sure that it is always available&lt;/li&gt;
&lt;li&gt;  make sure that your service is resilient and handles the loss of one or more processes gracefully&lt;/li&gt;
&lt;li&gt;  add some auto-scalability into the mix, to make sure that you are ready to serve the right number of simultaneous conversations for your use case&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Depending on how you plan to distribute your bot, there are many good ways to do it. If you are looking for architecture advice, please &lt;a href="https://csml.dev/slack"&gt;reach out on Slack&lt;/a&gt;! We are running millions of conversations securely on CSML Studio and can probably point you in the right direction.&lt;/p&gt;

</description>
      <category>csml</category>
      <category>ubuntu</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Get your Chatbot to Speak over 12 Languages with Deepl</title>
      <dc:creator>Bastien Botella</dc:creator>
      <pubDate>Thu, 19 Nov 2020 11:44:45 +0000</pubDate>
      <link>https://dev.to/bastienbot/get-your-chatbot-to-speak-over-12-languages-with-deepl-3hd</link>
      <guid>https://dev.to/bastienbot/get-your-chatbot-to-speak-over-12-languages-with-deepl-3hd</guid>
      <description>&lt;p&gt;One of the great strengths of chatbots is their ability to adapt to each and every user. Chatbots can remember user details, fetch information from third-party API, or ask questions to the user. Being able to speak and understand the user's language is surely on the top of the list when it comes to adapting the conversation to the user.&lt;/p&gt;

&lt;p&gt;In this article we will see how to use translation to get a chatbot to understand the user and have a conversation in his/her language. We're going to use the &lt;a href="https://www.deepl.com/fr/docs-api/"&gt;Deepl&lt;/a&gt; App, available on the &lt;a href="https://studio.csml.dev?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=deepl"&gt;CSML Studio&lt;/a&gt;. Note that Deepl is not free but extremely accurate, there is an alternative app that you could use for free : &lt;a href="https://www.frengly.com/translate"&gt;Frengly&lt;/a&gt;; although it is free, it is also not even close to Deepl in terms of accuracy. Good news, both Apps work the same way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step1: Create a chatbot in one single language
&lt;/h2&gt;

&lt;p&gt;Let's create a food recipe chatbot in english. We'll get the recipes from an open API: &lt;a href="http://www.recipepuppy.com"&gt;RecipePuppy&lt;/a&gt;. The chatbot is going to ask what sort of dish and what ingredient the user wants in the recipe, and then get the matching dish from the API. Easyyyyyyyyyyy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="nx"&gt;say&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hi, I am the chatbot that find awesome recipes for you!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;goto&lt;/span&gt; &lt;span class="nx"&gt;dishType&lt;/span&gt;

&lt;span class="nx"&gt;dishType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="nx"&gt;say&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;What type of dish are you looking for?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;hold&lt;/span&gt;
  &lt;span class="nx"&gt;remember&lt;/span&gt; &lt;span class="nx"&gt;dType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;
  &lt;span class="nx"&gt;goto&lt;/span&gt; &lt;span class="nx"&gt;dishIngredient&lt;/span&gt;

&lt;span class="nx"&gt;dishIngredient&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="nx"&gt;say&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;What ingredient would you like in the recipe?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;hold&lt;/span&gt;
  &lt;span class="nx"&gt;remember&lt;/span&gt; &lt;span class="nx"&gt;dIngredient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;
  &lt;span class="nx"&gt;say&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Ok! Let me find the right recipes for you!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;goto&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt;

&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;HTTP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http://www.recipepuppy.com/api/?i={{dIngredient}}&amp;amp;q={{dType}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nx"&gt;recipes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;
  &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nx"&gt;cards&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="nx"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;recipe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;recipes&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nx"&gt;cards&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Card&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;recipe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;subtitle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;recipe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ingredients&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;image_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;recipe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;thumbnail&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;buttons&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[]))&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;say&lt;/span&gt; &lt;span class="nx"&gt;Carousel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;cards&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cards&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;goto&lt;/span&gt; &lt;span class="nx"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step2: Install the Deepl App
&lt;/h2&gt;

&lt;p&gt;Now that we have our chatbot, let's get started with translation. Installing the Deepl App is the way to go. Head over to the &lt;code&gt;Functions&lt;/code&gt; menu, find the Deepl App in the list, and install it. Enter your Deepl credentials to finish the installation. The same process can be done for Frengly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--brxUnSvA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/bxbme2hc7nhhuont5dnl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--brxUnSvA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/bxbme2hc7nhhuont5dnl.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
Done!&lt;/p&gt;
&lt;h2&gt;
  
  
  Step3: Set the user's language
&lt;/h2&gt;

&lt;p&gt;When a user first talks to the chatbot, we want to ask this user what's his/her language in order to switch from english to this language. Let's add this bit of logic.&lt;br&gt;
First we check if the user language is already known by the chatbot (even if it's english!), and if it isn't we want the bot to go to the step &lt;code&gt;pickLanguage&lt;/code&gt; before saying anything else. This way we can set the user language in memory for further use.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;language&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;goto&lt;/span&gt; &lt;span class="nx"&gt;pickLanguage&lt;/span&gt;
  &lt;span class="nx"&gt;say&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hi, I am the chatbot that find awesome recipes for you!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;goto&lt;/span&gt; &lt;span class="nx"&gt;dishType&lt;/span&gt;

&lt;span class="nx"&gt;pickLanguage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nx"&gt;availableLang&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fr&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;de&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;es&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pt&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;it&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;jp&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ru&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="nx"&gt;say&lt;/span&gt; &lt;span class="nx"&gt;Question&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;What language should we speak?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;button_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;quick_reply&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;buttons&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;availableLang&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;hold&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;availableLang&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;say&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;You should click on one of the buttons 🙃&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="nx"&gt;goto&lt;/span&gt; &lt;span class="nx"&gt;pickLanguage&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;remember&lt;/span&gt; &lt;span class="nx"&gt;language&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;
  &lt;span class="nx"&gt;say&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Ok! Let's spreak {{language}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;goto&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step4: Translate the content
&lt;/h2&gt;

&lt;p&gt;Now that we've installed the App and know the user language, we need to dynamically translate everything that the chatbot and user say. This way the chatbot will be able to understand when the user asks an "Omelette du fromage" 🤣.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9MQFJuo0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ivhboa26vxft2wbjjy8s.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9MQFJuo0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ivhboa26vxft2wbjjy8s.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's create a CSML function to wrap the translating logic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;fn&lt;/span&gt; &lt;span class="nx"&gt;translate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;
  &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;deepl&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;translations&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;

&lt;span class="c1"&gt;// Let's check how transltion work in the `dishType` step for instance&lt;/span&gt;
&lt;span class="nx"&gt;dishType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;// Translating to the user language&lt;/span&gt;
  &lt;span class="nx"&gt;say&lt;/span&gt; &lt;span class="nx"&gt;translate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;language&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;What type of dish are you looking for (tart, stew, ...)?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;hold&lt;/span&gt;
  &lt;span class="c1"&gt;// Translating user input to english before placing the value in a variable&lt;/span&gt;
  &lt;span class="nx"&gt;remember&lt;/span&gt; &lt;span class="nx"&gt;dType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;translate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;language&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;goto&lt;/span&gt; &lt;span class="nx"&gt;dishIngredient&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Click on the chatbot at the bottom right of the screen to see the result!&lt;/p&gt;

&lt;p&gt;Here is the chatbot source code: &lt;a href="https://github.com/CSML-by-Clevy/recipe-finder"&gt;https://github.com/CSML-by-Clevy/recipe-finder&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Going further
&lt;/h2&gt;

&lt;p&gt;Here are a few ideas to improve this chatbot:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Show several recipes with the &lt;code&gt;Carousel()&lt;/code&gt; component&lt;/li&gt;
&lt;li&gt;Give the opportunity to the user to change his/her language  to an other one&lt;/li&gt;
&lt;li&gt;Plug some NLP so the user can pick the language using actual words&lt;/li&gt;
&lt;li&gt;Allow the user to provide more than one ingredient&lt;/li&gt;
&lt;li&gt;Check if the dish types and ingredients exist&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Well I guess there are many way to improve the chatbot but at least we've got a great base!&lt;/p&gt;

</description>
      <category>chatbot</category>
      <category>csml</category>
      <category>translation</category>
    </item>
    <item>
      <title>Use the actual Eliza algorithm in your chatbot</title>
      <dc:creator>Bastien Botella</dc:creator>
      <pubDate>Mon, 26 Oct 2020 09:14:37 +0000</pubDate>
      <link>https://dev.to/bastienbot/use-the-actual-eliza-algorithm-in-your-chatbot-2k16</link>
      <guid>https://dev.to/bastienbot/use-the-actual-eliza-algorithm-in-your-chatbot-2k16</guid>
      <description>&lt;p&gt;Even though the chatbot trend is fairly new, they've been &lt;strong&gt;around for a long time&lt;/strong&gt;. I can remember talking to chatbots over ten years ago when trying to reach out to my mobile phone services (spoiler alert: I never got hold of them ~~).&lt;br&gt;
And then in 2016, Mark Zukerberg announced the integration of chatbots on Facebook Messenger and the trend started. But how did all this start?&lt;/p&gt;

&lt;p&gt;The first significant chatbot ever created was &lt;strong&gt;Eliza&lt;/strong&gt;. It is a program, part of the early work in NLP (Natural Language Processing). Developed between 1964 and 1966, it was a &lt;strong&gt;state of the art&lt;/strong&gt; NLP program back then, had to run on 128kb of ram (that was a lot back in 1966!). Eliza has a single purpose: keep the conversation running by asking questions to the user and trying to get him/her to keep talking. Eliza was actually meant to simulate the conversation of a psychotherapist.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ngkBCC54--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ek4xxetf43pzjkproo3c.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ngkBCC54--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ek4xxetf43pzjkproo3c.jpg" alt="Eliza"&gt;&lt;/a&gt;&lt;br&gt;
Let's see how to integrate the Eliza algorithm in a CSML chatbot!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt;: You can import the chatbot with the Eliza integration, by clicking on the link at the bottom of the page... and yes it's free.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 1: The use case
&lt;/h2&gt;

&lt;p&gt;We're going to create a chatbot that will interact with people who want to chitchat or are feeling a little down.&lt;br&gt;
This chatbot will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;propose a meditation video&lt;/li&gt;
&lt;li&gt;give a random motivational quote&lt;/li&gt;
&lt;li&gt;talk to the user using Eliza algorithm&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Step 2: Let's create the video and quotes conversation
&lt;/h2&gt;

&lt;p&gt;For the sake of simplicity, we'll create this chatbot in the &lt;a href="https://playground.csml.dev/?utm_source=blog&amp;amp;utm_medium=article&amp;amp;utm_campaign=elizo"&gt;CSML Development Studio&lt;/a&gt;, it's &lt;strong&gt;free&lt;/strong&gt;, easy to use and I can &lt;strong&gt;share the chatbot&lt;/strong&gt; at the end 🤙&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;start:
  say "Hello, I'm your Elizo"
  say Typing(3000)
  say "I'm here to make you feel good 🤗"
  say Typing(3000)
  goto menu

menu:
  say Question("What would you like to do?",
    buttons=[
      Button("I want to meditate") as btn_med,
      Button("I need some motivation!") as btn_mot,
      Button("Let's talk") as btn_talk
    ])
  hold
  if (event match btn_med) {
    goto meditation
  } else if (event match btn_mot) {
    goto motivation
  } else {
    say "Tell me what's on your mind ☺️"
    goto talk
  }

meditation:
  say "Here is video to help you with your meditation, enjoy 😌"
  say Video("https://www.youtube.com/watch?v=inpok4MKVLM")
  say Typing(20000)
  goto menu

motivation:
  do quotes = HTTP("https://type.fit/api/quotes").get().send()
  do shuffledQuotes = Shuffle(quotes)
  say Typing(3000)
  say "“{{shuffledQuotes[0].text}}”\n\n_{{shuffledQuotes[0].author}}_"
  say Typing(8000)
  goto menu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code above, we show three buttons to the user, the meditation step shows a video, the motivation step gives a motivational quote provided by an -awesome- API. Both of these steps bring the user back to the menu at the end.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Integrate Eliza
&lt;/h2&gt;

&lt;p&gt;In order to use the Eliza algorithm, we'll need to add it to our list of custom functions.&lt;/p&gt;

&lt;p&gt;First, let's &lt;strong&gt;find a version of the algorithm&lt;/strong&gt; that we can use. CSML supports &lt;strong&gt;large range of languages&lt;/strong&gt; such as nodejs, python, java, go, etc... I am more of a nodejs guy myself so I found this &lt;a href="https://github.com/ncarver/elizanode"&gt;repository&lt;/a&gt; that seems to do the job.&lt;/p&gt;

&lt;p&gt;Let's open a new nodejs project, install the &lt;code&gt;elizanode&lt;/code&gt; dependency using npm and create a &lt;code&gt;index.js&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// We import the dependency&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ElizaNode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;elizanode&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// event.query encloses the user message&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;No query parameter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="c1"&gt;// We init Eliza&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;eliza&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ElizaNode&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="c1"&gt;// We get the answer from eliza&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;reply&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;eliza&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// We check if Eliza evaluates the user message as the end of the conversation&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;eliza&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;quit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;end&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;reply&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;end&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;reply&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And finally we need zip the package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ zip -r9 eliza.zip index.js node_modules
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And now let's import it in the Studio:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click on &lt;code&gt;Functions&lt;/code&gt; in the sidebar, then &lt;code&gt;Add custom function&lt;/code&gt; &amp;gt; &lt;code&gt;Quick Mode&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Click on the upload area and upload the file &lt;code&gt;eliza.zip&lt;/code&gt; that you just created&lt;/li&gt;
&lt;li&gt;Give a name to your function&lt;/li&gt;
&lt;li&gt;Make sure that the runtime is set to &lt;code&gt;nodejs12.x&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Double check that the handler is &lt;code&gt;index.handler&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We're all set!&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Get Eliza to interact with the user
&lt;/h2&gt;

&lt;p&gt;Let's now add the missing step to this chatbot: the talk step!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;talk:
  hold
  do response = Fn("Eliza", query=event)
  say Typing(5000)
  say "{{response.message}}"
  if (response.end == true) {
    goto menu
  }
  goto talk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This step is basically an infinite loop: as long as Eliza does not detect that the user wants to end the conversation, we keep querying the algorithm so Eliza can answer. Note that a simple "Bye" can end the conversation at any given time, the user then go back to the menu.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step5: Done!
&lt;/h2&gt;

&lt;p&gt;That's it! We can now test Eliza 🎉&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BcU8MQgb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/e18n32b4bgwecm72z0gt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BcU8MQgb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/e18n32b4bgwecm72z0gt.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can obviously add a few features to this chatbot, like add more NLP to it, or extend Eliza's vocabulary.&lt;/p&gt;

&lt;p&gt;To import the ready-to-use chatbot, &lt;a href="https://studio.csml.dev/bots?action=import&amp;amp;import_mode=IMPORT_URL&amp;amp;name=Elizo&amp;amp;archive_url=https://github.com/CSML-by-Clevy/Elizo/archive/master.zip&amp;amp;autosubmit=true&amp;amp;utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=elizo"&gt;👉 it's over here 👈&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>nlp</category>
      <category>csml</category>
    </item>
    <item>
      <title>Using NLP in a CSML Chatbot with Dialogflow</title>
      <dc:creator>Bastien Botella</dc:creator>
      <pubDate>Mon, 19 Oct 2020 06:41:02 +0000</pubDate>
      <link>https://dev.to/bastienbot/using-nlp-in-a-csml-chatbot-with-dialogflow-43da</link>
      <guid>https://dev.to/bastienbot/using-nlp-in-a-csml-chatbot-with-dialogflow-43da</guid>
      <description>&lt;p&gt;&lt;a href="https://dialogflow.cloud.google.com/"&gt;Dialogflow&lt;/a&gt; is one of the best and most popular tools on the market for Natural Language Processing. However, creating a full, rich chatbot conversation using only Dialogflow (and most other NLP libraries or services) can be quite difficult, which is why we created a NLP connector between CSML Studio and Dialogflow to get the best of both worlds!&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 0. Setup
&lt;/h2&gt;

&lt;p&gt;For this tutorial, we are going to assume that you already have setup a free Dialogflow account. For this example we will be using one of the simple pre-built agents, "User Name".&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zzVz2KOe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.csml.dev/content/images/2020/10/image.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zzVz2KOe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.csml.dev/content/images/2020/10/image.png" alt=""&gt;&lt;/a&gt;You can install this agent by searching for User Name under "pre-built agents"&lt;br&gt;
You will also need a free &lt;a href="https://studio.csml.dev?utm_source=blog&amp;amp;utm_medium=article&amp;amp;utm_campaign=dialogflow"&gt;CSML Studio account&lt;/a&gt; which will allow you to create rich chatbots and deploy them easily on any communication channel. Once that is done, simply create an empty bot, which you can do by visiting &lt;a href="https://studio.csml.dev/bots?utm_source=blog&amp;amp;utm_medium=article&amp;amp;utm_campaign=dialogflow"&gt;this page&lt;/a&gt; and clicking on "Create bot". If you are new to CSML or CSML Studio, I suggest you read the &lt;a href="https://docs.csml.dev/studio?utm_source=blog&amp;amp;utm_medium=article&amp;amp;utm_campaign=dialogflow"&gt;Getting Started&lt;/a&gt; first!&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1. Connecting Dialogflow and CSML Studio
&lt;/h2&gt;

&lt;p&gt;To connect your chatbot with the Dialogflow agent, you will first need to get a  Dialogflow service account key.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Visit your Dialogflow agent's settings panel&lt;/li&gt;
&lt;li&gt;Under Google Project, click on the Project ID&lt;/li&gt;
&lt;li&gt;Under IAM &amp;amp; Admin, go to Service Account.&lt;/li&gt;
&lt;li&gt;If no service account exists, create one, otherwise go to step 5. Give the new service account a name (for example "Dialogflow CSML"), and click Create. Then give it a role of Dialogflow API Admin, continue. Finally, create the Service Account.&lt;/li&gt;
&lt;li&gt;Find the service account in the list, and click on "create key". Select JSON, and click Create. A file will download to your computer.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now that you have retrieved service account credentials for your Dialogflow agent, you can add them to your CSML chatbot:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Visit your chatbot settings on CSML Studio&lt;/li&gt;
&lt;li&gt;Go to NLP and select Dialogflow as a NLP provider&lt;/li&gt;
&lt;li&gt;Upload the file you downloaded before&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Voilà! Your CSML chatbot is now correctly configured with your Dialogflow agent. Below is a video of the full setup process:&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2. Using Dialogflow NLP in your CSML Chatbot
&lt;/h2&gt;

&lt;p&gt;NLP can be used in several different ways in a CSML chatbot: horizontally by matching intents with flows, or vertically to progress in a flow. Let's start with matching intents and flows.&lt;/p&gt;

&lt;h3&gt;
  
  
  Flow triggers
&lt;/h3&gt;

&lt;p&gt;CSML flows are triggered by *commands. *When a command is found, the corresponding flow is launched, taking precedence over any other behavior. If an intent should launch a flow, you should add its name to the flow commands. This can be done in the flow's configuration.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9NWSeV4b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.csml.dev/content/images/2020/10/image-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9NWSeV4b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.csml.dev/content/images/2020/10/image-1.png" alt=""&gt;&lt;/a&gt;Configuring flow commands&lt;br&gt;
In this case, we created a flow called &lt;code&gt;GetUsername&lt;/code&gt; and set one of its commands to &lt;code&gt;name.user.get&lt;/code&gt;. If a user says "What's my name?", the the request will be sent for analysis to Dialogflow, which will return a match with intent &lt;code&gt;name.user.get&lt;/code&gt;, which will then trigger the start step in flow &lt;code&gt;GetUsername&lt;/code&gt; in the CSML Engine, closing any previously open conversation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Inside flows
&lt;/h3&gt;

&lt;p&gt;You can also use Dialogflow inside a flow to match incoming user events. For example, in this scenario, the bot asks the user if they like their username, and shows them 2 buttons:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yLV72aVX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.csml.dev/content/images/2020/10/image-3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yLV72aVX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.csml.dev/content/images/2020/10/image-3.png" alt=""&gt;&lt;/a&gt;&lt;br&gt;
At this stage, the user could use one of the buttons, but they could also type something like "I like my name very much", which we would like to match with one of the buttons. That's very easy! There are already 2 intents for that, &lt;code&gt;name.user.feedback.good&lt;/code&gt; and &lt;code&gt;name.user.feedback.bad&lt;/code&gt;. We can simply add the intent names to the corresponding buttons &lt;code&gt;accepts&lt;/code&gt; parameter, and match the user input like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  say Question(
    "Do you like your name?",
    button_type="quick_reply",
    buttons=[
      Button("Yay!", accepts=["name.user.feedback.good"]) as btny,
      Button("Meh...", accepts=["name.user.feedback.bad"]) as btnn,
    ]
  )
  hold

  if (event.match(btny)) {
    say "I'm glad you like it!"
    goto end
  }
  else if (event.match(btnn)) {
    say "Oh, I'm sorry to hear that!"
    goto end
  }
  else {
    say "I'm sorry, I didn't get that."
    goto feedback
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Matching intents inside a flow&lt;br&gt;
Now, if the user says something that is interpreted as &lt;code&gt;name.user.feedback.good&lt;/code&gt;, the bot will react as if the user clicked on the &lt;code&gt;Yay!&lt;/code&gt; button.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rQZ9pJTH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.csml.dev/content/images/2020/10/image-4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rQZ9pJTH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.csml.dev/content/images/2020/10/image-4.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Entities
&lt;/h3&gt;

&lt;p&gt;The final trick I would like to show is that you can also use your agent's *entities *in CSML!&lt;/p&gt;

&lt;p&gt;Let's imagine a scenario where the user would want to change their name. They would say something like "now call me John". This sentence matches the &lt;code&gt;name.user.save&lt;/code&gt; intent in Dialogflow, but also the &lt;code&gt;given-name&lt;/code&gt; entity is set to &lt;code&gt;"John"&lt;/code&gt;.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TeC-H4fv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.csml.dev/content/images/2020/10/image-5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TeC-H4fv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.csml.dev/content/images/2020/10/image-5.png" alt=""&gt;&lt;/a&gt;&lt;br&gt;
Let's use this in our bot. We'll create a new flow to handle the request to change the name (with a &lt;code&gt;name.user.save&lt;/code&gt; command), and try to trigger it with NLP.&lt;/p&gt;

&lt;p&gt;If we try to print the event's content with &lt;code&gt;say "{{event.get_content()}}"&lt;/code&gt;, we see that we receive a large object containing quite a lot of information:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "payload": "name.user.change",
  "text": "I want to change my name to John",
  "_nlp_provider": {
    "provider": "dialogflow",
    "project_id": "user-name-hetw"
  },
  "_original_event": {
    "content_type": "text",
    "content": {
      "text": "I want to change my name to John"
    }
  },
  "_nlp_result": {
    "allRequiredParamsPresent": true,
    "queryText": "I want to change my name to John",
    "intent": {
      "inputContextNames": [],
      "name": "projects/user-name-hetw/agent/intents/5d1759cb-6eb1-4cec-bde2-d7391c9a932d",
      "trainingPhrases": [],
      "followupIntentInfo": [],
      "displayName": "name.user.change",
      "parentFollowupIntentName": "",
      "messages": [],
      "rootFollowupIntentName": "",
      "mlDisabled": false,
      "outputContexts": [],
      "defaultResponsePlatforms": [],
      "parameters": [],
      "events": [],
      "priority": 0,
      "action": "",
      "resetContexts": false,
      "webhookState": "WEBHOOK_STATE_UNSPECIFIED",
      "isFallback": false
    },
    "speechRecognitionConfidence": 0,
    "languageCode": "en",
    "fulfillmentMessages": [
      {
        "message": "text",
        "platform": "PLATFORM_UNSPECIFIED",
        "text": {
          "text": [
            ""
          ]
        }
      }
    ],
    "webhookPayload": null,
    "action": "name.user.change",
    "intentDetectionConfidence": 1,
    "fulfillmentText": "",
    "webhookSource": "",
    "parameters": {
      "fields": {
        "last-name": {
          "stringValue": "",
          "kind": "stringValue"
        },
        "nick-name": {
          "stringValue": "",
          "kind": "stringValue"
        },
        "given-name": {
          "stringValue": "John",
          "kind": "stringValue"
        },
        "type": {
          "kind": "stringValue",
          "stringValue": ""
        }
      }
    },
    "sentimentAnalysisResult": null,
    "outputContexts": [],
    "diagnosticInfo": null
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We can see that &lt;code&gt;event._nlp_result&lt;/code&gt; key contains everything as &lt;a href="https://cloud.google.com/dialogflow/es/docs/reference/rest/v2/DetectIntentResponse#QueryResult"&gt;returned by Dialogflow's API&lt;/a&gt; (I encourage you to click through this link and see all the data that you can retrieve this way). You can actually access the entities this way: indeed, &lt;code&gt;event._nlp_result.parameters.fields&lt;/code&gt; does contain all the possible entities for this intent, and in our case we can see that the &lt;code&gt;given-name&lt;/code&gt; entity is set to &lt;code&gt;"John"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's create a small function to extract any name-related entities  from incoming intents:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn getNameEntity(event):
  do entities = event._nlp_result.parameters.fields
  if (entities) {
    if (entities["given-name"].stringValue) return entities["given-name"].stringValue
    if (entities["last-name"].stringValue) return entities["last-name"].stringValue
    if (entities["nick-name"].stringValue) return entities["nick-name"].stringValue
  }
  return Null
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now, if the user says "I want to set my name to John", we will be able to directly detect the value of the name they want to set and set it directly with just a simple yes/no confirmation, but if they did not give us a name, we need to ask them for their name first.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;start:
  // We know that the matched intent for this flow requires us to change the user's name,
  // but we need to check if the event triggering this flow has one of the `name` entities set
  remember newname = getNameEntity(event)

  // The user did not give us their new name, we need to specifically ask for it
  if (!newname) goto askForNameInput

  // Otherwise we can just ask for confirmation that we understood it right
  // and skip the "what's your new name" part
  goto confirmNewName
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Sure enough, here is the result of this conversation:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YnIO-E7O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.csml.dev/content/images/2020/10/image-6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YnIO-E7O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.csml.dev/content/images/2020/10/image-6.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;As you saw, using an existing Dialogflow agent with CSML Studio is quite easy. The setup of this integration takes less than one minute, and lets you very easily benefit from the conversation building advantages of both platforms: with CSML, you can easily build rich conversations using not only text but also images, videos, carousels..., connect them to any API or service using built-in apps or your own functions in any programming language, and enhance your chatbot's comprehension skills by using Dialogflow's very powerful NLU!&lt;/p&gt;

&lt;p&gt;In this tutorial, we only scratched the surface of what's possible to achieve with Dialogflow and CSML together as a brief introduction to this exciting feature of CSML Studio. The full source code of the chatbot demonstrated above &lt;a href="https://github.com/CSML-by-Clevy/Dialogflow-Demo"&gt;is available on github&lt;/a&gt;. You can also &lt;a href="https://studio.csml.dev/bots?action=import&amp;amp;import_mode=IMPORT_URL&amp;amp;name=Dialogflow%20Demo&amp;amp;archive_url=https%3A%2F%2Fgithub.com%2FCSML-by-Clevy%2FDialogflow-Demo&amp;amp;autosubmit=true"&gt;import it on CSML Studio in just one click&lt;/a&gt; to get started quickly!&lt;/p&gt;

&lt;p&gt;I'm confident that you will be able to use Dialogflow to its full power in your next CSML projects!&lt;/p&gt;

</description>
      <category>chatbot</category>
      <category>csml</category>
      <category>startup</category>
      <category>dialogflow</category>
    </item>
    <item>
      <title>Create a customer support chatbot with Zendesk and CSML</title>
      <dc:creator>Bastien Botella</dc:creator>
      <pubDate>Mon, 10 Aug 2020 10:47:17 +0000</pubDate>
      <link>https://dev.to/bastienbot/create-a-customer-support-chatbot-with-zendesk-and-csml-3412</link>
      <guid>https://dev.to/bastienbot/create-a-customer-support-chatbot-with-zendesk-and-csml-3412</guid>
      <description>&lt;p&gt;Customer support is &lt;strong&gt;key&lt;/strong&gt; to keep your existing customers, it is &lt;strong&gt;key&lt;/strong&gt; to maintain a good reputation, it is &lt;strong&gt;key&lt;/strong&gt; to acquire new customers.&lt;/p&gt;

&lt;p&gt;A great way to take care of customer support is to work with a ticketing service that takes care of &lt;strong&gt;tracking&lt;/strong&gt; the open tickets, helps you &lt;strong&gt;resolve&lt;/strong&gt; issues, and provides &lt;strong&gt;notifications&lt;/strong&gt;. We, at CSML, use Zendesk, it’s one of the most (if not the most) efficient product on the market, so we decided to make an integration to Zendesk for CSML.&lt;br&gt;
With this CSML integration, your chatbot can create a ticket on Zendesk on the fly. Let’s see how this work.&lt;/p&gt;
&lt;h2&gt;
  
  
  The chatbot
&lt;/h2&gt;

&lt;p&gt;The chatbot we’re going to build is an IT support chatbot, so let’s make a chatbot for the serie The &lt;a href="https://www.google.com/search?q=the+it+crowd"&gt;IT Crowd&lt;/a&gt;. We’ll call this chatbot &lt;strong&gt;RoyBot&lt;/strong&gt;.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NhGgR25G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/mv37bryyxksvc98scf7s.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NhGgR25G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/mv37bryyxksvc98scf7s.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is Roy, asking the same question over and over again 👨‍💻&lt;br&gt;
The goal of this chatbot is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;to handle all incoming support requests&lt;/li&gt;
&lt;li&gt;ask the question that Roy asks 100% of the time: “Have you tried turning it off and on again?”
Asking this question over 50% of the IT support enquiries.&lt;/li&gt;
&lt;li&gt;create a ticket on Zendesk if the user has already restarted his computer.
Note that this chatbot will be coded with &lt;a href="https://www.csml.dev/?utm_source=medium&amp;amp;utm_medium=article&amp;amp;utm_campaign=zendesk"&gt;CSML&lt;/a&gt; on its free development Studio.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Step 1: Build the chatbot base
&lt;/h2&gt;

&lt;p&gt;Let’s code the chatbot base, for now let’s just ask to the user the question that Roy asks all day long, only we’ll be a bit more polite than Roy.&lt;br&gt;
Here is the result, if you’re looking for the source code, it’s over here 👇&lt;a href="https://gist.github.com/bastienbot/39af60477f77bbd96e724c8e68fb64e0"&gt;https://gist.github.com/bastienbot/39af60477f77bbd96e724c8e68fb64e0&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PYuTgekr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/55t4xz6b2kp3gr1jsfx4.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PYuTgekr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/55t4xz6b2kp3gr1jsfx4.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Step2: Install the Zendesk app
&lt;/h2&gt;

&lt;p&gt;In the CSML development Studio, you can install “Apps”, they are connectors to third-party services. In this case, we’re going to install the Zendesk app.&lt;br&gt;
To install it, go to Functions &amp;gt; Apps directory.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oFffnKat--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/tsfiv55xinyfvglv7awf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oFffnKat--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/tsfiv55xinyfvglv7awf.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will need three informations in order complete the App installation: ZENDESK_URL, ZENDESK_EMAIL and ZENDESK_API_TOKEN.&lt;br&gt;
Let’s go find these.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step3: Get the url, email and token from Zendesk
&lt;/h2&gt;

&lt;p&gt;To get the API Token you will need to connect to Zendesk as administrator. Then go to: Admin &amp;gt; API, then you can &lt;strong&gt;create a token&lt;/strong&gt; under the section “Token Access”.&lt;br&gt;
The email is your &lt;strong&gt;account email&lt;/strong&gt;, and the url is the first part of the dashboard url as follows: &lt;strong&gt;&lt;a href="https://my-company.zendesk.com"&gt;https://my-company.zendesk.com&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;Make sure you don’t keep the trailing slash at the end.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Step4: Time to finish the bot
&lt;/h2&gt;

&lt;p&gt;Now that we have the App successfully installed, we only need to write a single line of code (line 43) to get the chatbot to create tickets on the go.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Whenever a user confirms having turned his device off and on again, the chatbot asks the user to describe the issue, remembers it and uses this information to create a Zendesk ticket &lt;strong&gt;on its own&lt;/strong&gt;.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--J6HVqhbp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/59v11s7wz46tmcu9yv3i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--J6HVqhbp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/59v11s7wz46tmcu9yv3i.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s next?
&lt;/h2&gt;

&lt;p&gt;Depending on your business, there are a few ways to improve a customer support chatbot:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adding a &lt;strong&gt;QnA NLP base&lt;/strong&gt;, the user can ask questions to the chatbot using natural language, the chatbot can then answer frequently asked questions and forward the question to Zendesk if no suitable answer exists (exemple: &lt;a href="https://www.clevy.io"&gt;Clevy&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Adding more chatbot flows for to help the user resolving the issue on his own. In fact, &lt;strong&gt;Apple as well as many other companies&lt;/strong&gt; provides this service before opening a ticket.&lt;/li&gt;
&lt;li&gt;Asking more questions to the user in order to have &lt;strong&gt;as many informations as possible&lt;/strong&gt; when creating the ticket. The agent in charge of resolving the ticket won’t have to ask them later.&lt;/li&gt;
&lt;li&gt;Get the user to &lt;strong&gt;upload a file&lt;/strong&gt; (a screenshot for instance) that the chatbot will attach to the ticket.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With all these features, Roy can be no other than a happy man 😎.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--h2YJtUq0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8e32d8vz8a55ycpbdxiv.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--h2YJtUq0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8e32d8vz8a55ycpbdxiv.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>csml</category>
      <category>chatbot</category>
      <category>bot</category>
    </item>
    <item>
      <title>Optimize your chatbot with Google Analytics</title>
      <dc:creator>Bastien Botella</dc:creator>
      <pubDate>Mon, 03 Aug 2020 10:45:36 +0000</pubDate>
      <link>https://dev.to/bastienbot/optimize-your-chatbot-with-google-analytics-dej</link>
      <guid>https://dev.to/bastienbot/optimize-your-chatbot-with-google-analytics-dej</guid>
      <description>&lt;p&gt;The &lt;strong&gt;golden rule&lt;/strong&gt; when creating any kind of online service is to monitor its &lt;strong&gt;activity&lt;/strong&gt; through analytics. Any business needs analytics, they are helping leaders take decisions, increase revenues, optimize processes among other things.&lt;/p&gt;

&lt;p&gt;Chatbots are no exceptions to this rule and they also need their data to be analysed in order to improve. Right now, any chatbot company provides data like the number of messages sent and received, number of users, etc… and this is great to measure the chatbot activity on a macro level, but more often than not, chatbot creators also need some use-case oriented analytics, like a &lt;strong&gt;conversion funnel&lt;/strong&gt; for a &lt;strong&gt;newsletter signup chatbot&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Google Analytics for chatbots
&lt;/h3&gt;

&lt;p&gt;Google Analytics is a very powerful tool that pretty much everybody has used in the past. Most people know it as a service that provides analytics about the audience behaviour on a website, but it can also be used with chatbots, and in this case to create a funnel.&lt;/p&gt;

&lt;h2&gt;
  
  
  The overall mechanism
&lt;/h2&gt;

&lt;p&gt;In order to create a funnel, we’ll need the chatbot to send:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A starting event&lt;/strong&gt;: the user starts the flow&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Events throughout the flows&lt;/strong&gt;, very much like checkpoints, that will show us when a user drops
&lt;strong&gt;An ending event&lt;/strong&gt;: the user subscribed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All these events must be sent to Google Analytics.&lt;/p&gt;

&lt;p&gt;Let’s see how that works with &lt;a href="https://www.csml.dev?utm_source=dev.to&amp;amp;utm_medium=article&amp;amp;utm_campaign=ganalytics"&gt;CSML&lt;/a&gt; using &lt;a href="https://studio.csml.dev?utm_source=dev.to&amp;amp;utm_medium=article&amp;amp;utm_campaign=ganalytics"&gt;the development studio&lt;/a&gt;.&lt;br&gt;
&lt;em&gt;In the example below, we’ll assume you’ve created a free account on the studio.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 1: the chatbot
&lt;/h2&gt;

&lt;p&gt;Let’s create a simple newsletter signup chatbot, only three questions in three different steps that eventually trigger a Zapier event to register the user.&lt;/p&gt;

&lt;p&gt;Right now this chatbot is not yet linked to Google Analytics but at least we know what it’ll look like.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="nx"&gt;say&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hi, let's subscribe to an awesome newsletter 💌 !&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="c1"&gt;// Starting event should go here&lt;/span&gt;
  &lt;span class="nx"&gt;goto&lt;/span&gt; &lt;span class="nx"&gt;firstname&lt;/span&gt;

&lt;span class="nx"&gt;firstname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="nx"&gt;say&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;What's your firstname?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;hold&lt;/span&gt;
  &lt;span class="nx"&gt;remember&lt;/span&gt; &lt;span class="nx"&gt;firstname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;
  &lt;span class="c1"&gt;// First flow event&lt;/span&gt;
  &lt;span class="nx"&gt;goto&lt;/span&gt; &lt;span class="nx"&gt;lastname&lt;/span&gt;

&lt;span class="nx"&gt;lastname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="nx"&gt;say&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;What's your lastname?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;hold&lt;/span&gt;
  &lt;span class="nx"&gt;remember&lt;/span&gt; &lt;span class="nx"&gt;lastname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;
  &lt;span class="c1"&gt;// Second flow event&lt;/span&gt;
  &lt;span class="nx"&gt;goto&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;

&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="nx"&gt;say&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;What's your email address?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;hold&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;say&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Please enter a valid email address&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="nx"&gt;goto&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;remember&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;
  &lt;span class="c1"&gt;// Third flow event&lt;/span&gt;
  &lt;span class="nx"&gt;goto&lt;/span&gt; &lt;span class="nx"&gt;save&lt;/span&gt;

&lt;span class="nx"&gt;save&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nx"&gt;Fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;zapier&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;hook&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;myhook/myhookid&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;firstname&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;firstname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lastname&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;lastname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;say&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Ok **{{firstname}} {{lastname}}**, I have registered your email **{{email}}** to our newsletter!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;say&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Enjoy the great content 🎉&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="c1"&gt;// Ending event&lt;/span&gt;
  &lt;span class="nx"&gt;goto&lt;/span&gt; &lt;span class="nx"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Setting up Google Analytics
&lt;/h2&gt;

&lt;h3&gt;
  
  
  a. Get the Google Analytics Property ID
&lt;/h3&gt;

&lt;p&gt;First of all you will obviously need a Google Analytics account. You can then either use an existing property (website account), or create one. To go forward, you will only need the property ID that looks like “UA-xxxxxxx-x”.&lt;br&gt;
To find this ID, open Google Analytics, go to “Admin” at the bottom left of the screen, then click on “Property settings”, you’ll then see the ID under “Tracking ID”.&lt;/p&gt;
&lt;h3&gt;
  
  
  b. Setup the Google analytics App
&lt;/h3&gt;

&lt;p&gt;Now we need to connect the chatbot to Google Analytics. In order to do so, you can use the Google Analytics App in the Studio, you’ll just need to provide your Google Analytics &lt;strong&gt;property ID&lt;/strong&gt; (UA-xxxxxxx-x) when you setup the app.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uVmj7lat--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/o0vkpm2gey2ut43agwzp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uVmj7lat--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/o0vkpm2gey2ut43agwzp.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  c. Setup the Uuid App
&lt;/h3&gt;

&lt;p&gt;Since you want Google analytics to be able to track sessions, you’ll need to provide a &lt;strong&gt;unique ID&lt;/strong&gt; per user. Luckily, there is an app for that : uuid. Go to the app store and set it up.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GXARczVq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/fljgnqfw8lffkpwn343c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GXARczVq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/fljgnqfw8lffkpwn343c.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 3: Get the chatbot to send the events at the right time
&lt;/h2&gt;

&lt;p&gt;Remember the code we wrote earlier ? We’re going to edit it as follow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adding a unique id for each new user&lt;/li&gt;
&lt;li&gt;Adding the events checkpoints&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;// If the user doesn't exist, we create a new id using the uuid app&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;remember&lt;/span&gt; &lt;span class="nx"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;utils/uuid&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;v4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;say&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hi, let's subscribe to an awesome newsletter 💌 !&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nx"&gt;Fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;google/analytics&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;user_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;category&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;csml_nl_chatbot&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flow_process&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;start&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;goto&lt;/span&gt; &lt;span class="nx"&gt;firstname&lt;/span&gt;

&lt;span class="nx"&gt;firstname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="nx"&gt;say&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;What's your firstname?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;hold&lt;/span&gt;
  &lt;span class="nx"&gt;remember&lt;/span&gt; &lt;span class="nx"&gt;firstname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;
  &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nx"&gt;Fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;google/analytics&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;user_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;category&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;csml_nl_chatbot&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flow_process&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;firstname&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;goto&lt;/span&gt; &lt;span class="nx"&gt;lastname&lt;/span&gt;

&lt;span class="nx"&gt;lastname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="nx"&gt;say&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;What's your lastname?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;hold&lt;/span&gt;
  &lt;span class="nx"&gt;remember&lt;/span&gt; &lt;span class="nx"&gt;lastname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;
  &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nx"&gt;Fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;google/analytics&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;user_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;category&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;csml_nl_chatbot&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flow_process&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lastname&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;goto&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;

&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="nx"&gt;say&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;What's your email address?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;hold&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;say&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Please enter a valid email address&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="nx"&gt;goto&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;remember&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;
  &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nx"&gt;Fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;google/analytics&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;user_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;category&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;csml_nl_chatbot&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flow_process&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;firstname&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;goto&lt;/span&gt; &lt;span class="nx"&gt;save&lt;/span&gt;

&lt;span class="nx"&gt;save&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nx"&gt;Fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;zapier&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;hook&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;myhook/myhookid&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;firstname&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;firstname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lastname&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;lastname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;say&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Ok **{{firstname}} {{lastname}}**, I have registered your email **{{email}}** to our newsletter!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;say&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Enjoy the great content 🎉&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nx"&gt;Fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;google/analytics&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;category&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;csml_nl_chatbot&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flow_process&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;end&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;goto&lt;/span&gt; &lt;span class="nx"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As you can see, we create “checkpoints” throughout the flow, every time a user reaches one of these checkpoints, an event will be sent to Google Analytics.&lt;/p&gt;

&lt;p&gt;Now if you try it out, you should see something that looks like the screenshot below.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bV6C9uSa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/g9acjib6ungl5t575ifv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bV6C9uSa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/g9acjib6ungl5t575ifv.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: The funnel!
&lt;/h2&gt;

&lt;p&gt;It’s hard to believe, but the funnel is ready…you only need to wait for Google Analytics to update it. Updates happen the next day, so once you see the events in the “Realtime &amp;gt; Events” menu, just wait 24 hours and then go to “Behavior &amp;gt; Events &amp;gt; Events flow”, and you’ll should see the funnel below!&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gSvsEQST--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/jofv0tocffcjtg82kik5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gSvsEQST--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/jofv0tocffcjtg82kik5.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s it, you’re now ready to analyse and optimize your chatbots.&lt;/p&gt;

&lt;p&gt;Here are a few ideas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You could perform AB testing by creating two steps doing the same thing and randomly sending the users to one step or the other. Each of these two steps would send different labels to Google Analytics, you would then be able to check which step performs best.&lt;/li&gt;
&lt;li&gt;In the example above, you could send an event to Google Analytics if the users enter an invalid email address, then you would be able to see how many users drop after entering an invalid email address.&lt;/li&gt;
&lt;li&gt;You could also ask more information to the users if your funnel shows very low drop rate.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I am sure there are tons of possible optimizations, what would be the first optimization on your list? Share it in the comments!&lt;/p&gt;

&lt;p&gt;For more informations about CSML, visit &lt;a href="https://www.csml.dev/?utm_source=dev.to&amp;amp;utm_medium=article&amp;amp;utm_campaign=ganalytics"&gt;csml.dev&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>chatbot</category>
      <category>csml</category>
      <category>startup</category>
    </item>
  </channel>
</rss>
