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
configobject in thedefinitionandparameters, 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}}"
}
}
}
}