Recently I got inspired by some blogs explaining how to integrate SAP S/4HANA OnPrem with ChatGPT – using 3rd party tools such as MS-Azure.
Since more then a decade I have my focus on “pure Public Cloud ERP” and hence on SAP S/4HANA Cloud Public Edition. Also my focus is on midmarket and scaleup/hypergrowth companies who select the “GROW with SAP” bundle of SAP S/4HANA Cloud Public Edition and SAP BTP/CPI.
So in my opinion, it must be possible when buying nothing but this SAP bundle, you are capable to create E2E integration flows. No need to use other tools or brands.
I wanted to create an iFlow which executes the following: automating the reply to an incoming customer email query about the status of an order the customer placed earlier. The automation should parse the incoming query – for a valid SalesOrder number but also the “tone of voice”. S4HC Public gives factual details about the SalesOrder, followed by ChatGPT which crafts a customer-specific email response. Final step is the e-mail reply to the customer.
The motivation for this process I got reading the excellent blog from Sudip Gosh (ChatGPT Integration with S/4HANA).
So I set myself a challenge to integrate S/4HANA Cloud Public Edition with ChatGPT using nothing but SAP BTP/CPI.
Although I am experienced in S4HC Public, I had zero experience in creating iFlows in CPI, nor did I know how to do things like tracing and debugging errors, checking deployment status, creating groovy scripts, taking care of security features etc. So my other challenge was to self-learn how to do all these while “learning on the job” creating my storyline.
It was nice challenge as I learned rapidly new things which I can apply in my daily job as blackbelt presales. “From Rookie to Result” took me a few evenings hobbying – and in this blog I am sharing my meandering experience in the format of a step-by-step explanation how the end-to-end flow works.
In another blog I will describe which skills and experiences it takes to go “From Rookie to Result” – but I am sure anyone is able to learn this too :-). Two very nice learnings here though: 1) my CPI trial account is deployed in the USA Eastcoast area and I am based in NL. Just like using S4HC Public from an SAP datacenter, the CPI performance is phenomanal. 2) Using SAP Digital Assistance during my challenge was a real asset – I was amazed how well it serves its purpose.
The iFlow I created is neither perfect nor ready for productive use – but it serves a purpose to show how to integrate pure public cloud applications into a working prototype. And for other rookies to help saving time, effort and energy searching for sources and examples – which was a big part of those evenings hobbying for me.
My iFlow does take care of security! Although I have chosen to use the simpler UserID/PWD in some steps, CPI provides the means to use the strictest of security if you want. In the next image the green stars indicate where security measurements are used (enforced – as without your iFlow simply won’t work).
The following image shows the working end-to-end iFlow which integrates SAP S/4HANA Cloud Public Edition, ChatGPT and e-mail. The block numbers are used in the text following it.
Block 1. This is a Sender role – and in this iFlow version this is POSTMAN. In a new version of this iFlow the Sender must be reading from an Email system – where CPI offers possibilities to poll an inbox and extract emails from it on any desired frequency and interval.
Block 2. HTTPS Connector
It defines the unique URL used when the iFlow is deployed on BTP, in such a way that a Sender knows what to call:
The /salesorder/detailsv3 is appended to the URL created by CPI when it successfully deploys and starts the iFlow. This full address can be found in CPI Edit mode of the iFlow – click anywhere in the screen to see the following
Block 3. Content Modifier
This stores the incoming payload in a variable property.textToChatGPT so that it can be used in subsequent iFlow steps. In the current version of this iFlow this step can be left out – as I used the property in earlier versions for calling ChatGPT. I leave it in here to show a best practice in keeping the initial payload for reference sake in subsequent iFlow steps.
Block 4. Groovy Script
It takes the input (“payload”) entering the iFlow and parses the text to search for an integer (of a certain minimum number of digits) which is written after the word SalesOrder. The search result is written in property.ExtractSuccess – where 1 is successful and 0 unsuccessful. An integer number found is stored in property.extracted_integer which is used in the API call to S4HC Public.
Note: initially I wanted to use ChatGPT API to parse the text and return the SalesOrder number. This works perfect in the ChatGPT UI but unfortunately is not working consistently in the API. Many hits on the web show that this behaviour is experienced by others often too like this source: https://community.openai.com/t/different-results-chatgpt3-5-vs-api-gpt-3-5-turbo/123712
Block 5. Router
Based on the ExtractSuccess value the route is determined, with the default route being the main line in the iFlow. In case ExtractSuccess = 0 then the Route2 is taken which will lead to sending a failure email and stopping the iFlow.
Block 6. Route 2
This will make the iFlow not to take integration steps but instead jump to replying the customer with an email.
Block 7. Content Modifier
This sets an explanatory text which is used in the email reply being sent. An improvement can be to use the name of the initial sender of the incoming iFlow payload , instead of using the generic “Dear Customer”.
Block 8. Message Flow
This message flow is of type “Mail”. It defines the details for sending an email. The General tab in this iFlow component allows giving it a name and description. In the Processing Tab the email To: and From: addresses are specified. I use hard coded these in this iFlow, but for obvious reasons these should be changed by using property variables. The same could be done with the e-mail Title.
The Connection Tab is used to define the SMTP details which are used (or enforced) by the email system to send out the email. The authentication in this case is User/PWD combination defined at the email system.
The values of the UserID and Password are stored in a credential name – which you create/store in the Security Material tile of CPI
Block 10. Request Reply
This CPI component enables an external call to be made and a reply being received for further processing in the integration flow. Here we perform the API call to SAP S/4HANA Cloud, Public Edition. The API called is a “whitelisted” API which can be activated by setting up a so called “Communication Arrangement” in S4HC – which makes the API available with the desired credentials and access. These credentials are stored in the Keystore just like other credentials.
The Request Reply defines what the URL of the API is, what authentication to use and how its credentials are found. In this iFlow experiment I used basic UserID/Pwd credentials on the API – but for obvious reasons in “real life” cases a stricter policy such as OAuth2.0 should be used. The UserID/Pwd credentials are storied in CPI in the “Credential Name” tag.
The Processing tab defines what the API call is supposed to execute. Here, I perform a GET operation to read a certain amount of fields which are available with the API – in this case I pull only a handful of the 40+ fields this API has to offer. In order to prevent getting back far too many data I let the API filter on the earlier filled “extracted_integer”.
CPI helps you in selecting those XML tags nicely – as you can choose which part of the XML reply from S4HC you are interested in (here – I select A_SalesOrder), then to select the specific tags and finally set up your filter/sort:
When multiple APIs in your S4HC Public Edition system are available, it is pretty easy to toggle to these and select data too.
Block 11. Groovy Script
With the XML based reply received back from S4HC one cannot work directly in an API call to ChatGPT. Therefore I created a groovy script which executes several steps:
- Convert (“parse”) the XML tags from S4HC into static texts
- Create a text line which shows these tags in a sentence. This sentence I store in a variable “info”
- Create additional text which will be interpreted by ChatGPT in order to write an email. This text I store in variable “the_email_content”
- Define the conversation to ChatGPT – here, I want it to act like being a “useful assistant” to reply to the content it gets from a “user”. This content is the combination of “info” and “theemail_content”.
- Determine the Authorization and Content-Type which are both required to call the ChatGPT API in the next iFlow component. Note that here the unique ChatGPT API secret key is used – this key you get from login into ChatGPT API and then select “Generate Secret Key”
Making this groovy scripted was very much helped by using SAP Digital Assistant – which is a GPT4 based tool and a real powerhouse helping you creating and improving groovy scripts – and tons of other things!
it is in groovy script that the “ChatGPT magic” happens in terms of how a reply must be made – I am sure there are better ways, but as I am a rookie in ChatGPT too this is the best I could make given the time I had given myself for my challenge:
I must admit that does look a bit groovy and spooky, ay?
Block 12. Request Reply
Here, I execute the HTTPS call to ChatGPT API. As the message and details were set in my groovy script in Block 11, the HTTP definitions are all it takes to get a response from ChatGPT.
The URL Address I use is associated with gpt-3.5 and is publicly available. In order to let CPI use the API POST it is required to store a certificate from ChatGPT. I had to perform some trial&error in order to get to the proper certificate provider – but once I could get it out an “incognito browser” which opens https://api.openai.com/v1/chat/completions and the “peeling off” the certificate which you store on your laptop then upload into CPI “Keystore”.
Block 13. JSOn to XML Converter
I have been toggling with this step a bit – as it seems not to do much:
But If did not convert the JSON reply from ChatGPT API into XML he last step 14 would gave challenges in properly parsing text. It was here where SAP Digital Assistant gave me good guidance too!
Block 14. Groovy Script
This step executes a the parsing of the incoming XML from step 13 and this script then prepares a readable body text which is used in step 15.
Block 15. Message Flow
This one has exactly the same content as the one in Block8.
So that’s all folks!
How does the end-result look like? Here is a 15 seconds video showing the receiving of an email and looking at its content – things all determined by this iFlow with realtime calls to SAP S/4HANA Cloud Public Edition and ChatGPT being performed in the background.
Finally in this blog I give a few examples of POSTMAN input/output. Note that the results – structure and texts used – differ! This is due to the nature of ChatGPT API and the way how I make it perform its work determined in my Groovy script in Block 11 …
This is a contribution by SAP.