Send Task - Send Messages and Notifications
Send Task sends messages, emails, SMS, or notifications as part of your workflow. It's designed for one-way communication with external systems or users.
Overview
A Send Task allows you to:
- ✅ Send emails to users or teams
- ✅ Send SMS notifications
- ✅ Push notifications to mobile apps
- ✅ Webhook calls to external systems
- ✅ Queue messages for processing
- ✅ Log events to external systems
Properties
Required Properties
| Property | Type | Required | Description |
|---|---|---|---|
TaskType | string | Yes | Must be "SendTask" |
Name | string | Yes | Display name |
messageType | string | Yes | Type of message (email, sms, webhook, notification) |
Optional Properties
| Property | Type | Default | Description |
|---|---|---|---|
to | string/array | null | Recipient(s) |
subject | string | null | Message subject (email) |
body | string | null | Message content |
template | string | null | Template name |
templateData | JSON | null | Data for template |
retries | int | 0 | Number of retry attempts |
retryBackoff | int | 1000 | Delay between retries (ms) |
Message Types
1. Email
Send email notifications:
<bpmn:sendTask id="SendApprovalEmail" name="Send Approval Email">
<bpmn:extensionElements>
<custom:properties>
<custom:property name="messageType" value="email"/>
<custom:property name="to" value="context.applicantEmail"/>
<custom:property name="subject" value="Loan Application Approved"/>
<custom:property name="template" value="loan-approval-email"/>
<custom:property name="templateData" value="{
"applicantName": "context.applicantName",
"loanAmount": "context.loanAmount",
"approvedBy": "context.approvedBy",
"approvalDate": "context.approvalDate"
}"/>
<custom:property name="retries" value="3"/>
</custom:properties>
</bpmn:extensionElements>
</bpmn:sendTask>
2. SMS
Send SMS notifications:
<bpmn:sendTask id="SendOTP" name="Send OTP via SMS">
<bpmn:extensionElements>
<custom:properties>
<custom:property name="messageType" value="sms"/>
<custom:property name="to" value="context.phoneNumber"/>
<custom:property name="body" value="Your OTP is: {{context.otpCode}}. Valid for 5 minutes."/>
<custom:property name="retries" value="2"/>
</custom:properties>
</bpmn:extensionElements>
</bpmn:sendTask>
3. Push Notification
Send mobile push notifications:
<bpmn:sendTask id="SendPushNotification" name="Notify Mobile App">
<bpmn:extensionElements>
<custom:properties>
<custom:property name="messageType" value="push"/>
<custom:property name="to" value="context.userId"/>
<custom:property name="title" value="Payment Processed"/>
<custom:property name="body" value="Your payment of ${{context.amount}} was successful"/>
<custom:property name="data" value="{
"transactionId": "context.transactionId",
"action": "VIEW_TRANSACTION"
}"/>
</custom:properties>
</bpmn:extensionElements>
</bpmn:sendTask>
4. Webhook
Call external webhook:
<bpmn:sendTask id="NotifyPartner" name="Notify Partner System">
<bpmn:extensionElements>
<custom:properties>
<custom:property name="messageType" value="webhook"/>
<custom:property name="url" value="https://partner.com/api/notifications"/>
<custom:property name="method" value="POST"/>
<custom:property name="body" value="{
"eventType": "LOAN_APPROVED",
"loanId": "context.loanId",
"customerId": "context.customerId",
"amount": "context.loanAmount",
"timestamp": "context.approvalDate"
}"/>
<custom:property name="headers" value="{
"Authorization": "Bearer API_KEY",
"Content-Type": "application/json"
}"/>
<custom:property name="retries" value="3"/>
<custom:property name="retryBackoff" value="2000"/>
</custom:properties>
</bpmn:extensionElements>
</bpmn:sendTask>
Using Scripts for Dynamic Content
Generate message content dynamically:
<bpmn:sendTask id="SendCustomEmail" name="Send Personalized Email">
<bpmn:extensionElements>
<custom:properties>
<custom:property name="messageType" value="email"/>
<custom:property name="preScript"><![CDATA[
// Build recipient list dynamically
var recipients = [];
if (context.notifyManager) {
recipients.push(context.managerEmail);
}
if (context.notifyApplicant) {
recipients.push(context.applicantEmail);
}
if (context.amount > 100000) {
recipients.push('director@bank.com');
}
context.emailRecipients = recipients.join(',');
// Build dynamic subject
context.emailSubject = context.approved
? 'Loan Approved - ' + context.loanId
: 'Loan Application Requires Attention - ' + context.loanId;
// Build dynamic body
context.emailBody = `
Dear ${context.applicantName},
Your loan application for $${context.loanAmount.toLocaleString()}
has been ${context.approved ? 'approved' : 'reviewed'}.
Application ID: ${context.loanId}
Status: ${context.status}
${context.approved ? 'Approved by: ' + context.approvedBy : ''}
Best regards,
Loan Department
`;
]]></custom:property>
<custom:property name="to" value="context.emailRecipients"/>
<custom:property name="subject" value="context.emailSubject"/>
<custom:property name="body" value="context.emailBody"/>
</custom:properties>
</bpmn:extensionElements>
</bpmn:sendTask>
Common Patterns
Pattern 1: Multi-Recipient Email
Send to multiple recipients:
<bpmn:sendTask id="NotifyTeam" name="Notify Approval Team">
<bpmn:extensionElements>
<custom:properties>
<custom:property name="messageType" value="email"/>
<custom:property name="to" value="manager@bank.com,director@bank.com,compliance@bank.com"/>
<custom:property name="subject" value="High-Value Loan Requires Approval"/>
<custom:property name="template" value="high-value-loan-notification"/>
<custom:property name="templateData" value="{
"loanAmount": "context.loanAmount",
"applicantName": "context.applicantName",
"riskLevel": "context.riskLevel",
"dashboardLink": "https://portal.bank.com/loans/context.loanId"
}"/>
</custom:properties>
</bpmn:extensionElements>
</bpmn:sendTask>
Pattern 2: Conditional Notifications
Send different messages based on conditions:
<bpmn:exclusiveGateway id="CheckApprovalStatus" name="Approved?"/>
<!-- Approved notification -->
<bpmn:sendTask id="SendApprovalEmail" name="Send Approval Email">
<bpmn:extensionElements>
<custom:properties>
<custom:property name="messageType" value="email"/>
<custom:property name="to" value="context.applicantEmail"/>
<custom:property name="template" value="loan-approved"/>
<custom:property name="templateData" value="{
"applicantName": "context.applicantName",
"loanAmount": "context.loanAmount",
"interestRate": "context.interestRate",
"nextSteps": "SIGN_DOCUMENTS"
}"/>
</custom:properties>
</bpmn:extensionElements>
</bpmn:sendTask>
<!-- Rejection notification -->
<bpmn:sendTask id="SendRejectionEmail" name="Send Rejection Email">
<bpmn:extensionElements>
<custom:properties>
<custom:property name="messageType" value="email"/>
<custom:property name="to" value="context.applicantEmail"/>
<custom:property name="template" value="loan-rejected"/>
<custom:property name="templateData" value="{
"applicantName": "context.applicantName",
"rejectionReason": "context.rejectionReason",
"appealProcess": "CONTACT_SUPPORT"
}"/>
</custom:properties>
</bpmn:extensionElements>
</bpmn:sendTask>
Pattern 3: Escalation Notifications
Send escalation emails:
<bpmn:process id="ApprovalEscalation" name="Approval with Escalation">
<bpmn:userTask id="ManagerApproval" name="Manager Approval">
<!-- ... -->
</bpmn:userTask>
<!-- Timeout after 24 hours -->
<bpmn:boundaryEvent id="ApprovalTimeout"
attachedToRef="ManagerApproval"
cancelActivity="false">
<bpmn:timerEventDefinition>
<bpmn:timeDuration>P1D</bpmn:timeDuration>
</bpmn:timerEventDefinition>
</bpmn:boundaryEvent>
<!-- Send escalation email (non-interrupting) -->
<bpmn:sendTask id="SendEscalation" name="Send Escalation Email">
<bpmn:extensionElements>
<custom:properties>
<custom:property name="messageType" value="email"/>
<custom:property name="to" value="director@bank.com"/>
<custom:property name="subject" value="URGENT: Approval Pending for 24 Hours"/>
<custom:property name="body"><![CDATA[
Dear Director,
The following loan approval has been pending for 24 hours:
Loan ID: {{context.loanId}}
Applicant: {{context.applicantName}}
Amount: ${{context.loanAmount}}
Assigned to: {{context.assignedManager}}
Please review or reassign immediately.
View: https://portal.bank.com/loans/{{context.loanId}}
]]></custom:property>
</custom:properties>
</bpmn:extensionElements>
</bpmn:sendTask>
</bpmn:process>
Pattern 4: Status Updates
Send periodic status updates:
<bpmn:sendTask id="SendStatusUpdate" name="Send Progress Update">
<bpmn:extensionElements>
<custom:properties>
<custom:property name="messageType" value="email"/>
<custom:property name="to" value="context.applicantEmail"/>
<custom:property name="subject" value="Application Progress Update"/>
<custom:property name="preScript"><![CDATA[
// Calculate progress
var totalSteps = 5;
var currentStep = context.completedSteps;
var progressPercent = (currentStep / totalSteps * 100).toFixed(0);
var steps = [
{ name: 'Application Submitted', status: 'COMPLETED' },
{ name: 'Identity Verification', status: context.completedSteps >= 2 ? 'COMPLETED' : 'IN_PROGRESS' },
{ name: 'Credit Check', status: context.completedSteps >= 3 ? 'COMPLETED' : 'PENDING' },
{ name: 'Approval Review', status: context.completedSteps >= 4 ? 'COMPLETED' : 'PENDING' },
{ name: 'Document Signing', status: context.completedSteps >= 5 ? 'COMPLETED' : 'PENDING' }
];
context.progressData = {
percent: progressPercent,
currentStep: currentStep,
totalSteps: totalSteps,
steps: steps
};
]]></custom:property>
<custom:property name="template" value="progress-update"/>
<custom:property name="templateData" value="context.progressData"/>
</custom:properties>
</bpmn:extensionElements>
</bpmn:sendTask>
Error Handling (Phase 5)
Handle send failures with retry and error boundaries:
<bpmn:sendTask id="SendCriticalEmail" name="Send Critical Email">
<bpmn:extensionElements>
<custom:properties>
<custom:property name="messageType" value="email"/>
<custom:property name="to" value="context.recipientEmail"/>
<custom:property name="subject" value="Critical Alert"/>
<custom:property name="body" value="context.alertMessage"/>
<custom:property name="retries" value="3"/>
<custom:property name="retryBackoff" value="5000"/>
</custom:properties>
</bpmn:extensionElements>
</bpmn:sendTask>
<!-- Catch send failures -->
<bpmn:boundaryEvent id="SendFailed"
attachedToRef="SendCriticalEmail"
cancelActivity="true">
<bpmn:errorEventDefinition errorRef="SendError" />
</bpmn:boundaryEvent>
<!-- Fallback: Log or use alternative channel -->
<bpmn:scriptTask id="HandleSendFailure" name="Use Fallback Channel">
<bpmn:script>
var error = context._lastError;
logger.error('Email send failed: ' + error.errorMessage);
// Try SMS as fallback
if (context.phoneNumber) {
logger.info('Falling back to SMS');
BankLingo.ExecuteCommand('SendSMS', {
to: context.phoneNumber,
body: 'Critical alert - check your email or portal'
});
} else {
// Log for manual follow-up
BankLingo.ExecuteCommand('LogFailedNotification', {
recipient: context.recipientEmail,
message: context.alertMessage,
error: error.errorMessage
});
throw new BpmnError('NOTIFICATION_FAILED',
'All notification channels failed');
}
</bpmn:script>
</bpmn:scriptTask>
<bpmn:error id="SendError" errorCode="SEND_ERROR" />
Integration with BankLingo Commands
Send Task typically calls backend commands:
Code Removed
Implementation details removed for security.
Contact support for implementation guidance.
Best Practices
✅ Do This
<!-- ✅ Use templates for consistent formatting -->
<custom:property name="template" value="loan-approval-email"/>
<!-- ✅ Add retries for reliability -->
<custom:property name="retries" value="3"/>
<custom:property name="retryBackoff" value="2000"/>
<!-- ✅ Use preScript for dynamic content -->
<custom:property name="preScript" value="..."/>
<!-- ✅ Add error boundaries -->
<bpmn:boundaryEvent id="SendError" attachedToRef="SendEmail">
<bpmn:errorEventDefinition/>
</bpmn:boundaryEvent>
<!-- ✅ Validate recipients -->
<custom:property name="preScript"><![CDATA[
if (!context.recipientEmail || !context.recipientEmail.includes('@')) {
throw new BpmnError('INVALID_EMAIL', 'Invalid recipient email');
}
]]></custom:property>
⌠Don't Do This
<!-- ⌠No retries (single failure = lost notification) -->
<bpmn:sendTask id="SendEmail" name="Send Email">
<!-- Missing retries -->
</bpmn:sendTask>
<!-- ⌠Hardcoded content (not maintainable) -->
<custom:property name="body" value="Your loan was approved"/>
<!-- ⌠No error handling -->
<!-- Missing boundary event for failures -->
<!-- ⌠Sensitive data in plain text -->
<custom:property name="body" value="Your PIN is: 1234"/>
<!-- Should use secure channels or encryption -->
Performance Tips
- ✅ Use templates instead of dynamic content generation
- ✅ Batch notifications when possible (multi-recipient)
- ✅ Add timeouts for webhook calls
- ✅ Use async boundaries for non-critical notifications
- ✅ Log all send attempts for audit
Related Documentation
- Script Task - For dynamic content generation
- Receive Task - For receiving responses
- Error Handling - Send failure handling
- Async Boundaries - Background sending
Features Used:
- Core: Send Task
- Phase 5: Error Handling
Status: ✅ Production Ready
Version: 2.0
Last Updated: January 2026