Third party APIs examples

These are examples of calls to various third party APIs done on server side.

Note that some of these APIs need a paying subscription and/or 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 bellow 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 Params

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

Script

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};
};

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.

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);
};

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", ", ")));

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"));

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:

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);
    }
};

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);
    }
};

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 Param

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"
    }
}

Script

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 };
};

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);

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);
        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);
            this.setFieldValue("curRate", rates.optDouble(this.getFieldValue("curCurrency2"), 0))
            ot.validateAndSave();
        }
    } catch (e) {
        console.error(e.javaException ? e.javaException.getMessage() : e);
    }
}

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:

// (...)
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:

{
    "provider": "aws-s3",
    "accessKeyId": "<your access key ID>",
    "secretAccessKey": "<your access key secret>",
    "bucket": "<your bucket name>"
}
{
    "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>"
}

TODO: to be completed

TODO: to be completed