### Store Installation Parameters with postConfigs Source: https://developers.freshworks.com/docs/app-sdk/v2.3/freshdesk/app-settings/app-installation-page/custom-installation-page Use the `postConfigs` method in `iparams.html` to store installation parameter values when the user clicks 'Install'. Secure parameters can be marked using the `__meta.secure` array. ```javascript function postConfigs() { var requester={}; var deparment = []; var conditions = []; var api_key = jQuery("input[name=api_key]").val(); var first_name = jQuery("input[name=first_name]").val(); var last_name = jQuery("input[name=last_name]").val(); requester["first_name"] = first_name; requester["last_name"] = last_name; jQuery("#deparment option:selected").each(function(){ deparment.push(jQuery(this).val()); }); jQuery("input[name=\"condition\"]:checked").each(function(){ conditions.push(jQuery(this).val()); }); return { __meta: { secure: ["api_key"] }, api_key, requester, deparment: deparment, conditions: conditions } } ``` -------------------------------- ### Error Object Example for onAppInstall Source: https://developers.freshworks.com/docs/app-sdk/v2.3/freshdesk/serverless-apps/app-set-up-events Example of an error object used with renderData() to disallow app installation. ```javascript renderData({message: "Installation failed due to network error."}); ``` -------------------------------- ### Manage Dependencies in Freshservice Apps Source: https://developers.freshworks.com/docs/app-sdk/v2.3/freshservice/app-validation Ensure all declared dependencies are used and no undeclared dependencies are imported. This example shows a correct manifest.json and server.js setup. ```json { "platform-version": "2.3", "product": { "freshservice": { "events": { "onTicketCreate": { "handler": "onTicketCreateHandler" } } } }, "engines": { "node": "18.17.1", "fdk": "9.0.4" }, "dependencies": { "lodash": "4.0.0" } } ``` ```javascript var _ = require('lodash'); exports = { events: [ { event: 'onTicketCreate', callback: 'onTicketCreateHandler' }, ], onTicketCreateHandler: function (args) { console.log('Hello ' + args['data']['requester']['name']); // Some logic with lodash } }; ``` -------------------------------- ### Example Folder Update Changes Source: https://developers.freshworks.com/docs/app-sdk/v2.3/freshdesk/serverless-apps/product-events/onfolder An example demonstrating the 'changes' object for the onFolderUpdate event, showing specific modifications to folder attributes like 'name' and 'updated_at'. ```json "changes": { "misc_changes": {}, "model_changes": { "name": [ "FAQs", "Frequently Asked Questions" ], "updated_at": [ "2021-10-29T13:46:04Z", "2021-10-29T13:46:14Z" ], }, "system_changes": {} } ``` -------------------------------- ### Retrieve Installation Parameters with getConfigs Source: https://developers.freshworks.com/docs/app-sdk/v2.3/freshdesk/app-settings/app-installation-page/custom-installation-page Include the `getConfigs` method in `iparams.html` to retrieve and populate stored installation parameter values on the Edit Settings page. This method is triggered when the 'Settings' menu button is clicked. ```javascript function getConfigs(configs) { jQuery("input[name=first_name]").val(configs["first_name"]); jQuery("input[name=last_name]").val(configs["last_name"]); for(var i= 0; i < configs.department.length; i++ ) { jQuery("#department option[value=" + configs.department[i] + "]").attr("selected",true); } jQuery("#department").select2(); if(configs.conditions) { jQuery("input[name=\"condition\"]").attr("checked",false); for(var a= 0; a < configs.conditions.length; a++ ) { jQuery("input[name=\"condition\"][value="+ configs.conditions[a]+"]").attr("checked",true); } } } ``` -------------------------------- ### Accessing Secure Installation Parameters Source: https://developers.freshworks.com/docs/app-sdk/v2.3/freshdesk/app-review/code-review-guidelines Demonstrates how to securely access installation parameters (iparams) in the front end using the Request method. This method should be used for sensitive data. ```javascript client.request.invoke("GET", { url: encodeURI("{{product_url}}/api/v2/users?query=(email='{{email}}')"), headers: { "Authorization": "Zoho-oauthtoken {{secure_token}}" } }).then(function(data) { console.log(data); }, function(err) { console.error(err); }); ``` -------------------------------- ### Code Coverage Summary Example Source: https://developers.freshworks.com/docs/app-sdk/v2.3/freshdesk/basic-dev-tools/freshworks-cli This is an example of a code coverage summary displayed after testing an app with 'fdk run'. It shows the percentage of code covered by tests, which is important for app review. ```text ========= Coverage summary ========== Statements : 98.18% ( 54/55 ) Branches : 100% ( 4/4 ) Functions : 84.62% ( 22/26 ) Lines : 98.18% ( 54/55 ) ====================================== ``` -------------------------------- ### Sample Manifest.json Configuration Source: https://developers.freshworks.com/docs/app-sdk/v2.3/freshdesk/serverless-apps/app-manifest An example of a complete manifest.json file, demonstrating the structure for platform version, product events and requests, engine versions, and dependencies. ```json { "platform-version": "2.3", "product": { "freshdesk": { "events": { "onTicketCreate": { "handler": "onTicketCreateHandler" }, "onExternalEvent": { "handler": "onExternalEventHandler" } }, "requests": { "createTicket": {}, "getTickets": {} } } }, "engines": { "node": "18.17.1", "fdk": "9.0.4" }, "dependencies": { "nodemon": "1.14.12" } } ``` -------------------------------- ### Configure onAppInstall Event - Success Source: https://developers.freshworks.com/docs/app-sdk/v2.3/freshdesk/serverless-apps/app-set-up-events Callback function to allow app installation completion. Use renderData() without arguments for success. ```javascript exports = { onAppInstallCallback: function(payload) { console.log("Logging arguments from onAppInstallevent: " + JSON.stringify(payload)); // If the setup is successful renderData(); } } ``` -------------------------------- ### OAuth Configuration without iparams Source: https://developers.freshworks.com/docs/app-sdk/v2.3/freshdesk/advanced-interfaces/request-method/oauth Example of an OAuth configuration file without using installation parameters (iparams). This configuration is used to set up access to OAuth-secured resources. ```json { "client_id": "1aXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXc8d1", "client_secret": "q8NbXXXXXXXXXXXXXXXX1p1", "authorize_url": "https://login.domain.com/authorize.srf", "token_url": "https://login.domain.com/token.srf", "options": { "scope": "read" }, "token_type": "account" } ``` -------------------------------- ### Retrieve all iparams using client.iparams.get() Source: https://developers.freshworks.com/docs/app-sdk/v2.3/freshdesk/app-settings/app-installation-page/installation-page Sample code to retrieve all configured installation parameters (excluding secure ones) using the client.iparams.get() method. ```javascript client.iparams.get().then ( function(data) { // success output // "data" is returned with the list of all the iparams }, function(error) { console.log(error); // failure operation } ); ``` -------------------------------- ### Example: Hide lastname if firstname is entered Source: https://developers.freshworks.com/docs/app-sdk/v2.3/freshdesk/app-settings/app-installation-page/installation-page Demonstrates hiding the 'lastname' iparam from the installation page when the 'firstname' iparam receives a value. This uses the 'visible' attribute and requires a 'change' event handler on 'firstname'. ```json { "firstname": { "display_name": "First Name", "description": "Please enter your business name", "type": "text", "required": true, "events": [ {"change": "firstnameChange"} ] }, "lastname": { "display_name": "Last Name", "description": "Please enter your last name", "type": "text", "required": false } } ``` ```javascript function firstnameChange(event) { if (event.value) { utils.set('lastname', { visible: false }); } else { utils.set('lastname', { visible: true }); } } ``` -------------------------------- ### Create a Freshdesk App using FDK Source: https://developers.freshworks.com/docs/app-sdk/v2.3/freshdesk/app-development-process Run this command to create a new Freshdesk app using the 'your_first_app' template. This command prompts for product and template selection if not specified. ```bash fdk create --product freshdesk --template your_first_app ``` -------------------------------- ### Verify FDK CLI Installation Source: https://developers.freshworks.com/docs/app-sdk/v2.3/freshdesk/app-development-process Run this command to verify that the Freshworks CLI has been installed correctly. Ensure the installed version is 9.4.1 or later. ```bash fdk version ``` -------------------------------- ### Start Timer Source: https://developers.freshworks.com/docs/app-sdk/v2.3/freshdesk/front-end-apps/interface-methods Starts a timer for a ticket. If a timer is already running, it will be stopped and a new one started. Requires agent ID, billable status, and an optional note. ```javascript try { let data = await client.interface.trigger("start", { id: "timer", value: { agent: user_id, billable: true, note: "text" } }) .then(function(data) { // data - success message }).catch(function(error) { // error - error object }); } ``` -------------------------------- ### Create a Freshservice App Source: https://developers.freshworks.com/docs/app-sdk/v2.3/freshservice/app-development-process Creates a new Freshservice app using the 'your_first_app' template. This command prompts for product and template selection if not specified. ```bash fdk create --product freshservice --template your_first_app ``` -------------------------------- ### Handle onAppInstall Event in server.js Source: https://developers.freshworks.com/docs/app-sdk/v2.3/freshservice/serverless-apps/external-events Implement the onAppInstallHandler in server.js to generate a webhook URL and register it with an external product. ```javascript exports = { onAppInstallHandler: function(payload) { generateTargetUrl() .then(function(url) { //Include API call to the third party to register your webhook }, function(err) { // Handle error }); } }; ``` -------------------------------- ### Install Latest CLI Version with Homebrew Source: https://developers.freshworks.com/docs/app-sdk/v2.3/freshdesk/app-development-process Install the latest version of the Freshworks CLI using Homebrew. This command also installs a compatible Node.js version and creates a custom node location. ```bash brew install fdk ``` -------------------------------- ### Example Request Template with App Settings Source: https://developers.freshworks.com/docs/app-sdk/v2.3/freshdesk/advanced-interfaces/request-method Illustrates using app settings for host, method, path, protocol, and authorization headers. Includes encoding for API keys. ```json { "schema": { "host": "<%= app_settings.domain %>", "method": "GET", "path": "<%= app_settings.path %>", "protocol": "https", "headers": { "Content-Type": "application/json", "Authorization": "Bearer <%= encode(app_settings.apiKey) %>" } } } ``` -------------------------------- ### Toggle Timer Action Source: https://developers.freshworks.com/docs/app-sdk/v2.3/freshservice/front-end-apps/interface-methods Toggles the state of a timer (starts if stopped, stops if started). ```javascript client.interface.trigger("toggle", { id: "timer" }) ``` -------------------------------- ### Create a Freshdesk Visitor App Source: https://developers.freshworks.com/docs/app-sdk/v2.3/freshdesk/end-user-apps This command initiates the creation of a new Freshdesk app using the 'your_first_visitor_app' template. It sets up the basic directory structure and configuration files required for a front-end application deployed on the customer support portal. ```bash fdk create ``` -------------------------------- ### Validate Installation Parameters with validate Source: https://developers.freshworks.com/docs/app-sdk/v2.3/freshdesk/app-settings/app-installation-page/custom-installation-page Use the `validate` method in `iparams.js` to validate user-entered iparam values on the Installation or Edit Settings pages. If the method returns false, the installation or saving of values is stopped. ```javascript function validate() { let isValid = true; var input = jQuery("input[name=last_name]").val(); if(!input.match(/^[A-z]+$/)) { jQuery("#error_div").show(); isValid = false; } else { jQuery("#error_div").hide(); } return isValid; } ``` -------------------------------- ### Manifest.json - onAppInstall Event Subscription Source: https://developers.freshworks.com/docs/app-sdk/v2.3/freshdesk/serverless-apps/app-set-up-events Configuration in manifest.json to subscribe to the onAppInstall event. ```json "events": { "onAppInstall": { "handler": "onAppInstallCallback" } } ``` -------------------------------- ### Start Timer Action Source: https://developers.freshworks.com/docs/app-sdk/v2.3/freshservice/front-end-apps/interface-methods Starts a timer action. Requires a payload object specifying the necessary details for the timer. ```javascript client.interface.trigger("start", { id: "timer", value: {
``` -------------------------------- ### Error Object Example for afterAppUpdate Source: https://developers.freshworks.com/docs/app-sdk/v2.3/freshdesk/serverless-apps/app-set-up-events Example of an error object used with renderData() to revert the app to the previous version. ```javascript renderData({message: "Invalid API key. App reverted to previous version. Try updating again."}); ``` -------------------------------- ### Sample manifest.json Configuration Source: https://developers.freshworks.com/docs/app-sdk/v2.3/freshservice/front-end-apps/app-manifest Example of a manifest.json file for a Freshservice application, showing platform version, product configuration for Freshservice including ticket sidebar location and API requests, and engine versions. ```json { "platform-version": "2.3", "product": { "freshservice": { "location": { "ticket_sidebar": { "url": "template.html", "icon": "logo.svg" } }, "requests": { "createTicket": {}, "getTickets": {} } } }, "engines": { "node": "18.17.1", "fdk": "9.0.4" } } ``` -------------------------------- ### Update FDK Installation Command Source: https://developers.freshworks.com/docs/app-sdk/v2.3/freshservice/whats-new Use this command to install the latest CLI version. The previous command will be deprecated soon. ```bash npm install https://cdn.freshdev.io/fdk/UFsBA.tgz -g ``` -------------------------------- ### Agent Update Example Changes Source: https://developers.freshworks.com/docs/app-sdk/v2.3/freshdesk/serverless-apps/product-events/onagent An example of the 'changes' object for an onAgentUpdate event, specifically showing a change in the 'signature_html' attribute. ```json { "model_changes": { "signature_html": ["
agent signature
", "
updated agent signature
"] }, "system_changes": {}, "misc_changes": {} } ``` -------------------------------- ### List Configuration Parameters Source: https://developers.freshworks.com/docs/app-sdk/v2.3/freshdesk/basic-dev-tools/freshworks-cli Lists all currently set or default configuration parameters and their values. This command is used to view the existing environment settings. ```bash fdk config list ``` -------------------------------- ### Example Changes Object Source: https://developers.freshworks.com/docs/app-sdk/v2.3/freshservice/serverless-apps/product-events/onchange An example illustrating how custom fields and requester IDs are represented within the 'changes' object when an update occurs. ```json "changes": { "custom_fields": { "custom_number_field": [ 1234, 1234567 ] }, "requester_id": [ 37656, 37659 ] } ``` -------------------------------- ### Example Request Template with iparams Source: https://developers.freshworks.com/docs/app-sdk/v2.3/freshdesk/advanced-interfaces/request-method Demonstrates using non-secure and secure iparams within the request schema for host and headers. Ensure iparam names match runtime API context. ```json { "schema": { "method": "GET", "host": "<%= iparam.domain %>.freshdesk.com", "path": "/api/v2/tickets", "headers": { "Authorization": "Bearer <%= iparam.api_key %>", "Content-Type": "application/json" }, "query": { "page": "<%= context.page %>", "per_page": "20" } } } ``` -------------------------------- ### Example Group Update Changes Source: https://developers.freshworks.com/docs/app-sdk/v2.3/freshdesk/serverless-apps/product-events/ongroup A concrete example of the 'changes' object in an onGroupUpdate event, showing a modification to the group's name. ```json "changes": { "misc_changes": {}, "model_changes": { "name": [ "TitanGroup", "TitanGroup updated" ] }, "system_changes": {} } ``` -------------------------------- ### Sample app_settings.json Configuration Source: https://developers.freshworks.com/docs/app-sdk/v2.3/freshdesk/app-settings/developer-app-settings Define the names of credentials your app will use in the `app_settings.json` file. The values are provided during local development or app submission. ```json { "apiKey": {}, "ssh_key": {}, "iam_key": {}, "token": {} } ``` -------------------------------- ### Start Timer Action Source: https://developers.freshworks.com/docs/app-sdk/v2.3/freshdesk/front-end-apps/interface-methods Use this method to start a timer action. The `id` must be 'timer', and the `value` should contain the necessary payload for the timer. ```javascript client.interface.trigger("start", { id: "timer", value: {", "Content-Type": "application/json" } }, "options": { "isOAuth": true } } ``` -------------------------------- ### Get Help for a Specific CLI Command Source: https://developers.freshworks.com/docs/app-sdk/v2.3/freshdesk/basic-dev-tools/freshworks-cli Use the -h or --help flag with any command to get detailed information about its usage and options. ```bash fdk COMMAND [-h or --help] ``` ```bash fdk create -h ``` -------------------------------- ### Timer Control Source: https://developers.freshworks.com/docs/app-sdk/v2.3/freshdesk/front-end-apps/interface-methods Allows an app to start or stop the timer for a ticket. If a timer is already running, starting a new one will stop the previous one. ```APIDOC ## client.interface.trigger("start", { id: "timer", value: { agent: "user_id", billable: true, note: "text" } }) ### Description Starts or stops a timer for a ticket. If a timer is already running, the running timer is stopped and a new timer is started. ### Method `trigger` ### Parameters #### `id` - **timer** (string) - Required - Identifier for the timer action. #### `value` - **agent** (string) - Required - The user ID of the agent. - **billable** (boolean) - Required - Indicates if the time is billable. - **note** (string) - Optional - A note associated with the timer. ### Request Example ```javascript try { let data = await client.interface.trigger("start", { id: "timer", value: { agent: user_id, billable: true, note: "text" } }) .then(function(data) { // data - success message }).catch(function(error) { // error - error object }); } catch(error) {} ``` ``` -------------------------------- ### Correct manifest.json for Dependencies Source: https://developers.freshworks.com/docs/app-sdk/v2.3/freshdesk/app-development-guidelines/app-validation This manifest.json example shows the correct way to declare dependencies for a serverless application. Ensure all used dependencies are declared and unused ones are removed. ```json { "platform-version": "2.3", "product": { "freshdesk": { "events": { "onTicketCreate": { "handler": "onTicketCreateHandler" } } } }, "engines": { "node": "18.17.1", "fdk": "9.0.4" }, "dependencies": { "lodash": "4.0.0" } } ``` -------------------------------- ### Example: Populate multiselect options based on firstname Source: https://developers.freshworks.com/docs/app-sdk/v2.3/freshdesk/app-settings/app-installation-page/installation-page Demonstrates populating a 'multiselect' iparam with options based on the value entered in the 'firstname' iparam. This requires the 'firstname' iparam to have a 'change' event handler. ```json { "firstname": { "display_name": "First Name", "description": "Please enter your business name", "type": "text", "required": true, "events": [ {"change": "firstnameChange"} ] }, "multiselect": { "display_name": "Other Details", "description": "Please select values", "type": "multiselect", "required": true, "options": [ "opt1", "opt2", "opt3" ] } } ``` ```javascript function firstnameChange(event) { // Example: dynamically set options based on firstname if (event.value === 'some_value') { utils.set('multiselect', { values: ['new_opt1', 'new_opt2'] }); } else { utils.set('multiselect', { values: ['opt1', 'opt2', 'opt3'] }); } } ```