Advice Needed: Posting a message to the active workflow from an embedded form event

Hey all,
I have an embedded form that queues up some attachments, allows the user to select the attachments and compose an email to the customer then posts it off. This user task remains active and the user can send multiple emails from the task until they select an attachment and complete the task.

Here is the screen:

The section of the workflow looks like this:
Capture Bank Offers is the screen in question
Process Received offers ingest the PDF, parses and does data extraction and attaches it to the workflow. (Adds the attachments to the “New Offers Received” section of the form.
Send Offer Batch to Customer is triggered from the embedded for button “Email batch to customer”
The task can only be completed once an offer is “nominated” (button at the bottom left of the screen)

Screen Shot 2022-03-04 at 09.40.57

Question: What is the best way to post the “Send Offer Batch” message from the embedded form.

Option: Make a REST call to the Camunda REST API.
Issues: How do I configure the endpoint url of the REST API for my different environments? I have only ever seem this hard coded.

Question: Is there a preferred approach to this problem or a better approach.
Contraints: I cannot break the screen into multiple tasks, this needs to be one task.

Thanks in advance!!

Solved it.

NOTE: You have to inject $http like this:

<script cam-script type="text/form-script">
    inject(['$http', 'Uri', function ($http, Uri) {
           // fun stuff in here
    }]);
</script>

Now the fun stuff.
Made a simple function to post to send message:

function sendMessage(payload) {
  // payload definition: https://docs.camunda.org/manual/7.16/reference/rest/message/post-message/#request-body
    $http.post(Uri.appUri('engine://engine/:engine/message'), payload);
}

Also for correlation you will need the business key, so I write this function to get the process definition, which has the business key in it.

function getProcessInstance() {
    $http.get(Uri.appUri('engine://engine/:engine/process-instance/' + camForm.options.processInstanceId))
        .then(function(response) {
            $scope.processInstance = response.data;
        });
}

Call it in this event:

camForm.on('variables-fetched', function () {
    getProcessInstance();
});

Then make a simple event compiling the payload:

$scope.emailBatchToCustomer = function() {
    var batchedOffers = $scope.batchedOffers();
    
    if (batchedOffers.length <= 0) {
        alert("Cannot send the offer email to the customer. The email requires offers be added to the batch");
        return;
    }

    if (!$scope.customerOfferEmailSubject) {
        alert("Please enter a subject before sending the email to the customer");
        return;
    }

    if (!$scope.customerOfferEmailBody) {
        alert("Please enter an email body message before sending the email to the customer.");
        return;
    }

    var batchId = batchedOffers[0].batchId;
    var emailSubject = $scope.customerOfferEmailSubject;
    var emailBody = $scope.customerOfferEmailBody;

    var payload = {
        messageName: "userDidSendOfferBatchMessage",
        businessKey: $scope.processInstance.businessKey,
        correlationKeys: {
            applicationKey: {
                value: $scope.applicationKey, 
                type: "String"
            }
        },
        processVariables: {
            batchId: {
                value: batchId,
                type: "Integer",
                valueInfo: {
                    transient: true
                }
            },
            emailSubject: {
                value: $scope.customerOfferEmailSubject,
                type: "String",
                valueInfo: {
                    transient: true
                }
            },
            emailBody: {
                value: $scope.customerOfferEmailBody,
                type: "String",
                valueInfo: {
                    transient: true
                }
            }
        }
    }

    sendMessage(payload);
}

Hook the event up to the button:

<button 
    type="button" 
    class="btn btn-primary btn-sm" 
    ng-click="emailBatchToCustomer()">
    Email batch to customer
</button>

Hope this helps someone.

1 Like

Thanks a lot for posting such a detailed solution.