Rendering Dynamic Parameters
Boltic enables the dynamic rendering of UI elements, known as parameters, through REST API calls. This allows integration definitions to adapt dynamically based on external data fetched at runtime.
Implementation Steps
To dynamically render parameters, use the config
object at either the definition
and parameters
level within your integration definition.
Follow these guidelines:
- In the
config
object in thedefinition
andparameters
, set:"urlType": "parameters"
"body.loadParametersMethod"
pointing to a specific root-level key
- The referenced root-level key should contain the actual REST API definition that retrieves the dynamic parameters.
- Within this REST API definition, include transformations, authorization headers, and other configurations.
Example Configuration
The following is an example demonstrating dynamic parameters rendering:
Integration Definition with Dynamic Parameters:
"create": {
"definition": {
"method": "post",
"url": "{{secrets.api_url}}/api/contacts",
"headers": {
"Authorization": "Token token={{secrets.api_key}}"
},
"qs": {},
"body": "{{parameters}}",
"response": {
"output": "{{response.data.contact}}",
"error": {
"message": "{{response.data.errors.message}}",
"code": "{{response.data.errors.code}}"
}
}
},
"parameters": [],
"config": {
"urlType": "parameters",
"method": "post",
"url": "integrations/parameters",
"body": {
"name": "freshsales",
"resource": "contact",
"secret": "{{parameters.secret}}",
"loadParametersMethod": "getMoreParameters"
}
}
}
Root-Level REST Definition (``):
"getMoreParameters": {
"definition": {
"method": "get",
"url": "{{secrets.api_url}}/api/settings/contacts/fields",
"headers": {
"Authorization": "Token token={{secrets.api_key}}"
},
"qs": {},
"transform": {
"output": "const result = output.sort((a, b) => a.position - b.position).map((ele) => { const excludeParameters = [ 'phone_numbers', 'sales_accounts', 'active_sales_sequences', 'last_contacted', 'last_contacted_mode', 'last_contacted_sales_activity_mode', 'last_contacted_via_sales_activity', 'completed_sales_sequences', 'last_seen', 'lead_score', 'recent_note', 'creater_id', 'created_at', 'updater_id', 'updated_at', 'web_form_ids', 'last_assigned_at', ]; if (!excludeParameters.includes(ele.name)) { const typeMap = { text: 'text', textarea: 'textarea', dropdown: 'select', auto_complete: 'multitext', multi_select_dropdown: 'multiselect', radio: 'select', number: 'number', }; const placeholderPrefix = ['select', 'multiselect', 'radio'].includes( typeMap[ele.type] ) ? 'Select' : 'Enter'; const requiredParameters = ['emails', 'first_name']; const newObj = { name: ele.name, meta: { displayName: ele.label, displayType: typeMap[ele.type] || 'text', placeholder: `${placeholderPrefix} ${ele.label}`, validation: { required: requiredParameters.includes(ele.name) || ele.required, }, }, }; if (['dropdown', 'radio', 'multi_select_dropdown'].includes(ele.type)) { newObj.meta.htmlProps = { allowDynamic: true }; if (ele.choices && ele.choices.length) { newObj.meta.options = ele.choices.map((choice) => ({ label: choice.value, value: choice.id, })); } else { newObj.meta.displayType = 'text'; } if (ele.type === 'multi_select_dropdown') { newObj.meta.value = []; } } if (ele.default === false) { newObj.prop = 'custom_field'; } return newObj; } return null; }).filter((ele) => ele !== null); let custom_field = { name: 'custom_field', meta: { children: [], displayType: 'object', }, }; const outputWithCustomField = result.reduce((acc, ele) => { if (ele.prop === 'custom_field') { custom_field.meta.children.push(ele); } else { acc.push(ele); } return acc; }, []); if (custom_field.meta.children.length > 0) { outputWithCustomField.push(custom_field); } return outputWithCustomField"
},
"response": {
"output": "{{response.data.fields}}",
"error": {
"message": "{{response.data.errors.message}}",
"code": "{{response.data.errors.code}}"
}
}
}
}