=============== LIBRARY RULES =============== From library maintainers: - Use Integration Procedures for server-side, multi-step orchestration without UI. - Always add a Response Action at the end to control output payload (prevents data leakage). - Use Named Credentials in HTTP Actions; never hard-code URLs or secrets. - For >120s callouts, convert to Long-Running IP with Continuation. - Wrap risky steps (HTTP, Remote Action) in Try-Catch Blocks for resilience. - Prefer DataRaptor Turbo Extract for single-sObject reads (2-10x faster). - Use Cache Blocks/Actions with appropriate TTL for reference data. - Bulkify: never call Extract inside a Loop Block on per-item basis — extract once with filter on key list. ### Concatenate List Items Example Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/02-work-with-data-and-lists.md This example demonstrates concatenating values from an array into a single comma-separated string using a Set Values Action within a Loop Block, followed by trimming the output. ```json // This is a conceptual example and requires specific Integration Procedure actions to implement. // Assume 'values' is an array of strings from a previous step. // Inside a Loop Block: // Set Values Action: // Output Variable: concatenatedString // Value: "${concat(concatenatedString, ', ', item.value)}" // After the Loop Block: // Set Values Action: // Output Variable: finalString // Value: "${trim(concatenatedString)}" ``` -------------------------------- ### Invoke Integration Procedure using IntegrationProcedureService Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/10-invocation-from-apex.md This example demonstrates calling an Integration Procedure using a custom IntegrationProcedureService class. It shows how to initialize variables and populate input/output maps. ```apex /* Initialize variables */ String procedureName = 'Type_SubType'; Map ipInput = new Map (); Map ipOutput = new Map (); Map ipOptions = new Map (); /* Populating input map for an Integration Procedure. Follow whatever structure your VIP expects */ String orderId = '80100000000abcd'; ipInput.put('orderId', orderId); /* Call the Integration Procedure via runIntegrationService, and save the output to ipOutput */ ipOutput = (Map) ``` -------------------------------- ### Name Field vs OmniProcessKey Example Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/12-naming-restrictions.md Demonstrates the difference between the 'Name' field (which can contain underscores) and the 'OmniProcessKey' (which must adhere to alphanumeric restrictions for Type and SubType). ```text OmniProcessKey: "SURA_LeadUpdateOrchestrator" (no underscore in SubType) Name field: "SURA_LeadUpdate_Orchestrator" (WITH underscore!) ``` -------------------------------- ### Example List Structure for Loop Block Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/02-work-with-data-and-lists.md This JSON structure represents a list of products with IDs, which can be iterated over using a Loop Block in an Integration Procedure. ```json { "Products": { "Ids": [ { "Id": 1 }, { "Id": 2 } ] } } ``` -------------------------------- ### Example Input for Searching Records with Loop Block Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/02-work-with-data-and-lists.md This JSON structure provides a list of names to be used as input parameters for searching records within a Loop Block. ```json { "names": [ { "Name": "Miller" }, { "Name": "Torres" } ] } ``` -------------------------------- ### Vlocity CLI Deployment YAML Manifest Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/13-datapack-structure.md Example YAML manifest file used with the Vlocity CLI for deploying DataPacks, specifying project paths and included DataRaptors and Integration Procedures. ```yaml projectPath: . expansionPath: ./vlocity delete: false activate: true compileOnBuild: true manifest: DataRaptor: - SURADRExtractLeadById IntegrationProcedure: - SURA_LeadGetOrchestrator - SURA_LeadUpdateOrchestrator ``` -------------------------------- ### elementValueMap Formula with = Prefix Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/14-formula-gotchas.md Formulas within elementValueMap require an '=' prefix. This example shows a conditional check for non-blank input. ```json "myField": "=IF(NOT(ISBLANK(%input%)), true, false)" ``` -------------------------------- ### executionConditionalFormula Without = Prefix Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/14-formula-gotchas.md Formulas used in executionConditionalFormula should not use the '=' prefix. This example checks if a data field is false. ```json "executionConditionalFormula": "%Set_HasData:hasOwnerData% = false" ``` -------------------------------- ### DataRaptor Naming Restrictions Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/12-naming-restrictions.md Shows examples of incorrect and correct naming conventions for DataRaptors, emphasizing the alphanumeric-only rule. ```text | Incorrect | Correct | |-----------|---------| | `SURA_DR_Extract_Lead` | `SURADRExtractLead` | | `SURA_DR_Transform_ApiResponse` | `SURADRTransformApiResponse` | ``` -------------------------------- ### failureConditionalFormula Without = Prefix Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/14-formula-gotchas.md Formulas used in failureConditionalFormula should not use the '=' prefix. This example checks if an error field is not blank. ```json "failureConditionalFormula": "NOT(ISBLANK({%Step:result:error%}))" ``` -------------------------------- ### Clear Integration Procedure Cache with Connect API Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/06-caching.md Use this Connect API method to clear all cached data for an Integration Procedure. This method replaces older IntegrationProcedureService methods starting in Summer '25. ```Apex ConnectApi.IntegrationProcedureCacheInputData apexInput = new ConnectApi.IntegrationProcedureCacheInputData(); apexInput.ipKey = ipKey; List l = new List(); l.add(apexInput); finalInput.ipInput = l; finalInput.cacheStorageType = ConnectApi.CacheStorageType.All; ConnectApi.IntegrationProcedureCacheOutputRepresentation test = ConnectApi.OmniDesignerConnect.ClearIntegrationProcedureCache(finalInput); ``` -------------------------------- ### failureConditionalFormula with Curly Braces Syntax Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/14-formula-gotchas.md The failureConditionalFormula uses a distinct merge field syntax with curly braces `{%...%}`. This example checks if an error field is not blank. ```json "failureConditionalFormula": "NOT(ISBLANK({%CreateLead:result:error%}))" ``` -------------------------------- ### Import Context7 Library Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/README.md Add this statement to your prompt in supported AI clients to ground responses in the Omnistudio Integration Procedures documentation. ```text use context7 ``` -------------------------------- ### Deploy Integration Procedure using Vlocity CLI Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/13-datapack-structure.md Commands for deploying Integration Procedures using a YAML manifest and exporting a specific IP. ```bash # Deploy using YAML manifest vlocity packDeploy --sfdx.username my-org --job manifest/package.yaml # Export specific IP vlocity packExport --sfdx.username my-org --type IntegrationProcedure --name "SURA_LeadGetOrchestrator" ``` -------------------------------- ### Integration Procedure Invocation with Connect API Options Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/10-invocation-from-apex.md Demonstrates setting various options for Integration Procedure execution via the Connect API, including debug, caching, and queueable flags. ```apex String ipName = 'FindContacts_LastNames'; Map inputMap = new Map(); inputMap.put('ContactLastName', 'Smith'); Map outputMap = new Map(); Map optionsMap = new Map(); optionsMap.put('isDebug', false); ConnectAPI.IntegrationProcedureServiceRunInputRepresentation apexInput = new ConnectAPI.IntegrationProcedureServiceRunInputRepresentation(); List stringList = new List(); String serializedInputMap = JSON.serialize(inputMap); stringList.add(serializedInputMap); apexInput.input = stringList; ConnectAPI.IntegrationProcedureServiceRunOptionsRepresentation options = new ConnectAPI.IntegrationProcedureServiceRunOptionsRepresentation(); for (String key: optionsMap.keySet()){ if (key == 'isDebug') { options.isDebug = (Boolean)optionsMap.get(key); } else if (key == 'chainable') { options.chainable = (Boolean)optionsMap.get(key); } else if (key == 'resetCache') { options.resetCache = (Boolean)optionsMap.get(key); } else if (key == 'ignoreCache') { options.ignoreCache = (Boolean)optionsMap.get(key); } else if (key == 'queueableChainable') { options.queueableChainable = (Boolean)optionsMap.get(key); } else if (key == 'useQueueableApexRemoting') { options.useQueueableApexRemoting = (Boolean)optionsMap.get(key); } else if (key == 'vlcApexResponse') { options.vlcApexResponse = (Boolean)optionsMap.get(key); } else if (key == 'useFuture') { options.useFuture = (Boolean)optionsMap.get(key); } else if (key == 'useQueueable') { options.useQueueable = (Boolean)optionsMap.get(key); } else if (key == 'vlcIPData') { options.vlcIPData = (String)optionsMap.get(key); } else if (key == 'vlcStatus') { options.vlcStatus = (String)optionsMap.get(key); } else if (key == 'vlcMessage') { options.vlcMessage = (String)optionsMap.get(key); } } options.shouldSendLegacyResponse = true; apexInput.options = options; ``` -------------------------------- ### Synchronous Integration Procedure Execution with ConnectAPI (JSON Input) Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/10-invocation-from-apex.md Executes an Integration Procedure synchronously using ConnectAPI, where input and options are provided as JSON strings. This requires deserialization before execution. ```Apex String ipName = 'FindContacts_LastNames'; String inputMap = '{"ContactLastName": "Smith"}'; String optionsMap = '{"isDebug": false}'; ConnectAPI.IntegrationProcedureServiceRunInputRepresentation apexInput = new ConnectAPI.IntegrationProcedureServiceRunInputRepresentation(); List stringList = new List(); stringList.add(inputMap); apexInput.input = stringList; Map optionsMapDeserialized = (Map)JSON.deserializeUntyped(optionsMap); ConnectAPI.IntegrationProcedureServiceRunOptionsRepresentation options = new ConnectAPI.IntegrationProcedureServiceRunOptionsRepresentation(); for (String key: optionsMapDeserialized.keySet()){ if (key == 'isDebug') { options.isDebug = (Boolean)optionsMapDeserialized.get(key); } else if (key == 'chainable') { options.chainable = (Boolean)optionsMapDeserialized.get(key); } else if (key == 'resetCache') { options.resetCache = (Boolean)optionsMapDeserialized.get(key); } else if (key == 'ignoreCache') { options.ignoreCache = (Boolean)optionsMapDeserialized.get(key); } else if (key == 'queueableChainable') { options.queueableChainable = (Boolean)optionsMapDeserialized.get(key); } else if (key == 'useQueueableApexRemoting') { options.useQueueableApexRemoting = (Boolean)optionsMapDeserialized.get(key); } else if (key == 'vlcApexResponse') { options.vlcApexResponse = (Boolean)optionsMapDeserialized.get(key); } else if (key == 'useFuture') { options.useFuture = (Boolean)optionsMapDeserialized.get(key); } else if (key == 'useQueueable') { options.useQueueable = (Boolean)optionsMapDeserialized.get(key); } else if (key == 'vlcIPData') { options.vlcIPData = (String)optionsMapDeserialized.get(key); } else if (key == 'vlcStatus') { options.vlcStatus = (String)optionsMapDeserialized.get(key); } else if (key == 'vlcMessage') { options.vlcMessage = (String)optionsMapDeserialized.get(key); } } options.shouldSendLegacyResponse = true; options.useFuture = true; apexInput.options = options; ConnectAPI.OmniDesignerConnect.integrationProcedureExecute(ipName, apexInput); ``` -------------------------------- ### Invoke Integration Procedure from Apex Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/10-invocation-from-apex.md This Apex code snippet demonstrates how to execute an Integration Procedure, set various run options, and process the JSON response. It's used when you need to trigger backend business logic from Apex. ```apex ConnectAPI.IntegrationProcedureServiceRunOptionsRepresentation options = new ConnectAPI.IntegrationProcedureServiceRunOptionsRepresentation(); for (String key: optionsMap.keySet()){ if (key == 'isDebug') { options.isDebug = (Boolean)optionsMap.get(key); } else if (key == 'chainable') { options.chainable = (Boolean)optionsMap.get(key); } else if (key == 'resetCache') { options.resetCache = (Boolean)optionsMap.get(key); } else if (key == 'ignoreCache') { options.ignoreCache = (Boolean)optionsMap.get(key); } else if (key == 'queueableChainable') { options.queueableChainable = (Boolean)optionsMap.get(key); } else if (key == 'useQueueableApexRemoting') { options.useQueueableApexRemoting = (Boolean)optionsMap.get(key); } else if (key == 'vlcApexResponse') { options.vlcApexResponse = (Boolean)optionsMap.get(key); } else if (key == 'useFuture') { options.useFuture = (Boolean)optionsMap.get(key); } else if (key == 'useQueueable') { options.useQueueable = (Boolean)optionsMap.get(key); } else if (key == 'vlcIPData') { options.vlcIPData = (String)optionsMap.get(key); } else if (key == 'vlcStatus') { options.vlcStatus = (String)optionsMap.get(key); } else if (key == 'vlcMessage') { options.vlcMessage = (String)optionsMap.get(key); } } options.shouldSendLegacyResponse = true; apexInput.options = options; ConnectAPI.IntegrationProcedureServiceRunOutputRepresentation output = ConnectAPI.OmniDesignerConnect.integrationProcedureExecute(ipName, apexInput); List responseList = output.response; String currentSerResponse = responseList[0]; Map currentResponseObj = (Map)JSON.deserializeUntyped(currentSerResponse); Object ipOutput = currentResponseObj.get('result'); System.debug('IP Output: ' + ipOutput); ``` -------------------------------- ### Integration Procedure DataPack Directory Structure Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/13-datapack-structure.md This outlines the standard directory layout for an Integration Procedure DataPack, with each IP residing in its own directory containing definition, configuration, and element files. ```directory structure vlocity/IntegrationProcedure/ └── {IP_Name}/ # One directory per IP ├── {IP_Name}_DataPack.json # Main definition (OmniProcessElement[] = execution order) ├── {IP_Name}_PropertySetConfig.json # IP-level config (chainable limits, rollback) ├── {IP_Name}_ParentKeys.json # Parent key references ├── {IP_Name}_Element_{StepName}.json # One file per step/element └── {IP_Name}_SampleInput.json # Test input (optional) ``` -------------------------------- ### Synchronous Integration Procedure Execution with ConnectAPI Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/10-invocation-from-apex.md Executes an Integration Procedure synchronously using the ConnectAPI. This method is suitable for immediate results within a transaction. ```Apex ConnectAPI.IntegrationProcedureServiceRunOptionsRepresentation options = new ConnectAPI.IntegrationProcedureServiceRunOptionsRepresentation(); for (String key: optionsMap.keySet()){ if (key == 'isDebug') { options.isDebug = (Boolean)optionsMap.get(key); } else if (key == 'chainable') { options.chainable = (Boolean)optionsMap.get(key); } else if (key == 'resetCache') { options.resetCache = (Boolean)optionsMap.get(key); } else if (key == 'ignoreCache') { options.ignoreCache = (Boolean)optionsMap.get(key); } else if (key == 'queueableChainable') { options.queueableChainable = (Boolean)optionsMap.get(key); } else if (key == 'useQueueableApexRemoting') { options.useQueueableApexRemoting = (Boolean)optionsMap.get(key); } else if (key == 'vlcApexResponse') { options.vlcApexResponse = (Boolean)optionsMap.get(key); } else if (key == 'useFuture') { options.useFuture = (Boolean)optionsMap.get(key); } else if (key == 'useQueueable') { options.useQueueable = (Boolean)optionsMap.get(key); } else if (key == 'vlcIPData') { options.vlcIPData = (String)optionsMap.get(key); } else if (key == 'vlcStatus') { options.vlcStatus = (String)optionsMap.get(key); } else if (key == 'vlcMessage') { options.vlcMessage = (String)optionsMap.get(key); } } options.shouldSendLegacyResponse = true; apexInput.options = options; ConnectAPI.IntegrationProcedureServiceRunOutputRepresentation output = ConnectAPI.OmniDesignerConnect.integrationProcedureExecute(ipName, apexInput); List responseList = output.response; String currentSerResponse = responseList[0]; Map currentResponseObj = (Map)JSON.deserializeUntyped(currentSerResponse); Object ipOutput = currentResponseObj.get('result'); ``` -------------------------------- ### Executing Integration Procedure with Custom Apex Class Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/10-invocation-from-apex.md Invokes an Integration Procedure using a custom Apex class, passing input and options maps. This demonstrates a common pattern for encapsulating Integration Procedure calls. ```Apex String ipName = 'FindContacts_LastNames'; Map inputMap = new Map(); inputMap.put('ContactLastName', 'Smith'); Map optionsMap = new Map(); optionsMap.put('isDebug', false); Object ipOutput = devopsimpkg11.IntegrationProcedureService.runIntegrationProcedureServiceFromApex(ipName, inputMap, optionsMap); ``` -------------------------------- ### Working Boolean Comparison in executionConditionalFormula Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/14-formula-gotchas.md This demonstrates the correct way to use boolean flags in executionConditionalFormula by explicitly comparing them with '= true'. ```json "executionConditionalFormula": "%Set_HasData:hasOwnerData% = true" ``` -------------------------------- ### Invoke Integration Procedure from Apex using ConnectAPI Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/09-invocation.md Use the ConnectAPI.OmniDesignerConnect.integrationProcedureExecute method for calling Integration Procedures from Apex classes. This method offers improved performance and removes managed package dependencies. ```apex ConnectAPI.OmniDesignerConnect.integrationProcedureExecute(ipName, apexInput); ``` -------------------------------- ### Correct vs Incorrect SubType and Type Naming Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/12-naming-restrictions.md Illustrates common naming errors for SubType and Type fields, highlighting the restriction against underscores, spaces, and hyphens. ```text | Incorrect | Why | Correct | |-----------|-----|---------| | `SubType: "Lead_Create"` | Underscore in SubType | `SubType: "LeadCreate"` | | `SubType: "Quote_GetFactors"` | Underscore in SubType | `SubType: "QuoteGetFactors"` | | `Type: "SURA_Lead"` | Underscore in Type | `Type: "SURA"` | | `SubType: "Lead Create"` | Space in SubType | `SubType: "LeadCreate"` | | `SubType: "lead-create"` | Hyphen in SubType | `SubType: "LeadCreate"` | ``` -------------------------------- ### Invoke Integration Procedure using IntegrationProcedureService Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/10-invocation-from-apex.md This is the older method for invoking an Integration Procedure. It is recommended to use the Connect API for better performance. ```apex String ipName = 'FindContacts_LastNames'; Map inputMap = new Map(); inputMap.put('ContactLastName', 'Smith'); Map optionsMap = new Map(); optionsMap.put('isDebug', false); Object ipOutput = devopsimpkg11.Integration ProcedureService.runIntegrationService(ipName, inputMap, optionsMap); ``` -------------------------------- ### Invoke Integration Procedure using Connect API Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/10-invocation-from-apex.md Executes an Integration Procedure using the Salesforce Connect API. This method handles complex input and option configurations. ```apex Map optionsMap = new Map(); optionsMap.put('isDebug', false); ConnectAPI.IntegrationProcedureServiceRunInputRepresentation apexInput = new ConnectAPI.IntegrationProcedureServiceRunInputRepresentation(); List stringList = new List(); String serializedInputMap = JSON.serialize(inputMap); stringList.add(serializedInputMap); apexInput.input = stringList; ConnectAPI.IntegrationProcedureServiceRunOptionsRepresentation options = new ConnectAPI.IntegrationProcedureServiceRunOptionsRepresentation(); for (String key: optionsMap.keySet()){ if (key == 'isDebug') { options.isDebug = (Boolean)optionsMap.get(key); } else if (key == 'chainable') { options.chainable = (Boolean)optionsMap.get(key); } else if (key == 'resetCache') { options.resetCache = (Boolean)optionsMap.get(key); } else if (key == 'ignoreCache') { options.ignoreCache = (Boolean)optionsMap.get(key); } else if (key == 'queueableChainable') { options.queueableChainable = (Boolean)optionsMap.get(key); } else if (key == 'useQueueableApexRemoting') { options.useQueueableApexRemoting = (Boolean)optionsMap.get(key); } else if (key == 'vlcApexResponse') { options.vlcApexResponse = (Boolean)optionsMap.get(key); } else if (key == 'useFuture') { options.useFuture = (Boolean)optionsMap.get(key); } else if (key == 'useQueueable') { options.useQueueable = (Boolean)optionsMap.get(key); } else if (key == 'vlcIPData') { options.vlcIPData = (String)optionsMap.get(key); } else if (key == 'vlcStatus') { options.vlcStatus = (String)optionsMap.get(key); } else if (key == 'vlcMessage') { options.vlcMessage = (String)optionsMap.get(key); } } options.shouldSendLegacyResponse = true; options.useQueueable = true; apexInput.options = options; ConnectAPI.IntegrationProcedureServiceRunOutputRepresentation output = ConnectAPI.OmniDesignerConnect.integrationProcedureExecute(ipName, apexInput); List responseList = output.response; String currentSerResponse = responseList[0]; Map currentResponseObj = (Map)JSON.deserializeUntyped(currentSerResponse); Object currentResult = currentResponseObj.get('result'); Map mapCurrentResult = (Map)currentResult; Object ipResultObj = mapCurrentResult.get('IPResult'); Map IpResultMap = (Map)ipResultObj; Id ipOutput = (Id)IpResultMap.get('queueableJobId'); ``` -------------------------------- ### Invoke Integration Procedure using Queueable Apex Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/10-invocation-from-apex.md Executes an Integration Procedure asynchronously using a queueable Apex method. This is suitable for long-running operations. ```apex String ipName = 'FindContacts_LastNames'; Map inputMap = new Map(); inputMap.put('ContactLastName', 'Smith'); Map optionsMap = new Map(); optionsMap.put('isDebug', false); Id ipOutput = devopsimpkg11.IntegrationProcedureService.runIntegrationProcedureQueueable(ipName, inputMap, optionsMap); ``` -------------------------------- ### Invoke Integration Procedure using Connect API Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/10-invocation-from-apex.md Use this method to invoke an Integration Procedure and retrieve its data. It bypasses sharing rules and custom permissions. ```apex String ipName = 'FindContacts_LastNames'; Map inputMap = new Map(); inputMap.put('ContactLastName', 'Smith'); Map optionsMap = new Map(); optionsMap.put('isDebug', false); ConnectAPI.IntegrationProcedureServiceRunInputRepresentation apexInput = new ConnectAPI.IntegrationProcedureServiceRunInputRepresentation(); List stringList = new List(); String serializedInputMap = JSON.serialize(inputMap); stringList.add(serializedInputMap); apexInput.input = stringList; ConnectAPI.IntegrationProcedureServiceRunOptionsRepresentation options = new ConnectAPI.IntegrationProcedureServiceRunOptionsRepresentation(); for (String key: optionsMap.keySet()){ if (key == 'isDebug') { options.isDebug = (Boolean)optionsMap.get(key); } else if (key == 'chainable') { options.chainable = (Boolean)optionsMap.get(key); } else if (key == 'resetCache') { options.resetCache = (Boolean)optionsMap.get(key); } else if (key == 'ignoreCache') { options.ignoreCache = (Boolean)optionsMap.get(key); } else if (key == 'queueableChainable') { options.queueableChainable = (Boolean)optionsMap.get(key); } else if (key == 'useQueueableApexRemoting') { options.useQueueableApexRemoting = (Boolean)optionsMap.get(key); } else if (key == 'vlcApexResponse') { options.vlcApexResponse = (Boolean)optionsMap.get(key); } else if (key == 'useFuture') { options.useFuture = (Boolean)optionsMap.get(key); } else if (key == 'useQueueable') { options.useQueueable = (Boolean)optionsMap.get(key); } else if (key == 'vlcIPData') { options.vlcIPData = (String)optionsMap.get(key); } else if (key == 'vlcStatus') { options.vlcStatus = (String)optionsMap.get(key); } else if (key == 'vlcMessage') { options.vlcMessage = (String)optionsMap.get(key); } } options.shouldSendLegacyResponse = true; apexInput.options = options; ConnectAPI.IntegrationProcedureServiceRunOutputRepresentation output = ConnectAPI.OmniDesignerConnect.integrationProcedureExecute(ipName, apexInput); List responseList = output.response; String currentSerResponse = responseList[0]; Map currentResponseObj = (Map)JSON.deserializeUntyped(currentSerResponse); Object ipOutput = currentResponseObj.get('result'); ``` -------------------------------- ### Inserting New Elements into DataPack.json Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/13-datapack-structure.md Illustrates the modification of the 'OmniProcessElement[]' array in DataPack.json to insert new elements while maintaining correct execution order. ```text BEFORE (DataPack.json OmniProcessElement[]): ["Set_Input", "Set_HasData", "If_No_Update_Data", "Response_No_Update_Data", "ValidateLead", "PersonLookup", "MergeData"] AFTER inserting If_Invalid_Scenario + Response_Invalid_Scenario: ["Set_Input", "Set_HasData", "If_No_Update_Data", "Response_No_Update_Data", "If_Invalid_Scenario", "Response_Invalid_Scenario", ← NEW (position 5-6) "ValidateLead", "PersonLookup", "MergeData"] ``` -------------------------------- ### Working AND() with Nested IF in executionConditionalFormula Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/14-formula-gotchas.md This demonstrates the correct way to handle complex conditions using nested IF statements combined with 2-argument AND() functions in executionConditionalFormula. ```json "executionConditionalFormula": "IF(AND(%Set_HasData:hasOwnerData% = true, %Set_HasData:hasVehicleData% = true), false, IF(%Set_HasData:hasPlanData% = true, false, true))" ``` -------------------------------- ### Clear All Cached Data for an Integration Procedure Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/06-caching.md Execute this Apex code to clear all cached data associated with an Integration Procedure, including session cache, org cache, and metadata. Ensure the 'ipKey' variable is correctly set. ```Apex ConnectApi.IntegrationProcedureCacheInputRepresentation finalInput = new ConnectApi.IntegrationProcedureCacheInputRepresentation(); ConnectApi.IntegrationProcedureCacheInputData apexInput = new ConnectApi.IntegrationProcedureCacheInputData(); apexInput.ipKey = ipKey; List l = new List(); l.add(apexInput); finalInput.ipInput = l; // To clear all cache types, do not specify cacheStorageType or set it to null/default. // For example, if you want to clear all, you might omit the next line or set it appropriately based on API behavior. // ConnectApi.IntegrationProcedureCacheOutputRepresentation test = ConnectApi.OmniDesignerConnect.ClearIntegrationProcedureCache(finalInput); ``` -------------------------------- ### Invoke Integration Procedure as Queueable Apex Job Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/10-invocation-from-apex.md Initiates an Integration Procedure as a Queueable Apex job for asynchronous processing. This method returns the job ID, allowing for tracking of the asynchronous operation. ```Apex String ipName = 'FindContacts_LastNames'; Map inputMap = new Map(); inputMap.put('ContactLastName', 'Smith'); ``` -------------------------------- ### Integration Procedure Element File Structure Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/13-datapack-structure.md The JSON structure for an individual element file within an Integration Procedure DataPack, detailing its properties and configuration. ```json { "Description": "WHAT THIS STEP DOES", "IsActive": true, "IsOmniScriptEmbeddable": false, "Name": "ElementName", "OmniProcessId": { "Name": "IP_Name_As_In_Org", "VlocityDataPackType": "VlocityMatchingKeyObject", "VlocityMatchingRecordSourceKey": "OmniProcess/Type/SubType/Language", "VlocityRecordSObjectType": "OmniProcess" }, "PropertySetConfig": { "elementValueMap": {}, "executionConditionalFormula": "", "id": "", "isActive": true }, "Type": "Set Values", "VlocityDataPackType": "SObject", "VlocityRecordSObjectType": "OmniProcessElement", "VlocityRecordSourceKey": "OmniProcessElement/OmniProcess/Type/SubType/Language/ElementName" } ``` -------------------------------- ### IP Naming Structure Table Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/12-naming-restrictions.md Defines the structure for Integration Procedure keys, including Type, SubType, and Language fields, and their corresponding formats. ```text ┌────────────────┬─────────────────────────┬──────────────────────────────┐ │ Field │ Value │ Notes │ ├────────────────┼─────────────────────────┼──────────────────────────────┤ │ Type │ Namespace or feature │ e.g., "SURA" or "MyProject" │ │ SubType │ Descriptive name │ e.g., "LeadCreateOrchestrator"│ │ Language │ "English" or "Procedure"│ "English" = callable IP │ │ │ │ "Procedure" = internal sub-IP│ ├────────────────┼─────────────────────────┼──────────────────────────────┤ │ IP Key format │ Type_SubType │ SURA_LeadCreateOrchestrator │ │ VlocitySourceKey│ OmniProcess/Type/ │ OmniProcess/SURA/ │ │ │ SubType/Language │ LeadCreateOrchestrator/English│ └────────────────┴─────────────────────────┴──────────────────────────────┘ ``` -------------------------------- ### Create Salesforce Flow Component for Integration Procedure Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/09-invocation.md Define a class with the @InvocableMethod annotation to create a Salesforce Flow component for invoking Integration Procedures. This allows Integration Procedures to be called from Salesforce Flows. ```apex @InvocableMethod public static void invokeIntegrationProcedure(List recordIds) { // Implementation to invoke Integration Procedure } ``` -------------------------------- ### Checking Object Fields for Data Instead of ISBLANK() Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/14-formula-gotchas.md The ISBLANK() function returns false for objects even if all their fields are empty. To accurately check if an object contains meaningful data, individual fields must be checked. ```json "hasOwnerData": "=IF(NOT(ISBLANK(%owner:first_name%)),true,IF(NOT(ISBLANK(%owner:last_name%)),true,IF(NOT(ISBLANK(%owner:email%)),true,false)))" ``` -------------------------------- ### Invoke Integration Procedure with @future Annotation Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/10-invocation-from-apex.md Executes an Integration Procedure asynchronously using the @future annotation. This is suitable for background processing where immediate results are not required. ```Apex String ipName = 'FindContacts_LastNames'; String inputMap = '{"ContactLastName": "Smith"}'; String optionsMap = '{"isDebug": false}'; devopsimpkg11.IntegrationProcedureService.runIntegrationServiceFuture(ipName, inputMap, optionsMap); ``` -------------------------------- ### Working Nested IFs for NOT(OR(...)) in executionConditionalFormula Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/14-formula-gotchas.md This shows the correct workaround for the NOT(OR(...)) limitation in executionConditionalFormula by using nested IF statements to achieve the desired logic. ```json "executionConditionalFormula": "IF(%flag1% = true, false, IF(%flag2% = true, false, IF(%flag3% = true, false, true)))" ``` -------------------------------- ### DataPack.json Critical Fields Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/13-datapack-structure.md Key fields within the main DataPack.json file that define the Integration Procedure's execution order, identity, and language. ```json { "OmniProcessElement[]": [ "Set_Input", "Set_HasData", "If_No_Update_Data", "Response_No_Update_Data", "ValidateLead" ], "OmniProcessKey": "SURA_LeadUpdateOrchestrator", "Type": "SURA", "SubType": "LeadUpdateOrchestrator", "Language": "English", "IsIntegrationProcedure": true } ``` -------------------------------- ### Loop Block Iteration Result Structure Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/02-work-with-data-and-lists.md When a Loop Block iterates over the 'Products.Ids' list, each iteration processes a single element nested within the original list structure. ```json { "Products": { "Ids": { "Id": 1 } } } ``` -------------------------------- ### Broken Boolean Comparison in executionConditionalFormula Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/14-formula-gotchas.md Boolean flags from Set Values must be explicitly compared with '= true' or '= false' in executionConditionalFormula. Using the flag directly as a truthy/falsy value will cause the step to always or never run. ```json "executionConditionalFormula": "%Set_HasData:hasOwnerData%" ``` -------------------------------- ### Execute Action if Contact First Name is Blank Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/04-execution-logic.md Use this formula in the Execution Conditional Formula field to execute an action or block only when the Contact First Name is empty. The formula evaluates to TRUE if the FirstName field is an empty string. ```text %ContactInfo:FirstName% == "" ``` -------------------------------- ### Clear Integration Procedure Metadata Cache Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/06-caching.md Use this Apex code to clear the metadata cache for a specific Integration Procedure. Replace 'Type_Subtype' with the actual key of your Integration Procedure. ```Apex ConnectApi.IntegrationProcedureCacheInputRepresentation finalInput = new ConnectApi.IntegrationProcedureCacheInputRepresentation(); ConnectApi.IntegrationProcedureCacheInputData apexInput = new ConnectApi.IntegrationProcedureCacheInputData(); apexInput.ipKey = ipKey; List l = new List(); l.add(apexInput); finalInput.ipInput = l; finalInput.cacheStorageType = ConnectApi.CacheStorageType.Metadata; ConnectApi.IntegrationProcedureCacheOutputRepresentation test = ConnectApi.OmniDesignerConnect.ClearIntegrationProcedureCache(finalInput); ``` -------------------------------- ### Broken AND() with 3+ Arguments in executionConditionalFormula Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/14-formula-gotchas.md The AND() function in Vlocity does not reliably work with 3 or more arguments in executionConditionalFormula, leading to silent failures. Use nested IF statements with 2-argument AND() instead. ```json "executionConditionalFormula": "NOT(OR(AND(a, b), AND(a, b, c)))" ``` -------------------------------- ### Child Element Structure within Blocks Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/13-datapack-structure.md Structure for elements nested within Conditional or Try-Catch Blocks, requiring parent references to establish the relationship. ```json { "ParentElementId": { "Name": "ParentBlockName", "OmniProcessId": { "Name": "IP_Name_As_In_Org", "VlocityDataPackType": "VlocityMatchingKeyObject", "VlocityMatchingRecordSourceKey": "OmniProcess/Type/SubType/Language", "VlocityRecordSObjectType": "OmniProcess" }, "VlocityDataPackType": "VlocityMatchingKeyObject", "VlocityRecordSourceKey": "OmniProcessElement/OmniProcess/Type/SubType/Language/ParentBlockName", "VlocityRecordSObjectType": "OmniProcessElement" }, "ParentElementName": "ParentBlockName", "ParentElementType": "Conditional Block" } ``` -------------------------------- ### Broken NOT(OR(...)) Wrapper in executionConditionalFormula Source: https://github.com/slorenzot/context7-llm-omnistudio-integration-procedures/blob/main/14-formula-gotchas.md The NOT(OR(...)) pattern fails silently in executionConditionalFormula. Use nested IF statements that return true/false instead. ```json "executionConditionalFormula": "NOT(OR(%flag1%, %flag2%, %flag3%))" ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.