Skip to Content

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.

To report this post you need to login first.

4 Comments

You must be Logged on to comment or reply to a post.

  1. Andy Curtis

    I’m new to CF Wf and each time I think about a feature of Classic Wf that I don’t see in CF Wf, I then find a blog showing me someone else has thought of it and done it.  Great thinking, as an extension to your thinking does it ensure the approve/reject came from the actual agent for the task and not someone the email was forwarded to (or spoofed)?

    (1) 
    1. Nabheet Madan Post author

      Dear Andy

      Thanks for the feedback, at this point of time i believe anyone have this mail can approve it. Another alternative which i can think(feasible or not don’t know as of now have to experiment) somehow let this link send an email to a cloud server location for exmaple integration flow and their we can read through message for decision and proceed. This solution is more or less on similar lines like approving business workflow via email. I am still searching for any other way to resolve this. Will keep you posted.

       

      Thanks

      Nabheet

      (0) 
  2. Phil Cooley

    Nice Former Member  and very timely. We’ve been asked for this exact business requirement – basically whether or not it was possible to Approve or Reject directly from the email. I believe I can now say YES!!!! Thanks! I also attended the ASUG workflow webcasts – really great and love the SCP workflow service.

    Thanks for posting this, really informative.

     

    (0) 
    1. Nabheet Madan Post author

      Thanks Phil for the feedback, ASUG webcasts are amazing. So much to learn in SAP Cloud  or generally the whole technical space.   Lets keep learning and keep sharing our experiences.

      (0) 

Leave a Reply