As you build integration with Freshsales, you will quickly find there’s a need for two critical requirements for your integration to succeed.
- Subdomain + Root Domain
- API Key
The subdomain is usually the brand name of the organization.
The root domain can be one of the following.
As an app developer, you want your integration to work seamlessly with any user of Freshsales with any of the above root domains possible amongst the users. Both of these details are necessary to consume Freshsales API.
This Handbook will explore the right way to accomplish it and get your app the right combination of domain and API keys to make API calls and make the integration accurately. It is important to note that there is
- Freshsales
- Freshsales Suite (previously freshsales suite)
If your app runs on Freshworks App Platform, developers can choose to build their app either by using iparams.json
or by iparams.html
(labeled custom installation page).
Iparams.json
This allows the app developer to define a JSON
file in the config/
directory.
Previously (labeled: Freshsales Classic)
config/iparams.json
"domainName": {
"display_name": "Domain Name",
"description": "Please enter your domain name",
"type": "domain",
"type_attributes": {
"product": "freshsales"
},
"required": true
},
"apiKey": {
"display_name": "API Key",
"description": "Please enter your api_key",
"type": "api_key",
"type_attributes": {
"product": "freshsales"
},
"secure": true,
"required": true,
}
App expected the above declaration of installation parameters. The above would render the following:
The app can access the user entered Domain Name as follows:
// app.js
let client;
(async function init(){
client = await app.initialized();
client.events.on('app.activated', ignite);
})();
async function ignite(){
// 'brandname' is retrievable as follows:
let domainName = await client.iparams.get("domainName");
}
// server.js
// All serverless event payloads get the "iparams" property where the app can access stored data.
Prime points to pay attention to:
- All the users who newly sign up for Freshsales will have
brandname.myfreshworks.com
instead ofbrandname.freshsales.io
. - Eventually, accounts on
brandname.freshsales.io
will be moved underbrandname.freshworks.com
. - All the apps using
brandname.freshsales.io
to construct API endpoints and make API calls will continue to succeed.
If the type_attributes.product
value is freshworks_crm
, in the input box that is displayed on the Installation page, the domain name part is populated as myfreshworks.com
.
// iparams.json
{
"domainName": {
"display_name": "Domain Name",
"description": "Please enter your domain name",
"type": "domain", // use type "text" to populate "http
"type_attributes": {
"product": "freshworks_crm"
},
"data-bind": "product.domain",
"required": true,
"visible": false // (Optional) The field won't be displayed but it will be correctly populated and stored.
},
"apiKey": {
"display_name": "API Key",
"description": "Please enter your api_key",
"type_attributes": {
"product": "freshworks_crm"
},
"type": "text",
"secure": true,
"required": true
}
}
Render:
If the value is freshworks_crm
and if the app is installed on a Freshsales Suite (FCRM) account that has been migrated from Freshsales, the domain name part is populated as freshworks.com
.
Omni apps supporting Freshsales and Freshsales suite simultaneously, If the type_attributes.product
value is current
, the domain name is populated based on the product on which the app is installed.
If the app is installed on a Freshsales account, the domain name part is populated as freshsales.io
. If the app is installed on a Freshsales Suite (FCRM) account, the domain name part is populated as myfreshworks.com
or freshworks.com
(if the account is migrated from Freshsales).
Tip: Learn about Data Bind to Auto Populate these fields as needed.
Custom Installation Page
You can use data-bind to auto-populate domain names or even API keys without users having to enter them. This way app can use DOM manipulation to access the values to perform any validations if necessary.
Get Domain at App Runtime
Now can get the domain or URL at the runtime of the app. The app doesn’t need to capture those details from the user.
// app.js. on Freshsales Suite
let client;
(async function init(){
client = await app.initialized();
client.events.on('app.activated', ignite);
})();
async function ignite(){
// The domain details is retrive-able as follows
let data = await client.data.get("domainName");
/*
data:
{
domainName:"brandname.myfreshworks.com",
productContext:{
url:"https://brandname.myfreshworks.com/crm",
name:"freshworks_crm"
}
}
*/
// You can access the above details at runtime automatically.
}
Unless required based on the use case, you can avoid getting the domain name completely, and gain them at runtime. Construct API endpoints and make API calls worry-free.
Alternate Approach to get Domain Details at Runtime
Let’s say the following is your iparams.json
. It’s mandatory to have both domainName
and apiKey
.
// iparams.json
"domainName": {
"display_name": "Domain Name",
"description": "Please enter your domain name",
"type": "domain",
"type_attributes": {
"product": "freshworks_crm"
},
"required": true
},
"apiKey": {
"display_name": "API Key",
"description": "Please enter your api_key",
"type": "api_key",
"type_attributes": {
"product": "freshworks_crm"
},
"secure": true,
"required": true,
}
In app.js
or anywhere
let client;
(async function init(){
client = await app.initialized();
client.events.on('app.activated', ignite);
})();
async function ignite(){
// 'brandname' is retrievable as follows:
let data = await client.iparams.get($domainName);
/* data
{ url: https://brandname.myfreshworks.com/crm, name: ‘freshworks_crm’ }
*/
}
Note:
- The
$domainName
here should be of"type":"domain"
- The
domainName
in$domainName
should be the same property key iniparams.json
. For example, theiparams.json
mentionsdomain
. At the time of retrieval$domain
should be be used asawait client.iparams.get($domain)
. - This way of retrieving the root domain and subdomain will require another property listed in
iparams.json
with the"type":"api_key"