Ionic 4 Chatbot App using Dialogflow

How to build the sample Ionic 4 Chatbot app using and Dialogflow.


This sample app provides step by step instructions that will walk you through the process of creating the Chatbot application with the help of Dialogflow.

The tutorial is divided into two parts: setting up the Dialogflow service (part 1) and creating the Ionic 4 app with defining its logic (part 2). You should complete the first part first and then move to the second part.

Target Audience

This sample app tutorial is intended for advanced developers who have prior experience building apps with
But as an alternative, you can also try this app by creating it from the backup:

  1. Download the app backup file.
  2. Click Create new app.
  3. Type in the app name.
  4. Click From backup and select the project backup file on your drive.
  5. Click Create.

Dialogflow Setup

Dialogflow is a natural language processing (NLP) platform that provides services for chatbots and makes it easy to create and integrate a conversational user interface into your mobile app, web app, chatbot, etc.

Dialogflow can analyze different types of input from your customers (including text and audio input) and respond to them.

Dialogflow compares the user's phrase in a natural language with some "non-linguistic" value (called intent) and then provides an answer. In addition, it can hold the context of the dialog, so that the following phrase can take into account the conversation context.

For more information about the platform, visit the Dialogflow docs page.

Creating Agent

Let's start with setting up Dialogflow and building a simple Agent. You can think of an Agent as a call center operator that can react to user phrases and fulfill user intentions.

  1. First, go to the Dialogflow website and sign up using your Google account.
  2. After logging in, click the Go to console link in the top-right screen corner:
Dialogflow consoleDialogflow console

Dialogflow console

  1. In the left menu, click New Agent > Create new agent:
Creating new Dialogflow AgentCreating new Dialogflow Agent

Creating new Dialogflow Agent

  1. Enter your agent name, for example, ApperyAgent.

  2. In the GOOGLE PROJECT section, select Create new Google project or choose any other existing Google project for import. Make sure that billing is enabled for the project.

Creating new Google projectCreating new Google project

Creating new Google project

  1. Click the Create button in the top-right corner.

That's it, now our agent is created and ready for further adjustments.

Setting up Agent

Default Intents

Intents are used to handle specific requests from a user. In simple terms, if a user says A, we want our Chatbot to respond with B.

Let's go to the Intents tab. After creating an agent, there will be two default intents here:

  1. The Default Welcome Intent, that is called in case a user begins a conversation with your agent. It should welcome a user and return a response that helps him understand what the agent does or what to say to start a conversation.
  2. The Default Fallback Intent, that is called when the agent cannot recognize user input.
**Intents** tab**Intents** tab

Intents tab

Let's modify the Default Welcome Intent responses to provide more information about the Chatbot. Change default responses text as shown in the screenshot below and click the SAVE button on the top panel:

Modifying **Default Welcome Intent** responsesModifying **Default Welcome Intent** responses

Modifying Default Welcome Intent responses

Creating Custom Intent

Our app should be able to correctly respond to "What is the weather in ..." requests for any city.
So, we need a way to get the city name from a user's message, get the weather forecast, and then send a reply to this user. To do it, let's use a custom intent.

  1. To create an intent, in the left menu, click the + button located next to the Intents button.
    Let's name our new intent Detect location.

  2. Also, to provide some sample user phrases, click the ADD TRAINING PHRASES button under the Training phrases tab:

Creating custom intentCreating custom intent

Creating custom intent

  1. Type some training phrases here as shown in the screenshot:
Adding training phrasesAdding training phrases

Adding training phrases


As you can see, the city names are highlighted in yellow.
To do this manually, highlight the city names with the cursor and mark it as @sys.geo-city — the predefined entity for cities.

  1. Then, under the Action and parameters tab, make geo-city a required parameter:
**Action and parameters** tab**Action and parameters** tab

Action and parameters tab

  1. Add the default response under the Response tab. The Chatbot will use it in case, for some reason, the weather for the city cannot be received:
Default responseDefault response

Default response

  1. And, finally, we need to enable fulfillment for this intent. It is needed for the integration of our custom backend script that receives a city from the intent and returns weather information. Under the Fulfillment tab, click the ENABLE FULFILLMENT button and then check the box next to Enable webhook call for this intent, as shown below:
Enabling fulfillmentEnabling fulfillment

Enabling fulfillment

Don't forget to save all the changes by clicking the SAVE button at the page top.

Getting Google Service Account Key

To use a chatbot created outside the Google Cloud Console, we need to get a service key. It will give us the possibility to make authorized API calls.

  1. Go to the Google Console.
  2. From the left menu, select IAM & admin > Service accounts:
Service accountsService accounts

Service accounts

  1. In the header, select ApperyAgent, the project created by Dialogflow:
Selecting ***ApperyAgent*** projectSelecting ***ApperyAgent*** project

Selecting ApperyAgent project

  1. In the list of service accounts, select the new-generated service account email, the one named Dialogflow Integrations. You should see the service account details:
***Dialogflow Integrations*** service account details***Dialogflow Integrations*** service account details

Dialogflow Integrations service account details

  1. In the service account details section, click the Edit button. Now, you'll see that the CREATE KEY button at the bottom becomes enabled.
  2. Click the CREATE KEY button to generate a service account key.
  3. In the pop-up window, choose JSON key type and click CREATE:
Creating a keyCreating a key

Creating a key

  1. Save the generated JSON file on your local machine. Afterward, click the Save button in the service account details page to save all the changes.

Loading Required Dependency

Interacting with the Dialogflow API V2 requires authentication by service account.

To authenticate using generated keys of our service account, we will use the JSON Web Token approach to generate an access token. For more details, please see this Wiki article.

Creating Server Code Libraries

Creating Dialogflow Settings

  1. Login to and go to the Server Code section.
  2. Click the Create library button in the Libraries section.
  3. Enter DialogflowSettings for the name of a new script.
  4. In the code editor, paste the following JavaScript code:
(function(context) {
    // Data from the JSON file generated from your Google Service Account
  // Base url of Dialogflow V2 API
  var DF_API_BASE_URL = "";
  // Session alias
  var DF_SESSION_ALIAS = "/projects/" + DF_ACCOUNT_KEYS.project_id + "/agent/sessions/"+ new Date().getTime();
  return context;
  1. Note that the DF_ACCOUNT_KEYS constant value should be the same as the JSON which was downloaded in steps 7-8 of the Getting Google service account keys part of this tutorial:
Dialogflow SettingsDialogflow Settings

Dialogflow Settings

  1. Click Save and then test for syntax errors in your code by clicking the Test button at the bottom of the script editor.

Creating Dialogflow Auth Manager

  1. From the dashboard, go to the Server Code section.
  2. Click the Create library button in the Libraries section.
  3. Enter DialogflowAuthManager for the name of a new script.
  4. In the code editor, paste the following JavaScript code:
(function(context) {
  var manager = {
    getAccessToken: generateToken
  var b64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  var b64pad = "=";
  function generateToken() {
    // Header
    const header = {
      alg: 'RS256',
      typ: 'JWT',
      kid: DF_ACCOUNT_KEYS.private_key_id
    // Payload
    const payload = {
      iss: DF_ACCOUNT_KEYS.client_email,
      sub: DF_ACCOUNT_KEYS.client_email,
      iat: getTime('now'),
      exp: getTime('now + 1hour'),
      aud: ''
    const stringHeader = JSON.stringify(header);
    const stringPayload = JSON.stringify(payload);
    const uHeader = utf8tob64u(stringHeader);
    const uPayload = utf8tob64u(stringPayload);
    const uSignatureInput = uHeader + "." + uPayload;
    const token = Apperyio.Crypto.sign(uSignatureInput, DF_ACCOUNT_KEYS.private_key, 'SHA256withRSA');
    return uSignatureInput + '.' + token;
  function utf8tob64u(s) {
    return hextob64u(uricmptohex(encodeURIComponentAll(s)));
  function hextob64u(s) {
    if (s.length % 2 == 1) s = "0" + s;
    return b64tob64u(hex2b64(s));
  function uricmptohex(s) {
    return s.replace(/%/g, "");
  function encodeURIComponentAll(u8) {
    var s = encodeURIComponent(u8);
    var s2 = "";
    for (var i = 0; i < s.length; i++) {
      if (s[i] == "%") {
        s2 = s2 + s.substr(i, 3);
        i = i + 2;
      } else {
        s2 = s2 + "%" + stohex(s[i]);
    return s2;
  function stohex(s) {
    return BAtohex(stoBA(s));
  function BAtohex(a) {
    var s = "";
    for (var i = 0; i < a.length; i++) {
      var hex1 = a[i].toString(16);
      if (hex1.length == 1) hex1 = "0" + hex1;
      s = s + hex1;
    return s;
  function stoBA(s) {
    var a = new Array();
    for (var i = 0; i < s.length; i++) {
      a[i] = s.charCodeAt(i);
    return a;
  function b64tob64u(s) {
    s = s.replace(/\=/g, "");
    s = s.replace(/\+/g, "-");
    s = s.replace(/\//g, "_");
    return s;
  function hex2b64(h) {
    var i;
    var c;
    var ret = "";
    for (i = 0; i + 3 <= h.length; i += 3) {
      c = parseInt(h.substring(i, i + 3), 16);
      ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63);
    if (i + 1 == h.length) {
      c = parseInt(h.substring(i, i + 1), 16);
      ret += b64map.charAt(c << 2);
    } else if (i + 2 == h.length) {
      c = parseInt(h.substring(i, i + 2), 16);
      ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4);
    if (b64pad)
      while ((ret.length & 3) > 0) ret += b64pad;
    return ret;
  function getTime(s) {
    if (s == "now") {
      return getNow();
    } else if (s == "now + 1hour") {
      return getNow() + 60 * 60;
    } else if (s == "now + 1day") {
      return getNow() + 60 * 60 * 24;
    } else if (s == "now + 1month") {
      return getNow() + 60 * 60 * 24 * 30;
    } else if (s == "now + 1year") {
      return getNow() + 60 * 60 * 24 * 365;
    } else if (s.match(/^[0-9]+$/)) {
      return parseInt(s);
    throw "unsupported format: " + s;
  function getNow() {
    var d = ~~(new Date() / 1000);
    return d;
  context.dfManager = manager;
  1. Open the Dependencies tab and select the DialogflowSettings script:
**Dependencies** tab**Dependencies** tab

Dependencies tab

  1. Then, go back to the Library tab and click Save.
  2. Finally, test your code for syntax errors by clicking the Test button at the bottom of the script editor:
Testing libraryTesting library

Testing library

Creating Server Code for Integration with Dialogflow API V2

  1. From the dashboard, go to the Server Code section.
  2. Click the Create script button.
  3. Enter getChatBotResponse for the name of a new script. Then, click Save.
  4. Open the Dependencies tab and select the following scripts:
Selecting scriptsSelecting scripts

Selecting scripts

  1. Go back to the Script tab. Paste the following JavaScript code in the code editor:
try {
  var requestBody = JSON.parse(request.body());
  var message = requestBody.message || '';
  var language = 'en-US';
  var token = dfManager.getAccessToken();
  if (token) {
    var apiResult = getDetectIntentResult(token, message, language);
    response.success(apiResult, 'application/json');
  } else {
    throw new Error('Failed to retrieve access token.');
} catch (err) {
    'error': err.message,
    'message': 'serverCode getChatBotResponse execution failed.'
  }, 400);

function getDetectIntentResult(token, message, language) {
  var apiResponse = detectIntent(token, message, language);
  if (apiResponse.status === 200) {
    return JSON.parse(apiResponse.body);
  } else {
    throw new Error('Failed to request Dialogflow API.');

function detectIntent(token, message, language) {
  var url = DF_API_BASE_URL + DF_SESSION_ALIAS + ':detectIntent';
  var XHRResponse = XHR2.send('POST', url, {
    'headers': {
      'Authorization': 'Bearer ' + token,
      'Content-type': 'application/json'
    'body': {
      'queryInput': {
        'text': {
          'text': message,
          'languageCode': language
  return XHRResponse;
  1. Click the Save button to save all the changes.

Testing Integration

Let’s test integration with Dialogflow API V2.

  1. Go to the Script parameters tab.
  2. Select POST as the request method and JSON for MIME type.
  3. Type the following request body:
  "message": "Hello"
Request bodyRequest body

Request body

  1. Go to the Run tab and click Save and run. You will see the response from Dialogflow:
Test responseTest response

Test response

Getting Weather Information

We will use OpenWeatherMap API to get the current weather forecast based on a user query.


You can go through our Ionic 4 Weather App tutorial to get familiar with the API usage.

In fact, all you need for our Chatbot app is just to get the OpenWeatherMap API key and paste it into a sample script.

Obtaining OpenWeatherMap API Key

  1. Sign up for a free account to get an API key for using the service.
  2. Get your OpenWeatherMap API key.

Creating Server Code for Integration with OpenWeatherMap

  1. From the dashboard go to the Server Code section.
  2. Click the Create script button.
  3. Enter getWeather for the name of a new script.
  4. From your OpenWeatherMap dashboard, copy the API key you have just created.
  5. In the code editor, enter the following JavaScript code. Don't forget to replace the value of the OPENWEATHER_API_KEY constant with the just copied OpenWeatherMap API key:
try {
  const requestBody = JSON.parse(request.body());
  const city = requestBody.queryResult.parameters['geo-city'];
  const apiResult = getWeatherInfo(city);
  const weather = generateMessage(apiResult);
  response.success({ 'fulfillmentText': weather }, "application/json");
} catch (err) {
    'error': err.message,
    'message': 'serverCode getWeather execution failed.'
  }, 400);

function getWeatherInfo(city) {
  const url = '' + city + '&units=metric&appid=' + OPENWEATHER_API_KEY;
  const XHRResponse = XHR2.send('GET', url);
  return XHRResponse;

function generateMessage(res) {
  const text = JSON.parse(res.body);
  return `It is ${text.main.temp}° and ${[0].description} in ${}!`;
  1. Click the Save button.
  2. Finally, copy the script service URL to the clipboard by clicking the button next to it. We'll need this URL in the next step:
Script service URLScript service URL

Script service URL

Enabling Dialogflow Fulfillment

Now, the final touch. We need to add the getWeather script URL to the Dialogflow settings. Then Dialogflow will be able to send a request to our service with information about the matched intent.

  1. Go to the Dialogflow console. In the left menu, click the Fulfillment button:
Enabling Dialogflow fulfillmentEnabling Dialogflow fulfillment

Enabling Dialogflow fulfillment

  1. Enable Webhook and insert the getWeather script service URL into the URL field:
Enabling WebhookEnabling Webhook

Enabling Webhook

  1. Save all the changes by clicking the SAVE button at the bottom of the page.

Now, we can test our Chatbot — right here, on the right side of the Dialogflow console. Let's ask it about the weather in some city:

Testing ChatbotTesting Chatbot

Testing Chatbot

Congratulations, now we are ready to build the app UI!

App UI

Creating New App

  1. Navigate to the dashboard. Here, under the Apps tab, click Create new app.
  2. Select the Ionic 4 application type and Blank as a template. Let's name our app chatbotApp:
Creating new appCreating new app

Creating new app

  1. Click Create. You should see the default Screen1 page.

Creating App UI

  1. Open the CODE tab of the Screen1 page. Here, create two variables:
    • messages of Any type with [] default value;
    • myMessage of String type with no default value:
Defining variablesDefining variables

Defining variables

  1. On the current page, go to the DESIGN tab. Select the ToolbarTitle1 element and set its Text property value to Chat Bot:
Defining **ToolbarTitle** elementDefining **ToolbarTitle** element

Defining ToolbarTitle element

  1. Remove all the elements from the footer.
  2. Drag & drop an Input component from the PALETTE to the footer.
  3. In the PROPERTIES area of the created Input component, remove the label text. Update its placeholder value to Enter message. Also, add a new property [(ngModel)] with myMessage value:
Defining **Input** elementDefining **Input** element

Defining Input element

  1. Drag & drop a Button component to the app footer. Set the Expand property of the button to block and change the button's Text property to Send:
Defining **Button** elementDefining **Button** element

Defining Button element

  1. Drag & drop a new Text component to the content area with the default name Content1. Change its Container property to div and the Text property to {{ item.text }}.
  2. Also, add it a couple of properties:
    • *ngFor with let item of messages value;
    • [className] with item.answer && 'text-right' value:
Defining **Text** elementDefining **Text** element

Defining Text element

  1. We can also apply some styling. Open the SCSS tab and enter the following styles:
.text-right {
  text-align: right;
  margin: 8px 0;

The resulting app UI is simple:

Resulting app UIResulting app UI

Resulting app UI

App Logic

Now, let’s import the service that we created in the first part of our tutorial.

  1. Click the Create new button.
  2. Select Server code service from the dropdown menu.
  3. In the dropdown, choose the previously created getChatBotResponse server code script. Click the Import selected service button:
Importing Server code serviceImporting Server code service

Importing Server code service

  1. On the left side, expand the Services folder and select getChatBotResponse_service.
  2. Go to the Test service tab and click Test on the right.
  3. After testing is finished, you should get a response in the body section. Click the Import as response button to generate a mapping response model:
Importing responseImporting response

Importing response

  1. Go to the Response tab of the service. You will see that a response model for the mapping has been generated. Make sure the fulfillmentMessages property exists in the response model.
  2. Let’s update the request model of the service. Open the Settings tab and, in the Request Content Type field, select JSON:
Request Content TypeRequest Content Type

Request Content Type

  1. Go to the Request tab of the service. Add a new parameter and name it message:
Adding Request parameterAdding Request parameter

Adding Request parameter

  1. Now, we should define the newly created service on the Screen1 page. Open the DATA tab of the Screen1 page. For Add datasource, select Service and choose getChatBotResponse_service that we have just created. Click the Add button and change the name of the created instance to getChatBotResponse:
Adding datasourceAdding datasource

Adding datasource

  1. Now, let’s update the execution flow. Click the Add button of the Before send event and select Run TypeScript. As you can see, the EVENTS tab has been expanded from the bottom. Type the following script there:
this.messages.push({text: this.myMessage});
  1. Click the Save button. Also, let’s change the script execution order so that the script starts before the mapping. Drag the Run TypeScript block to the left, before the mapping block, as shown below:
Setting up script execution orderSetting up script execution order

Setting up script execution order

  1. Then, we should create a mapping for the request. Click the Mapping block in the Before send section. The visual mapping window will appear.
  2. Create the relation as shown in the screenshot below and click the Save & Replace button to save the Before send mapping:
Before send mappingBefore send mapping

Before send mapping

  1. Let’s proceed with mapping. Click the Mapping block in the Success section. Then. you'll need to create a relation between the response and the Screen1 page. Create it as shown n the screenshot:
Success mappingSuccess mapping

Success mapping

  1. Click the green TS button next to the messages variable. In the editor, paste the following code:
let oldMessages = this.messages;
const answer = {
  text: value[0].text.text[0],
  answer: true

this.myMessage = '';

return oldMessages;
  1. Click the Save button and then the Save & Replace button.
  2. To finish, we should execute the getChatBotResponse service. Go to the DESIGN section of the Screen1 page, select the Button1 component, and expand the EVENTS tab from the bottom.
  3. Both Button1 component and Click event are selected by default. Choose Invoke service in the Action dropdown. In the Datasource dropdown, choose getChatBotResponse. Then click the Save button in the EVENTS tab:
Send button click eventSend button click event

Send button click event

  1. Finally, click the Save button in the top menu to save all the app changes.

App Testing

Now we are ready to test our app. In the top menu, select the TEST button and choose the testing option you prefer.

When the app starts in the Web browser, just say Hello and ask the Chatbot about the weather in some city:

Testing the appTesting the app

Testing the app