Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
nabheetscn
Active Contributor
PS: Demo At the end

Motivation


The trigger for this workflow is an awesome ASUG SAP Cloud Workflow Webcast by christian.loos and Peter yesterday. One of the question asked was can we do workflow approval via outlook/emails etc. As suggested by christian.loos, yes it can be done I thought of trying it out. The hint provided was by using API's it can be done.

Problem Statement


Can we provide approvals via outlook/email using SAP Cloud Platform Workflow approvals?


Technology Stack used for Solution



  • SAP Cloud Workflow

  • SAP Cloud Workflow API’s

  • Out Old is Gold PHP for consuming the API’s


Solution



  • The first approach which came to my mind was to send an email before the user task which will contain hyperlinks for approval and reject. This approve and reject will call my PHP Script which internally will consume SAP Cloud workflow API’s. The road block which I faced was that the user task is created after the mail step. The task instance id of user task is not known, while sending the email. so practically it will be impossible to find the task instance id.

  • Then i thought how it works in our old SAP Business workflow, we have the concept of Extended Workflow Notification which runs report SWN_SELSEN periodically to send emails for the pending work items, but here we don’t have such concept as of now.

  • I needed something which gets triggered after task is created, something like escalation or deadline monitoring. As luck had it on searching further came to know about boundary events which can be triggered at an interval for a task. All I need to do was to create a boundary event which will be triggered after one minute, the call a script task to update workflow context with task instance id and send the mail with an html template, Bingo the solution was here.


High Level Design



Workflow Design



PHP Script Used, HTML Email file and Script JS file.


The reason I am providing it in separate sub section is someone might struggle in understanding what format to be used to access the variables.

PHP Script


<?php
$method = $_SERVER['REQUEST_METHOD'];
$decisiondata = explode("/", $_SERVER['PATH_INFO']);
$username = '<cloud username>';
$password = '<password>';
// Get XCSRF token
$ch = curl_init('https://bpmworkflowruntimewfs-<username>trial.hanatrial.ondemand.com/workflow-service/rest/v1/xsrf-token');
$request_headers = array();
$request_headers[] = 'X-CSRF-Token: Fetch';
$request_headers[] = 'Content-Type: application/json';
$request_headers[] = 'Accept: application/json';
$request_headers[] = 'APIKey: <key>';
curl_setopt($ch, CURLOPT_HTTPHEADER, $request_headers);
curl_setopt($ch, CURLOPT_POST, 0);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_HEADERFUNCTION, function($curl, $header) use (&$headers)
{
$len = strlen($header);
$header = explode(':', $header, 2);
if (count($header) < 2) { // ignore invalid headers
return $len;
}
$name = strtolower(trim($header[0]));
if (!array_key_exists($name, $headers)) {
$headers[$name] = [trim($header[1])];
} else {
$headers[$name][] = trim($header[1]);
}
return $len;
});
$tmpfname = dirname(__FILE__) . '/cookie.dat';
curl_setopt($ch, CURLOPT_COOKIESESSION, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, $tmpfname);
$resp = curl_exec($ch);


// Update task and decision
$context = array();
$context["context"]["Decision"] = $decisiondata[2];
$context["status"] = "COMPLETED";
curl_setopt($ch, CURLOPT_URL, 'https://bpmworkflowruntimewfs-<user account>trial.hanatrial.ondemand.com/workflow-service/rest/v1/task-instances/' . $decisiondata[1]);
$request_headers = array();
$request_headers[] = 'X-CSRF-Token: ' . $headers['x-csrf-token'][0];
$request_headers[] = 'Content-Type: application/json';
$request_headers[] = 'Accept: application/json';
$request_headers[] = 'APIKey: <api key>';
$request_headers[] = 'Content-Length: ' . strlen(json_encode($context));
$request_headers[] = 'taskInstanceId:' . $decisiondata[1];
curl_setopt($ch, CURLOPT_HTTPHEADER, $request_headers);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH');
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_HEADERFUNCTION, function($curl, $header) use (&$headers)
{
$len = strlen($header);
$header = explode(':', $header, 2);
if (count($header) < 2) { // ignore invalid headers
return $len;
}
$name = strtolower(trim($header[0]));
if (!array_key_exists($name, $headers)) {
$headers[$name] = [trim($header[1])];
} else {
$headers[$name][] = trim($header[1]);
}
return $len;
});
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($context));
$resp = curl_exec($ch);

// Close request to clear up some resources
curl_close($ch);
var_dump($resp);
?>

HTML file for email


<!DOCTYPE html><html>
<body>
Testing SAP Cloud Workflow Outlook Approval via links in email
<br>
<a href="http://<url>/api/chat/MailApproval.php/${context.taskid}/Approve">Approve</a>
<br>
<a href="http://<url>/api/chat/MailApproval.php/${context.taskid}/Reject">Reject</a>
</body>
</html>

Script Task


$.context.taskid = $.usertasks.usertask1.last.id;
$.context.workflowInstanceId = $.info.workflowInstanceId ;
$.context.workflowDefinitionId = $.info.workflowDefinitionId;

Demo



Wishlist for SAP Cloud Workflow



  • One of the important thing which i feel is missing is concept of extended notifications or something similar.


 

Feel free to provide your feedback, open to all ears.
8 Comments
Labels in this area