For any Freshworks product that allows its users to automate their workflows, developers can now define their custom logic amidst this workflow. We call it Custom Actions. This feature will allow the app to be the central component of Action defined by the user.

Typical examples of custom actions in the workflow are,

Freshcaller has Call Workflows built-in for users to automate tasks by interconnecting actions. Automating Call Routing is something we are going to look at today. We will accomplish this by defining custom actions that are suitable to each use case.

  1. Handle VIP customers - to route the call quickly to relevant teams. For example, it would be a great use in a case where a premium customer would like to connect the live agent without going through IVR and waiting time.
  2. Return dynamic response - to answer the customer queries. For example, a customer can know about the transition status of the ordered e-commerce item without needing to go through IVR or connect to an agent.
  1. Freshworks CLI installed
  2. A Freshcaller Trial Account signed up. Use the assistance catalog to extend the trial and phone credits further if needed.
  3. The starter code (see Setting Up section)

Run the following command to create a boilerplate serverless app.

fdk create --products freshcaller --template your_first_serverless_app

The project files required for the serverless app are created. For more information, refer to the documentation. Let's start defining the actions that need to be performed.

The actions that can be included as part of an automated workflow must be defined as an action in the actions.json file. The action names are keys to callback functions.

  1. Navigate to the home directory of your project and create a new file with the name, actions.json. The file content must follow the JSON schema.
  2. In the actions.json file, define the validateVIPPhoneNumber and respondOrderStatus actions and the corresponding attributes. Refer to the documentation for the format. For now, you can copy and paste the following code into the file.

actions.json

{
 "validateVIPPhoneNumber": {
   "display_name": "validate VIP users based on phone numbers",
   "description": "Validates if the input phone number is in the VIP list of contacts",
   "parameters": {
     "$schema": "http://json-schema.org/draft-07/schema#",
     "type": "object",
     "properties": {
       "input": {
         "type": "string"
       }
     },
     "required": [
       "input"
     ]
   },
   "response": {
     "type": "string"
   }
 },
 "respondOrderStatus": {
   "display_name": "to send the message to be played as a dynamic message in Freshcaller",
   "description": "Responds with the order status from third-party system",
   "parameters": {
     "$schema": "http://json-schema.org/draft-07/schema#",
     "type": "object",
     "properties": {
       "input": {
         "type": "string"
       }
     },
     "required": [
       "input"
     ]
   },
   "response": {
     "type": "string"
   }
 }
}

We have listed two properties in the actions.json file.

Each property is a description of inputs and outputs of a serverless callback that we will define in our app.

When the user configures these properties as part of Call Workflows within Freshcaller, the callback defined within the "server.js" is invoked.

Navigate to the "server.js" file and define the callback functions corresponding to the actions defined in the actions.json file.

As an acknowledgment of the automated workflow, the actions should return a result. In the server.js file, use the renderData() method to return the result of the callback function to the workflow from where the function is triggered, through actions. If the callback function succeeds, it returns a response data object as the second argument of the renderData() callback. Otherwise, it returns an error object with a status and message as the first argument of the renderData() callback.

In the callback functions, we will do the following operation before returning the results.

validateVIPPhoneNumber

This function will validate if the incoming phone number is a VIP number and return the result if it's valid or invalid.

respondOrderStatus

This function will validate if the appropriate product is chosen from IVR and return an error if proper input is not received.

Upon receiving the right product input, it will return the status of the respective product. In our case, we will always send it as "in progress".

Use the following code to define these functions in the "server.js" file.

server.js

exports = {
validateVIPPhoneNumber: function (request) {
   let validVIPNumbers = ['+15684561239','+12587419632'],
   response = validVIPNumbers.includes(request.input) ? 'valid': 'invalid',
   data = {
     response,
     "app_variables": {}
   };

   return renderData(null, { data });
 },
 respondOrderStatus: function (request) {
   const productIndex = request.input
   const productName = ['Freshcaller', "Freshdesk", "Freshsales", "Freshchat", "Freshservice"];

   if (productName(productName) === -1) {
     const error = { status: 404, message: "The selected product is not found. Choose a valid product." };
     return renderData(error)
   }
   return renderData(null, {
     success: true, data: {
       response: request.input, "app_variables": { "name": productName[productIndex], status: "in progress" }
     }
   });
 }
}

After your app is published and integrated with Freshcaller, when you design a Call Workflow using the routing automation, the custom actions configured in the app are listed as functions when the app is selected.

We will test the custom actions separately by simulating the actions and check the actual results from the app with the expected results.

You can simulate a workflow trigger and test your app from the testing page (http://localhost:10001/web/test).

  1. Run the fdk run command. A message with the test URL is displayed.
  2. To initiate the workflow actions from the testing page, navigate to the test URL from your browser.
  3. From the "Select type" drop-down field, select actions. The actions defined in the actions.json file are displayed in the Select action drop-down list.
  4. To test the workflow, select an action. The payload JSON is displayed.
  5. Click Simulate to trigger the appropriate callback function.

Positive : Note: You can modify the payload values before clicking on the Simulate button to validate the app thoroughly. You can test the app with various test scenarios such as, adding a user whose account does not exist, adding a user to an organization that does not exist, and so on.

For more information on how to test the workflow actions, refer to the documentation related to testing.

Testing in production

Yes, we all want to test the app once in production to make sure everything works when the environment changes. Also, this app requires configuration in Freshcaller to make the app work coordinated.

alt_text

We are not going to cover the steps required to configure the workflow in Freshcaller. To test in a production environment by publishing the app as a custom app, configure the workflow in Freshcaller to run custom actions from a custom app.

We have learned to use custom actions in Routing Automation to automate some of the mundane tasks that would usually take valuable time and efforts of agents working at the other end of the user.

Here's what we learned in this tutorial,

See the final source code of the app.

If you are excited to use custom actions to automate certain tasks, play with the same app to achieve different things.