Skip to Content
Author's profile photo Nabheet Madan

SAP Cloud Workflow Meet Outlook/Email via API & PHP

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.

Assigned Tags

      8 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo andrew curtis
      andrew 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)?

      Author's profile photo Nabheet Madan
      Nabheet Madan
      Blog 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

      Author's profile photo Phil Cooley
      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.

       

      Author's profile photo Nabheet Madan
      Nabheet Madan
      Blog 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.

      Author's profile photo Abdul Samad Mohammed
      Abdul Samad Mohammed

      Hi Nabheet,

      Excellent post......I have started the R&D and this post just helped in understand a little more specially the presence of usertasks and info in context.....

      Have a little doubt on the linkage of PHP and generation of the url.....can you tell a little for people like me who doesn't have much background.

      Keep blogging 🙂

      Abdul

      Author's profile photo Nabheet Madan
      Nabheet Madan
      Blog Post Author

      Hello Abdul Samad Mohammed

      Thanks for the feedback.  Basically i have my PHP script hosted on my web server. This PHP script interacts with Workflow API's.  The link in the mail for approve and reject points to my php script hosted on my webserver(not disclosing the url) you can host it at your server.

      I hope it is clear. Let me know in case of any further issues.

      Thanks

      Nabheet

      Author's profile photo Abdul Samad Mohammed
      Abdul Samad Mohammed

      Hi Nabheet Madan

       

      Got it working by using XAMPP and hosting it locally from machine. Works exactly as expected...... need to check about hosting it somewhere global(accessible by others).

       

      Thanks

      Abdul

      Author's profile photo Vijay Chintarlapalli
      Vijay Chintarlapalli

      Nabheet Madan  : Is there any way to include workflow instance in email body so that when ever user clicks on the link it takes him to workitem in inbox app ?

      Thanks,

      Vijay