Streamline's Automated Workflow Triggers enable you to automatically launch Streamline workflows from within Salesforce using Apex code. This provides advanced control for complex scenarios that require custom logic, bulk processing, or integration with existing Apex infrastructure.
Common use cases include:
- Complex multi-object validation before triggering workflows
- Bulk processing with custom batching logic and priority ordering
- Integration with existing Apex frameworks
- Platform event-driven workflows from external systems
Key Concepts
-
Resume URL: The Resume URL (also called session URL) is a unique web link generated by Streamline when a workflow is initiated. This URL allows users to access and complete their workflow tasks. For example, when a contract generation workflow is triggered, the Resume URL might look like: https://us.streamline.intellistack.app/sessions/abc123xyz. This URL can be:
- Stored in a Salesforce field for easy access
- Sent via email to stakeholders
- Internal ID (format: INT-1762900715455-2eccc1f0-XXXXXXXX): This is the identifier you'll use in all Flow and Apex automation. This is the only ID needed for the setup described in this article.
- Project ID: References the Streamline project containing your workflow. Not used in Flow or Apex automation.
- Webhook ID: Identifier for the Streamline incoming webhook step. Not needed for standard Flow or Apex automation.
Prerequisites
Before you can use automated workflow triggers, ensure you have:
- Streamline for the Salesforce Managed Package installed in your Salesforce org
- Streamline Admin permission set assigned to your user account (required to create workflow triggers)
- Basic understanding of Apex development
Part 1: Setting Up a Workflow Trigger
Before you can automate workflows from Salesforce, you must first create a workflow trigger in the Streamline managed package interface.
Step 1: Navigate to Workflow Triggers
- In Salesforce, click the App Launcher (waffle icon)
- Search for and select Streamline
- Navigate to the Workflow triggers page
- Click + New workflow trigger
Step 2: Configure the Workflow Trigger
Follow the instructions in the How to Add a Streamline Workflow Button and Track CLM Status in Salesforce article to setup the workflow trigger.
Note: When configuring your workflow trigger, pay close attention to the Salesforce object you select. This object must match the object you'll be triggering from in your Flow or Apex code. For instance, if you plan to trigger workflows from Opportunity records, ensure your workflow trigger is configured for the Opportunity object.
Step 3: Retrieve the Internal ID
Once created, you'll need the Internal ID to use this trigger in your automation:
- From the Workflow triggers list, click on the trigger's Label (hyperlink)
- This opens the Salesforce record for the workflow trigger
- Copy the Internal ID value (format: INT-{numbers}-{alphanumeric})
- You'll use this Internal ID in your Flow or Apex code
Note: You can also find the Webhook ID in the Details tab, which may be needed for certain API calls.
Part 2: Accessing the Developer Console
Before you can create Apex triggers or classes, you need to access Salesforce's Developer Console:
- In Salesforce, click the gear icon (⚙️) in the upper right corner
- Select Developer Console from the dropdown menu
- A new window will open with the Developer Console interface
Note: Verify that your workflow trigger in the Streamline for Salesforce app is configured for the same object that will be used for the Apex. If your Apex is triggered by Account record changes, your workflow trigger must be set up for the Account object
Part 3: Implementing Apex Automation
Apex triggers allow you to execute logic when records are created, updated, or deleted. Use Streamline's Intellistack.StreamlineFacade.sendRecordToStreamline() method to trigger workflows.
Example: Auto-Generate Contracts When Opportunity Closes Won
When a sales opportunity reaches "Closed Won" stage, automatically generate a contract in Streamline and route it for signature, storing the signing URL back on the Opportunity record for easy access.
Create the Apex Trigger
/**
* @description Trigger for Opportunity object
* Auto-generates contracts when opportunities close
*/
trigger OpportunityTrigger on Opportunity(after update) {
if (Trigger.isAfter && Trigger.isUpdate) {
OpportunityTriggerService.handleClosedWon(Trigger.new, Trigger.oldMap);
}
}Create the Trigger Handler Class
/**
* @description Service class for Opportunity trigger operations
*/
public class OpportunityTriggerService {
public static void handleClosedWon(
List<Opportunity> newOpps,
Map<Id, Opportunity> oldMap
) {
// Internal ID for your contract generation workflow trigger
String webhookTriggerInternalId = 'INT-1762900715455-2eccc1f0-XXXXXXXX';
for (Opportunity opp : newOpps) {
Opportunity oldOpp = oldMap.get(opp.Id);
// Check if stage just changed to Closed Won
if (opp.StageName == 'Closed Won' &&
oldOpp.StageName != 'Closed Won') {
try {
Map<String, String> input = new Map<String, String>();
input.put('webhookTriggerInternalId', webhookTriggerInternalId);
input.put('recordId', opp.Id);
input.put('isAsync', 'true');
input.put('fieldNameForResult', 'Contract_Signing_URL__c');
Intellistack.StreamlineFacade.sendRecordToStreamline(input);
System.debug('Contract generation initiated for Opportunity: ' + opp.Id);
} catch (Exception e) {
System.debug(LoggingLevel.ERROR,
'Failed to trigger contract for Opportunity ' + opp.Id + ': ' + e.getMessage());
}
}
}
}
}
Key Points for Apex Triggers
- Must use async execution (isAsync: 'true') because Salesforce triggers do not allow synchronous callouts
- Specify a field to store the resume URL via fieldNameForResult
- Query the workflow trigger using the Streamline_Button__c object to get the Internal ID dynamically
Method 2: Using Batch Apex
For processing large volumes of records, use batch Apex with Streamline's batch processing method. This approach automatically starts a batch job that handles the batching and governor limits. If they want to use their own batch processing they can use the Intellistack.StreamlineFacade.sendRecordToStreamline() method above.
Input Parameters:
-
Map<String, String>
- webhookTriggerInternalId: Internal ID from workflow trigger
- objectApiName: Salesforce object API name (e.g., 'Account')
- whereClause: SQL WHERE conditions to filter records (optional)
- batchSize: Number of records per batch (maximum 99, recommended 20)
- fieldNameForResult: Field to store resume URL (the unique link to access the Streamline workflow session)
Execution Method:
global static void sendRecordToStreamlineBatch2(Map<String, String> input)
Example: Bulk Onboarding Workflows for New Hire Batches
HR needs to process onboarding documentation for 50+ new hires starting on the same date. Rather than clicking a button 50 times, they run a batch process that triggers personalized onboarding workflows for each employee.
Intellistack__Streamline_Button__c button = [
SELECT Intellistack__Internal_ID__c
FROM Intellistack__Streamline_Button__c
WHERE Name = 'New Hire Onboarding'
LIMIT 1
];
String buttonInternalId = button.Intellistack__Internal_ID__c;
String objectApiName = 'Contact';
String whereClause = 'Start_Date__c = 2025-01-15 AND Onboarding_Status__c = \'Pending\'';
Integer batchSize = 20;
String fieldNameForResult = 'Onboarding_Portal_URL__c';
Map<String, String> batchParams = new Map<String, String>{
'webhookTriggerInternalId' => buttonInternalId
'objectApiName' => objectApiName,
'whereClause' => whereClause,
'batchSize' => String.valueOf(batchSize),
'fieldNameForResult' => fieldNameForResult
};Batch Processing Details
- Automatic batching: The facade method breaks records into batches of the specified size (Salesforce governor limit max 99)
- Each batch is processed separately to respect governor limits
- Where clause: Add SQL WHERE conditions to filter which records to process
- Resume URL storage: Specify a field where the resume URL will be saved for each processed record
Part 4: Error Handling and Validation
Understanding the errors that Streamline's Apex methods can throw helps you build robust error handling into your automation.
Validation Errors
These errors occur when required parameters are missing or invalid:
1. Missing webhookTriggerInternalId
- Error Message: Webhook Trigger Internal ID cannot be null or empty
- Cause: The Internal ID parameter was not provided or is empty
- Solution: Verify you've copied the correct Internal ID from your workflow trigger record
2. Missing recordId
- Error Message: Record ID cannot be null or empty
- Cause: No Salesforce record ID was provided to the method
- Solution: Ensure you're passing a valid Salesforce record ID (typically from Trigger.new or a query)
Synchronous Execution Errors
These errors occur during synchronous workflow execution:
3. Empty webhook response
- Error Message: Webhook execution returned empty response
- Cause: Streamline API returned a blank response, indicating a silent failure
- Solution: Check Streamline workflow configuration and verify the workflow trigger is active
4. Invalid JSON
- Error Message: Invalid webhook response format: <JSONException message>
- Cause: The response from Streamline could not be parsed as valid JSON
- Solution: Check debug logs for the actual response; may indicate a server error or network issue
5. Unexpected deserialization issue
- Error Message: Failed to process webhook response: <Exception message>
- Cause: JSON structure doesn't match expected format (missing fields, wrong data types)
- Solution: Review debug logs; may require updating to a newer version of the managed package
Service-Layer Errors
These errors come from the underlying service infrastructure:
6. StreamlineProjectsLWCService failures
- Error Message: Webhook execution failed: <StreamlineProjectsLWCServiceException message>
- Cause: HTTP callout failures, authentication errors, missing metadata, or validation issues
-
Common Scenarios:
- Network connectivity issues
- Invalid or expired authentication credentials
- Workflow trigger not found in Streamline
- Object mismatch between workflow trigger and Apex code
-
Solution:
-
Verify Remote Site Settings are configured
- Access Streamline for Salesforce app - if any of the necessary remote site settings are missing or not active you will see an error message
- Check that the workflow trigger exists and is active
- Confirm object alignment between Streamline trigger and Apex code
-
Verify Remote Site Settings are configured
7. Unexpected runtime failures
- Error Message: Unexpected error during webhook execution: <Exception message>
- Cause: Unforeseen Apex exceptions during execution
- Solution: Review full stack trace in debug logs; may require support assistance
Batch Processing Errors
The batch methods (sendRecordToStreamlineBatch and sendRecordToStreamlineBatch2) execute using Salesforce's standard batch framework and do not raise custom errors themselves. However, you may encounter:
- Invalid SOQL syntax: Check your whereClause parameter for syntax errors
- Permission errors: Ensure the running user has access to the specified object and fields
- Governor limit exceptions: Reduce batch size or optimize queries
- Standard batch platform exceptions: Review batch job details in Setup → Apex Jobs
Asynchronous vs. Synchronous Error Handling
Asynchronous Execution (isAsync = 'true'):
- Skips response parsing entirely
- Returns a placeholder message: Async request initiated. Resume URL will be saved to field: <fieldName>
- Actual errors during workflow execution will not be visible in the calling code
- Resume URL is written to the specified field once workflow processing completes
- Check the target field and Streamline logs to verify success
Synchronous Execution (isAsync = 'false'):
- Waits for complete response from Streamline
- Returns actual Resume URL when successful
- Throws exceptions immediately if any validation or execution errors occur
- Better for debugging since errors surface immediately
Technical Limitations and Constraints
Apex Limitations
-
Callouts from Triggers
- Salesforce triggers do not allow synchronous callouts
- Always use async execution (isAsync: 'true') in trigger context
-
Governor Limits
- Be mindful of Salesforce's daily API call limits
- Each record processed triggers one API call to Streamline
- Consider batch sizes carefully for large-volume operations
Troubleshooting Common Issues and Solutions
| Issues | Solutions |
| "Workflow trigger not found" error | Verify the Internal ID is correct, and the workflow trigger exists in Streamline |
| "Field does not exist" error in async triggers | Ensure the fieldNameForResult field exists on the object and is spelled correctly (use API name) |
| Batch job not processing all records | Check Salesforce debug logs for governor limit exceptions; reduce batch size |
| Resume URL not saved to record | Verify the field is writable and the user has edit permission on that field |
| Workflow executes but fails or returns unexpected results | Check that your workflow trigger in Streamline for Salesforce is configured for the same Salesforce object as your Flow or Apex code. Go to the workflow trigger record in Salesforce and verify the object selection matches your automation code. |
Comments
0 comments
Article is closed for comments.