Skip to main content

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

PropertyTypeRequiredDescription
TaskTypestringYesMust be "SendTask"
NamestringYesDisplay name
messageTypestringYesType of message (email, sms, webhook, notification)

Optional Properties

PropertyTypeDefaultDescription
tostring/arraynullRecipient(s)
subjectstringnullMessage subject (email)
bodystringnullMessage content
templatestringnullTemplate name
templateDataJSONnullData for template
retriesint0Number of retry attempts
retryBackoffint1000Delay 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="{
&quot;applicantName&quot;: &quot;context.applicantName&quot;,
&quot;loanAmount&quot;: &quot;context.loanAmount&quot;,
&quot;approvedBy&quot;: &quot;context.approvedBy&quot;,
&quot;approvalDate&quot;: &quot;context.approvalDate&quot;
}"/>
<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="{
&quot;transactionId&quot;: &quot;context.transactionId&quot;,
&quot;action&quot;: &quot;VIEW_TRANSACTION&quot;
}"/>
</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="{
&quot;eventType&quot;: &quot;LOAN_APPROVED&quot;,
&quot;loanId&quot;: &quot;context.loanId&quot;,
&quot;customerId&quot;: &quot;context.customerId&quot;,
&quot;amount&quot;: &quot;context.loanAmount&quot;,
&quot;timestamp&quot;: &quot;context.approvalDate&quot;
}"/>
<custom:property name="headers" value="{
&quot;Authorization&quot;: &quot;Bearer API_KEY&quot;,
&quot;Content-Type&quot;: &quot;application/json&quot;
}"/>
<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="{
&quot;loanAmount&quot;: &quot;context.loanAmount&quot;,
&quot;applicantName&quot;: &quot;context.applicantName&quot;,
&quot;riskLevel&quot;: &quot;context.riskLevel&quot;,
&quot;dashboardLink&quot;: &quot;https://portal.bank.com/loans/context.loanId&quot;
}"/>
</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="{
&quot;applicantName&quot;: &quot;context.applicantName&quot;,
&quot;loanAmount&quot;: &quot;context.loanAmount&quot;,
&quot;interestRate&quot;: &quot;context.interestRate&quot;,
&quot;nextSteps&quot;: &quot;SIGN_DOCUMENTS&quot;
}"/>
</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="{
&quot;applicantName&quot;: &quot;context.applicantName&quot;,
&quot;rejectionReason&quot;: &quot;context.rejectionReason&quot;,
&quot;appealProcess&quot;: &quot;CONTACT_SUPPORT&quot;
}"/>
</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

Features Used:

  • Core: Send Task
  • Phase 5: Error Handling

Status: ✅ Production Ready
Version: 2.0
Last Updated: January 2026