Documentation |

The Developer Hub

Welcome to the Apperyio developer hub. You'll find comprehensive guides and documentation to help you start working with apperyio as quickly as possible, as well as support if you get stuck. Let's jump right in!


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 console

  1. In the left menu, click New Agent > Create new 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 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

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 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 intent

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

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

  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 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 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 accounts

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

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

  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 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 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

  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 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 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 body

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

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 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 fulfillment

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

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 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 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 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 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 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 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 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 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 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 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 Type

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

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 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 section 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 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 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 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 section 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 section:

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 app

Updated 17 days ago

Ionic 4 Chatbot App using Dialogflow

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

Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.