No more an “honorary” but now a full-blown member of the AppsLab team, I gave a presentation at the Chicago & Dubai Oracle Usability Advisory Board in November on REST and Web APIs and how they can facilitate the transition from on-premise software to cloud-based solutions (the content of which can be fodder for a future post).
As we all are transitioning from on-premise implementations to cloud-based solutions, there seems to be a growing fear among customers and partners (ISV, OEM) alike that they will lose the capability to extend these cloud-based applications. After all, they do not have access to the server anymore to deploy and run their own reports/forms/scripts.
I knocked up a very simple JavaScript client side application as part of my presentation to prove my point, which was that (well-designed) REST APIs and these JavaScript frameworks make it trivial to create new applications on top of existing backend infrastructure and add functionality that is not present in the original application.
My example application is based on existing Oracle Sales Cloud Web Services. I added the capability to tweet, send text messages (SMS) and make phone calls straight from my application and speech-enable the UI. Although you can debate the usefulness of how I am using some of these feature, that was obviously not the purpose of this exercise.
Instead, I wanted to show that, with just a few lines of code, you can easily add these extremely complex features to an existing application. When was the last time you wrote a bridge to the Public Switched Telephone Network or a Speech synthesizer that can speak 25 different languages?
Here’s a 40,000 foot view of the architecture:
The application itself is written as a Single Page Application (SPA) in plain JavaScript. It relies heavily on open source JavaScript libraries that are available for free to add functionality like declarative DOM binding and templating (knockout.js), ES6 style Promises (es6-promise.js), AMD loading (require.js) etc. I didn’t have to do anything to add all this functionality (other than including the libraries).
It makes use of the HTML5 Speech Synthesis API, which is now available in most modern browsers to add Text-to-Speech functionality to my application. I didn’t have to do anything to add all this functionality.
I also used the Twitter APIs to be able to send tweets from my application and the Twilio APIs to be able to make phone calls and send SMS text messages from my application. I didn’t have to do anything to add all this functionality. Can you see a theme emerging here?
Finally I used the Oracle Sales Cloud Web Services to display all the Business Objects I wanted to be present in my application, Opportunities, Interactions and Customers. As with the other pieces of functionality, I didn’t have to do anything to add this functionality!
You basically get access to all the functionality of your CRM system through these web services where available, i.e. not every piece of functionality is exposed through web services.
Note that I am not accessing the Web Services directly from my JS but I go through a proxy server in order to adhere to browser’s same-origin policy restrictions. The proxy also decorates the Oracle Applications SOAP Services as REST end-points. If you are interested in how to do this, you can have a look at mine, it’s freely available.
For looks I am using some CSS that makes the application look like a regular ADF application. Of course you don’t have to do this, you can e.g. use bootstrap if you prefer. The point being is that you can make this application look however you want. As I am trying to present this as an extension to an Oracle Cloud Application, I would like it to look like any other Oracle Cloud Application.
With all these pieces in place, it is now relatively easy to create a new application that makes use of all this functionality. I created a single index.html page that bootstraps the JS application on first load. Depending on the menu item that is clicked, a list of Customers, Opportunities or Interactions is requested from Oracle Sales Cloud, and on return, those are laid out in a simple table.
For demonstration purposes, I provided switches to enable or disable each feature. Whenever a feature is enabled and the user would click on something in the table, I would trigger either the phone call, SMS sending, speech or tweet, whichever is enabled, e.g. here is the code to do Text-to-Speech using the HTML5 Speech Synthesis API, currently available in webkit browsers so use Safari or Chrome (mobile or desktop), and yes I have feature detection in the original code, I just left it out to keep the code simple:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
if ($("#speech").is(':checked')) { | |
window.speechSynthesis.cancel(); // Cancel if already talking | |
var msg = new SpeechSynthesisUtterance(event.target.innerText); // Grab the text from the element that was clicked … | |
window.speechSynthesis.speak(msg); // … and speak it. | |
} |
Ditto for the SMS sending using the Twilio API:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var twilio = { | |
username: <your-twilio-username>, | |
pwd: <your-twilio-pwd>, | |
phone: <your-twilio-phone-number>, | |
server_url: 'https://api.twilio.com/2010-04-01/Accounts/' | |
}; | |
var user = { | |
phone: <user-phone-number> | |
}; | |
if ($("#sms").is(':checked')) { | |
$.ajax({ | |
type: "POST", | |
username: twilio.username, | |
password: twilio.pwd, | |
url: twilio.server_url + twilio.username + '/Messages.json', | |
data: { Body: event.target.innerText, From: twilio.phone, To: user.phone } | |
}) | |
.done(function( msg ) { | |
console.log("Message Send"); | |
}); | |
} |
And calling somebody, using the Phone Call API from Twilio, using the same user and twilio object from above:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
if ($("#call").is(':checked')) { | |
$.ajax({ | |
type: "POST", | |
username: twilio.username, | |
password: twilio.pwd, | |
url: twilio.server_url + twilio.username + '/Calls.json', | |
data: { Url: <xml-containing-twilio-message>, From: twilio.phone, To: user.phone } | |
}) | |
.done(function( msg ) { | |
console.log("Phone call made."); | |
}); | |
} |
The tweeting is done by adding the tweet button to the HTML, dynamically filling in the tweet’s content with some text from the Opportunity or Interaction.
Here is a screencast of the application in action:
As I mentioned earlier, how I am using the APIs might not be particularly useful, but the point is to show how easy it is to integrate this functionality with Oracle Cloud Applications to extend the functionality beyond what is delivered out of the box. It probably makes more sense to use Twilio to actually call or text a contact attached to the opportunity or interaction, rather than me. Or to tweet when an opportunity moves to a “win” status, the possibilities are literally endless, but I leave that up to you.
Happy Coding!
Mark.