Skip to main content

Third party APIs examples

These are examples of calls to various third party APIs done on server side. Most examples are using the server-side Rhino scripting language.

Note:

The Rhino-only code examples can easily be transposed to equivalent Java code. Some examples are provided both in Rhino and Java so as you can see the syntax differences.

Apart from the variable and methods declarations syntax, the main point of attention is regarding comparisons syntax for non raw types:

  • Rhino: a == b, Java: a.equals(b)
  • Rhino: a != b, Java: !a.equals(b)

Introduction

Simplicité being a Java platform, calling any HTTP-based can be done using either:

  • Standard low-level HTTP client Java API (java.net.[http.]*)
  • Included HTTP client libraries such as the Apache HTTP Client library
  • Utility classes provided by Simplicité such as com.simplicite.util.HTTPTool or the very simple Tool.readUrl(...), e.g. calling an REST-like API returning a JSON object:
var result = new JSONObject(Tool.readUrl("http(s)://my3rdpartyapi.com/a/b/c?d=e"));
var status = result.getString("myAPIStatus");
(...)

The following non limitative list of examples are describing some specifc cases for which higher level utility classes exists (provided by Simplicité and/or by the vendor of the 3rd party API, e.g. Google APIs). But the same cloud be achieved using one of the low-level above approaches.

Note that some of these 3rd party APIs may need a paying subscription and/or may have a limited free tier.

Calendar

This example is based on the client side Google Calendar API.

Note: As of version 4.0 it is also possible to use the server side Google calendar API wrapped into the GoogleAPI tools class. the example below is kept here for historical reasons.

Google Calendar API

You should have activate Google Oauth2 authentication to use it. See Tomcat OAuth2 authentification

See https://developers.google.com/google-apps/calendar for details.

System parameters

The OAUTH2_SCOPES system param has to contain https://www.googleapis.com/auth/calendar You may want to create GOOGLE_CALENDAR_ID system param to work on a specific calendar.

Code snippet

Here a generic script to use to create, update or delete an event.

Calendar = function(g) {
var grant = g;
var calId = grant.getParameter("GOOGLE_CALENDAR_ID","");
var endpoint = "https://www.googleapis.com/calendar/v3/calendars/";
// For 3.x versions
//var token = new JSONObject(grant.getParameter("GOOGLE_TOKEN", "{}")).optString("access_token", "");
// For version 4.0+
var token = g.getSessionInfo().getToken();

function insert(req) {
var headers = new HashMap();
headers.put("Authorization", "Bearer " + token);
headers.put("Content-type", HTTPTool.getMimeTypeWithEncoding(HTTPTool.MIME_TYPE_JSON, "UTF-8")); // Explicitly set content type as UTF-8-encoded application/json (not needed in version 4.0 if req is a JSONObject/JSONArray)

var url = endpoint + calId + "/events";
var res = Tool.readUrl(url, null, null, req, headers,"UTF-8"); // Must use UTF-8 encoding
return new JSONObject(res);
}

function update(eventId, req) {
var headers = new HashMap();
headers.put("Authorization", "Bearer " + token);
headers.put("Content-type", HTTPTool.getMimeTypeWithEncoding(HTTPTool.MIME_TYPE_JSON, "UTF-8")); // Explicitly set content type as UTF-8-encoded application/json (not needed in version 4.0 if req is a JSONObject/JSONArray)
headers.put("X-HTTP-Method-Override","PUT");

var url = endpoint + calId + "/events/" + eventId;
var res = Tool.readUrl(url, null, null, req, headers,"UTF-8"); // Must use UTF-8 encoding
return new JSONObject(res);
}

function del(eventId) {
var headers = new HashMap();
headers.put("Authorization", "Bearer " + token);
headers.put("Content-type", HTTPTool.getMimeTypeWithEncoding(HTTPTool.MIME_TYPE_JSON, "UTF-8")); // Explicitly set content type as UTF-8-encoded application/json (not needed in version 4.0 if req is a JSONObject/JSONArray)
headers.put("X-HTTP-Method-Override","DELETE");

var url = endpoint + calId + "/events/" + eventId;
var res = Tool.readUrl(url, null, null, "", headers,"UTF-8"); // Must use UTF-8 encoding
return new JSONObject(res);
}

return { insert: insert, update: update, del: del};
};

Java

import java.io.IOException;
import java.util.*;
import org.json.JSONObject;
import com.simplicite.util.*;
import com.simplicite.util.tools.*;

public class Calendar implements java.io.Serializable {
private static final long serialVersionUID = 1L;
Grant grant;
String calId;
String endpoint;
String token;
public Calendar(Grant g){
grant = g;
calId = grant.getParameter("GOOGLE_CALENDAR_ID","");
endpoint = "https://www.googleapis.com/calendar/v3/calendars/";
// For 3.x versions
//token = new JSONObject(grant.getParameter("GOOGLE_TOKEN", "{}")).optString("access_token", "");
// For version 4.0+
token = g.getSessionInfo().getToken();
return;
}
public JSONObject insert(JSONObject data) {
try {
HashMap<String,String> headers = new HashMap();
headers.put("Authorization", "Bearer " + token);
headers.put("Content-type", HTTPTool.getMimeTypeWithEncoding(HTTPTool.MIME_TYPE_JSON, "UTF-8")); // Explicitly set content type as UTF-8-encoded application/json (not needed in version 4.0 if req is a JSONObject/JSONArray)
String url = endpoint + calId + "/events";
String res = Tool.readUrl(url, null, null, data, headers,"UTF-8");
return new JSONObject(res);
} catch (IOException e) {
AppLog.error(e, grant);
} // Must use UTF-8 encoding
return new JSONObject();

}
public JSONObject update(String eventId, String req) {
String res="";
try {
HashMap<String,String> headers = new HashMap();
headers.put("Authorization", "Bearer " + token);
headers.put("Content-type", HTTPTool.getMimeTypeWithEncoding(HTTPTool.MIME_TYPE_JSON, "UTF-8")); // Explicitly set content type as UTF-8-encoded application/json (not needed in version 4.0 if req is a JSONObject/JSONArray)
headers.put("X-HTTP-Method-Override","PUT");
String url = endpoint + calId + "/events/" + eventId;

res = Tool.readUrl(url, null, null, req, headers,"UTF-8"); // Must use UTF-8 encoding
} catch (IOException e) {
AppLog.error(e, grant);
}
return new JSONObject(res);
}
public JSONObject del(String eventId) {
HashMap<String,String> headers = new HashMap();
headers.put("Authorization", "Bearer " + token);
headers.put("Content-type", HTTPTool.getMimeTypeWithEncoding(HTTPTool.MIME_TYPE_JSON, "UTF-8")); // Explicitly set content type as UTF-8-encoded application/json (not needed in version 4.0 if req is a JSONObject/JSONArray)
headers.put("X-HTTP-Method-Override","DELETE");

String url = endpoint + calId + "/events/" + eventId;
String res="";
try {
res = Tool.readUrl(url, null, null, "", headers,"UTF-8");// Must use UTF-8 encoding
} catch (IOException e) {
AppLog.error(e, grant);
}
return new JSONObject(res);
}

}

Code snippet using a business object

You can now use the previsous script on a business object hook and create an event. See business object hooks code examples

Example of a business object where event are created on google calendar. Date has to be on RFC3339 format. Simplicite provide method to change date to this specific format. Rhino

MyBusinessObject.preCreate = function() {
var c = new Calendar(this.getGrant());
var data = new JSONObject();
data.put("summary",this.getFieldValue("title"));
// Format date to RFC3339
data.put("start", new JSONObject().put("dateTime",Tool.dateTimeToRFC3339(this.getFieldValue("startDatetime"))).put("timeZone","Europe/Paris"));
data.put("end", new JSONObject().put("dateTime",Tool.dateTimeToRFC3339(this.getFieldValue("endDatetime"))).put("timeZone","Europe/Paris"));
data.put("guestsCanInviteOthers", false);
data.put("guestsCanSeeOtherGuests", false);
var res = c.insert(data);
var id = res.getString("id");
// Keep eventId for next call (update or delete)
this.getField("eventId").setValue(id);
};

Java

@Override
public String preCreate() {
Calendar c = new Calendar(getGrant());
JSONObject data = new JSONObject();
data.put("summary",getFieldValue("title"));
// Format date to RFC3339
data.put("start", new JSONObject().put("dateTime",Tool.dateTimeToRFC3339(getFieldValue("startDatetime"))).put("timeZone","Europe/Paris"));
data.put("end", new JSONObject().put("dateTime",Tool.dateTimeToRFC3339(getFieldValue("endDatetime"))).put("timeZone","Europe/Paris"));
data.put("guestsCanInviteOthers", false);
data.put("guestsCanSeeOtherGuests", false);
JSONObject res = c.insert(data);
String id = res.getString("id");
// Keep eventId for next call (update or delete)
getField("eventId").setValue(id);
return super.preCreate();
}

Geocoding

Google Maps

This example sets a myCoords object field (of type geocoordinates) with the coordinates returned by Google Maps geocoding service using the value of the myAddress text field.

var a = this.getField("myAddress");
if (a.hasChanged())
this.setFieldValue("myCoords", GMapTool.geocodeOne(a.getValue().replace("\n", ", ")));

Java

	ObjectField a = getField("myAddress");
GMapTool gT=new GMapTool(getGrant());
if (a.hasChanged())
setFieldValue("myCoords", gT.geocodeOne(a.getValue().replace("\n", ", ")));

Note: to debug response from the API you can use the DCORESV001 log event code

Translation

Google Translate

As of version 4.0 it is possible to submit translation requests to Google Translate API using the GoogleAPITool.translate() method.

var l = this.getField("myFrenchLabel");
if (l.hasChanged())
this.setFieldValue("myEnglishLabel", GoogleAPITool.translate(this.getGrant(), l.getValue(), "fr", "en"));

Java

try {
ObjectField l = getField("myFrenchLabel");
if (l.hasChanged())
setFieldValue("myEnglishLabel", GoogleAPITool.translate(getGrant(), l.getValue(), "fr", "en"));
} catch (Exception e) {
AppLog.error(e, getGrant());
}

Note: to debug response from the API you can use the DCORESV001 log event code

SMS

As of version 4.0 it is possible to use the SMSTool helper class for the following providers:

  • Twilio
  • SMS Envoi

The service configuration and credentials being stored in the SMS_SERVICE system parameter.

Note: to debug response from the API you can use the DCORESV001 log event code

Custom example

Warning: The following example is only for versions 3.x, for version 4.0, see above.

This example uses SMSEnvoi "premium" SMS service.

function sendSMS(phone, message) {
try {
var params = new JSONObject(Grant.getSystemAdmin().getParameter("SMSENVOI_CONFIG", "{}"));
var url = params.getString("url");
var email = params.getString("email");
var apikey = params.getString("apikey");

var res = Tool.readUrl(url, null, null, "email=" + HTTPTool.encode(email) + "&apikey=" + apikey + "&message[type]=sms&message[subtype]=PREMIUM&message[recipients]=" + HTTPTool.encode(phone) + "&message[content]=" + HTTPTool.encode(message), null, Globals.getPlatformEncoding());
console.log("Response: " + res);

var r = new JSONObject(res);
var id = r.getInt("message_id");
console.log("SMS Id:" + id);
} catch(e) {
console.error(e.javaException ? e.javaException.getMessage() : e);
}
};

Java

public void sendSMS(Object phone,Object message) {
try {
JSONObject params = new JSONObject(Grant.getSystemAdmin().getParameter("SMSENVOI_CONFIG", "{}"));
String url = params.getString("url");
String email = params.getString("email");
String apikey = params.getString("apikey");
String res;
res = Tool.readUrl(url, null, null, "email=" + HTTPTool.encode(email) + "&apikey=" + apikey + "&message[type]=sms&message[subtype]=PREMIUM&message[recipients]=" + HTTPTool.encode(phone) + "&message[content]=" + HTTPTool.encode(message), null, Globals.getPlatformEncoding());
AppLog.info("Response: " + res,grant);
JSONObject r = new JSONObject(res);
int id = r.getInt("message_id");
AppLog.info("SMS Id:" + id,grant);
} catch (IOException e) {
AppLog.error(e, grant);
}
}

Where the SMSENVOI_CONFIG system parameter has the following JSON value:

{
"email": "<email>",
"apikey": "<API key>",
"url": "http://www.smsenvoi.com/httpapi/sendsms/"
}

Emails

SendWithUs

The following example uses SendWithUs email templating/formatting service.

// data is a JSONObject, files is a JSONArray, returned value is a JSONObject
function(to, template, data, files) {
try {
var config = new JSONObject(Grant.getSystemAdmin().getParameter("SENDWITHUS_CONFIG", "{}"));
var endpoint = config.optString("endpoint");
var apikey = config.optString("apikey");
var locale = config.optString("locale");

var req = new JSONObject();
req.put("recipient", new JSONObject().put("address", to));
req.put("locale", locale);
if (data) req.put("template_data", data);
if (files) req.put("files", files);

var res = Tool.readUrl(endpoint, apikey, "", req, null);
console.log("Response: " + res);
return new JSONObject(res);
} catch (e) {
console.error(e.javaException ? e.javaException.getMessage() : e);
}
};

Java

public JSONObject sendMail(String to,String template,JSONObject data,JSONArray files) {
String res="";
try {
JSONObject config = new JSONObject(Grant.getSystemAdmin().getParameter("SENDWITHUS_CONFIG", "{}"));
String endpoint = config.optString("endpoint");
String apikey = config.optString("apikey");
String locale = config.optString("locale");

JSONObject req = new JSONObject();
req.put("recipient", new JSONObject().put("address", to));
req.put("locale", locale);
if (!Tool.isEmpty(data)) req.put("template_data", data);
if (!Tool.isEmpty(files)) req.put("files", files);
res = Tool.readUrl(endpoint, apikey, "", req, null);
} catch (IOException e) {
AppLog.error(e, grant);
}
AppLog.info("Response: " + res, grant);
return new JSONObject(res);
}

Where the SENDWITHUS_CONFIG system parameter has the following JSON value:

{
"endpoint": " https://api.sendwithus.com/api/v1/send",
"apikey": "<API key>",
"locale": "en-US"
}

MailJet

Here an example to use MailJet external service to send email. See MailJet Guides.

System parameter

First create a system param with MailJet api data. You will need your public and private key.

You may want to send transactionnal email. To do so, add your template id.

{
"provider": "MailJet",
"endpoint": " https://api.mailjet.com/v3/send",
"apipublickey": "<your_public_key>",
"apiprivatekey": "<your_private_key>",
"templates": {
"registration": "13237",
"thanks": "45675"
}
}

Code snippet

Create a script that can be used on different business object or external object. For example :

ExternalEmail = function(g) {
var grant = g;

var config = new JSONObject(grant.getParameter("EXTERNAL_EMAIL_CONFIG", "{}"));
var provider = config.optString("provider");
var endpoint = config.optString("endpoint");
var apipublickey = config.optString("apipublickey");
var apiprivatekey = config.optString("apiprivatekey");
var templates = config.optJSONObject("templates");

// Send email using a template created on service side.
// template is a string and data is a JSONObject
function send(template, data) {
var headers = new HashMap();
headers.put("Content-Type", HTTPTool.getMimeTypeWithEncoding(HTTPTool.MIME_TYPE_JSON, "UTF-8")); // Explicitly set content type as UTF-8-encoded application/json (not needed in version 4.0)

var tmpl = templates.optString(template);

var req = data;
req.put("MJ-TemplateID", tmpl);

var res = Tool.readUrl(endpoint, apipublickey, apiprivatekey, req, headers, "UTF-8"); // Must use UTF-8 encoding
return new JSONObject(res);
}

return { send: send };
};

Java

public class ExternalEmail implements java.io.Serializable {
private static final long serialVersionUID = 1L;
Grant grant=new Grant();
JSONObject config= new JSONObject();
String provider;
String endpoint;
String apipublickey;
String apiprivatekey;
JSONObject templates=new JSONObject();
public ExternalEmail(Grant g){
grant=g;
config = new JSONObject(grant.getParameter("EXTERNAL_EMAIL_CONFIG", "{}"));
provider = config.optString("provider");
endpoint = config.optString("endpoint");
apipublickey = config.optString("apipublickey");
apiprivatekey = config.optString("apiprivatekey");
templates = config.optJSONObject("templates");

}
// Send email using a template created on service side.
// template is a string and data is a JSONObject
public JSONObject send(String template,JSONObject data){
HashMap<String,String> headers = new HashMap<>();
headers.put("Content-Type", HTTPTool.getMimeTypeWithEncoding(HTTPTool.MIME_TYPE_JSON, "UTF-8")); // Explicitly set content type as UTF-8-encoded application/json (not needed in version 4.0)

String tmpl = templates.optString(template);

JSONObject req = data;
req.put("MJ-TemplateID", tmpl);

String res="";
try {
res = Tool.readUrl(endpoint, apipublickey, apiprivatekey, req, headers, "UTF-8"); // Must use UTF-8 encoding
} catch (java.io.IOException e) {
AppLog.error(e, grant);
}
return new JSONObject(res);
}

}

Code snippet using a business Object

You can now use the previsous script on a business object hook and send an email. See business object hooks code examples

var e = new ExternalEmail(this.getGrant());
var data = new JSONObject();
data.put("FromEmail", "contact@simplicite.fr");
data.put("FromName", "Simplicite Software");
data.put("Subject", "Bonjour");
// To be used with transactionnal email
data.put("MJ-TemplateLanguage", true);

var recipients = new JSONArray();
recipients.put(new JSONObject().put("Email", this.getFieldValue("email")));
data.put("Recipients", recipients);

// Vars define on your template to be replace with
var vars = new JSONObject();
vars.put("firstname", this.getFieldValue("firstname"));
data.put("Vars", vars);

var res = e.send("registration", data);

Java

ExternalEmail e = new ExternalEmail(getGrant());
JSONObject data = new JSONObject();
data.put("FromEmail", "contact@simplicite.fr");
data.put("FromName", "Simplicite Software");
data.put("Subject", "Bonjour");

// To be used with transactionnal email
data.put("MJ-TemplateLanguage", true);
JSONArray recipients = new JSONArray();
recipients.put(new JSONObject().put("Email", getFieldValue("email")));
data.put("Recipients", recipients);

// Vars define on your template to be replace with
JSONObject vars = new JSONObject();
vars.put("firstname", getFieldValue("firstname"));
data.put("Vars", vars)
JSONObject res = e.send("registration", data);

Currency rates

Fixer.io

This example is a MyCurrency business object custom method that updates the records with rates values got from the Fixer.io service.

MyCurrency.getRates = function(base, currencies) {
try {
var res = Tool.readUrl("http://api.fixer.io/latest?base=" + base + (currencies ? "&symbols=" + currencies.join() : ""));
console.log("Response: " + res);

var rates = new JSONObject(res).getJSONObject("rates");

var ot = new BusinessObjectTool(this) // or this.getTool() in version 5+
this.resetFilters();
this.getField("curCurrency1").setFilter(base);
var rows = ot.search(false);
for (var i = 0; i < rows.size(); i++) {
var row = rows.get(i);
this.setValues(row, true);
this.setFieldValue("curRate", rates.optDouble(this.getFieldValue("curCurrency2"), 0))
ot.validateAndSave();
}
} catch (e) {
console.error(e.javaException ? e.javaException.getMessage() : e);
}
}

Java

public void getRates(String base, String[] currencies) {
try{
String res = Tool.readUrl("http://api.fixer.io/latest?base=" + base + (Tool.isEmpty(currencies) ? "": "&symbols=" + String.join("",currencies) ));
AppLog.info("Response: " + res,getGrant());
JSONObject rates = new JSONObject(res).getJSONObject("rates");
BusinessObjectTool ot = new BusinessObjectTool(this); // or getTool() in version 5+
resetFilters();
getField("curCurrency1").setFilter(base);
for (String[]row :ot.search() ) {
setValues(row, true);
setFieldValue("curRate", rates.optDouble(this.getFieldValue("curCurrency2"), 0));
ot.validateAndSave();
}
}catch(IOException | ValidateException | SaveException | SearchException e){
AppLog.error(e, getGrant());
}
}

Typical usage would be MyCurrency.getRates.call(this, "EUR", ["USD", "GBP"]);.

Cloud

Apache JClouds

As of version 4.0 P19 the Apache JClouds Cloud Storage Java libraries are integrated to the standard libs for use with the following stotages: AWS S3, OpenStack Swift, Google cloud storage and Azure Blob.

The com.simplicite.util.tools.CloudStorage class wrapper makes it easy to read/write files from/to the above cloud storages. Example: Java

// (...)
import java.util.Date;
import com.simplicite.util.*;
import com.simplicite.util.tools.*;
// (...)
CloudStorageTool cst = null;
try {
cst = new CloudStorageTool(getGrant().getJSONObjectParameter("MY_STORAGE_CONFIG"));
String encoding = Globals.getPlatformEncoding();

cst.put(new JSONObject()
.put("name", "test.html")
.put("mime", HTTPTool.MIME_TYPE_HTML)
.put("encoding", encoding)
.put("content", "<html><body>hello world " + new Date() + "!</body></html>")
);

JSONObject file = cst.get("test.html", true);
AppLog.info(getClass(), "display", new String((byte[])file.get("content"), encoding), getGrant());
} catch (Exception e) {
AppLog.error(getClass(), "display", null, e, getGrant());
} finally {
if (cst != null) cst.close();
}

Note: This example is given in Java, it can be easily transposed to Rhino script

Where the MY_STORAGE_CONFIG system parameter contains:

  • for AWS S3:
{
"provider": "aws-s3",
"accessKeyId": "<your access key ID>",
"secretAccessKey": "<your access key secret>",
"bucket": "<your bucket name>"
}
  • for OpenStack Swift:
{
"provider": "openstack-swift",
"tenant": "<your tenant name>",
"username": "<your user name>",
"password": "<your password>",
"authUrl": "<your auth enpoint URL>",
"region": "<your region name>",
"container": "<your container name>"
}
  • for Google Cloud Storage:
{
"provider": "google-cloud-storage",
"accessKeyId": "<your access key ID>",
"secretAccessKey": "-----BEGIN PRIVATE KEY-----\n<your access key secret>\n-----END PRIVATE KEY-----\n",
"bucket": "<your bucket name>"
}
  • for Azure Blob:
{
"provider": "azureblob",
"accessKeyId": "<your access key ID>",
"secretAccessKey": "<your access key secret>",
"bucket": "<your bucket name>",
"debug": true
}