Core Concepts

CONVAYR allows you to integrate data from one application, the source, to a target application. This is called a Connection.

Once you have selected your source and target applications and authorised the applications, you define the way in which the data is transferred by defining a mapping.

The mapping allows you to select how each piece, or field, of the source data is mapped into the target system. This can be as simple as selecting the target field that you want the data transferred to. Mappings can have multiple sections, so the source data can for example create or update multiple objects in the target system. You can also transform the source value by defining a value transform and define conditions on a per field or per section basis

Value transforms include date transformations, picklist mappings e.g. when value A use value B, and scripting. Scripting is covered in the section below JEXL Script

Once you have defined your connection you can run it manually or define a schedule to run it on easily defined intervals.

You can create dependancies so that one Connection causes one or more other Connections to run.

You can allow people to control Connections with emails and submit csv data as attachments.

Users can subscribe to notifications to receive emails when a Connection runs and whether there were any errors.

Detailed logs are maintained each time the Connection is run and in the event of an error you can simply correct the mapping, or data, and re-run it.

Quickstart Videos

The following series of short videos is the quickest way to get youself familiar with CONVAYR.

  1. Introduction and Navigation (1:59)
  2. Administration and Setup (4:37)
  3. Creating and Mapping Connections (12:46)
  4. Activating Connections (7:01)
  5. Success and Error Notifications (6:40)

All the CONVAYR videos are on our YouTube channel.

Batch Processing

CONVAYR makes use of batch processing when it is available in a target system. This is the most efficient and therefore quickest method of running a job. Not only does CONVAYR make less calls to the target system, but also where it can, de-duplicates the payload. The savings on large payloads are substantial.

You have the ability to disable batch processing, but should only do this if you really need to. The only circumstances where this makes sense are:

1. You need a job to terminate as soon as an error is encountered with processing a single source item.
2. You are looking up by a value for an update or update/create which is mapped in the section itself. For instance Update a Contact based on the email and in the fields change the value of the email.
3. You are experiencing locking errors in the target system.
4. The target system is a database (other than MySQL) and you want every row to be attempted. The batch behaviour is to stop the batch at any error.

Salesforce Configuration & Security

CONVAYR uses OAuth to authenticate with Salesforce, therefore your credentials are never stored by CONVAYR.

In order to use an account with CONVAYR, the profile associated with the account must have the "API Enabled". Access to this is through the profile associated with the account in the "Administrative Permissions" section.

To use Salesforce reports as a source system you must have a profile with "Export Report" enabled, this is in the "General User Permissions" section of the profile.

If your Salesforce has Single Sign On (SSO) enabled then you must add the CONVAYR IP addresses to the user's Trusted IP Ranges. This can be against the organisation or the profile associated with the account

The IP addresses required for CONVAYR are:
52.58.12.161
52.29.130.144
Create an IP Range with the IP address as both the Start and End IP Address for both these IP addresses.

CONVAYR IP Addresses

CONVAYR is hosted in 2 physical locations the addresses for the loadbalancers are:

52.58.12.161
52.29.130.144

CONVAYR traffic can originate from either IP address. You need to allow traffic on your system from both of these addresses.

Source File Regex

You can use Regex (Regular Expression) to specify a pattern to match source files. The Regex only applies to the filename, NOT any preceding directories. An example to match any .csv file in the selected directory is:

/dir/subdir/.*\.csv

The Regex starts after the last forward slash (/). '.*' specifies zero or more characters, '\.' is a literal '.' it must be preceded by a '\' because '.' is a special character in Regex.

Regex can be as simple as the example above, but can also be very complex. It is unlikely that you will need very complex Regex to use in CONVAYR, however if you do need something more complex there are excellent references available including https://www.regular-expressions.info and there is a site that allows you to test your expressions here https://regex101.com

Target File Date Pattern

It is not uncommon to employ a naming convention for data files that includes the current date/time in the file name. CONVAYR supports this by allowing you to specify a date pattern. An example of a valid date pattern is:

%d{dd-MM-yyyy}.csv

The '%d{}' surrounds the pattern itself. So the above pattern will match a file with the current day, month and year in the name e.g. 01-12-2019.csv will be matched when the job runs on the 1st December 2019.

A full description of the date formats supported by CONVAYR is available here https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html

Append Special Characters

When appending a field value you can make use of the following special characters in the delimiter:

\nNewline
\rCarriage Return
\tTab
\sSpace

Carriage return is required for Windows specific file formats as Windows uses \r\n as the line ending, all other systems use just \n.

JEXL Script

You can use scripts to transform source data and create values for use in the mapping. The scripts are based on JEXL and allow complex transformations of source values as well as allowing access to runtime data e.g. row index number

This is extremely powerful and allows, amongst other things, string manipulation to transform the incoming source value.

There are three objects available in the scripts: $src (the source value), $tgt (the target value) and $ctx (the context).

To represent a standard non-transformed mapping the script would be

var v = $src.val
$tgt.val = v

or even more simply

$src.val

because the transformed value is either the value of the whole script (an expression) or the value that $tgt.val is set to within the script.

The value can then be further transformed using Java String functions. So to replace spaces with underscores you could use:

$src.val.replace(' ', '_')

To convert the value to lower case you could use

$src.val.toLowerCase()

To limit the length of the value to ten characters

var v = $src.val
if(v.length() > 10) {
  v = v.substring(0, 9)
}
$tgt.val = v

The following is a more complex script to change the email domain from the value in the source(abd.com) to another value (abc.com)

var v = $src.val
var toks = v.split('@')
if(toks.size() > 1) {
  if("abd.com".equals(toks[1])) {
    v = toks[0]+"@abc.com"
  }
}
$tgt.val = v

You can also manipulate dates. The following classes are available:

This example adds 6 months to the source date time

var dateFormat = DateTimeFormatter:ofPattern("yyyy-MM-dd HH:mm:ss")
var date = LocalDateTime:parse($src.val, dateFormat).plusMonths(6)
$tgt.val = date.format(dateFormat)

If the source value was a date not a date & time you could do the following

var dateFormat = DateTimeFormatter:ofPattern("yyyy-MM-dd")
var date = LocalDate:parse($src.val, dateFormat).minusYears(1)
$tgt.val = date.format(dateFormat)

To change the target date format you would do the following

var dateFormatIn = DateTimeFormatter:ofPattern("yyyy-MM-dd'T'HH:mm:ssX")
var date = LocalDateTime:parse($src.val, dateFormatIn).plusYears(1)
var dateFormatOut = DateTimeFormatter:ofPattern("yyyy-MM-dd HH:mm:ss")
$tgt.val = date.format(dateFormatOut)

To calculate the number of days from the source date (dd-mm-yyyy) to a fixed end date (31-12-2024)

var dtf = DateTimeFormatter:ofPattern("dd-MM-yyyy")

var startDate = LocalDate:parse($src.val, dtf).atStartOfDay()
var endDate = LocalDate:parse("31-12-2024", dtf).atStartOfDay()

$tgt.val = Duration:between(startDate, endDate).toDays()

This example calculates the largest number from 2 source values. Although you have to select a source field for the transform, you do not necessarily use the value.

var fields = $src.fields

var largest = 0

var n1_str = fields.get('number 1')

if(!n1_str.equals("")) {
  var n1 = Integer:parseInt(n1_str)
  if(n1 > largest) {
    largest = n1
  }
}
var n2_str = fields.get('number 2')
if(!n2_str.equals("")) {
  var n2 = Integer:parseInt(n2_str)
  if(n2 > largest) {
    largest = n2
  }
}
$tgt.val = largest

The error() and info() methods available against $ctx allow the script to both write to the log and to throw an error. This example throws an error if an email is empty. This is extremely useful for automating data validation.

var email = $src.val

if(email.equals("")) {
  $ctx.error = 'ERROR: Empty email'
}
$tgt.val = email

 

These are the top level objects and methods:

$src

Method Return Description
val String Get the source value for this mapping field
fields Map (name to value) Get a map of the source value fields. Name mapped to the value
fieldNames List Get a list of the source fields names

$tgt

Method Return Description
val void Set the target value for this mapping field. This is also the value of the whole script if it is a single expression.
objecttype String Gets the target object name e.g. account
objecttypelabel String Gets the target object label e.g. Account

$ctx

Method Return Description
row int Get the current row index
rowcount int Get the total number of source data rows
info void Write an info message to the log. Any non-empty message at the end of script execution will be written to the log. Subsequent calls will override the previous message.
error void Throw an error. The error will appear in the log and and an error will be thrown. Execution of the script continues after calling error(). Any non-empty error message at the end of script execution will throw an error. Subsequent calls will override the previous error message. The error will be handled depending on the setting in the mapping.

Email Control

You can control connections in CONVAYR via email if it has been enabled against the connection. This allows people who are not registered CONVAYR users to, for instance, run a Connection.

Email Control must be switched on for both the account and the connection, and the email of the external user must be added to the permitted emails list. This email will be checked when an control request is received.

The Control Email is of the form abc123@conveyor-control.frogfoundry.com, so it is a good idea to add it to your address book and give it a more meaningful title e.g. Run Contacts Import <abc123@conveyor-control.frogfoundry.com>

The available commands which must be the subject of the email (no content is required) are:

RUNRun the connection
STOPRequest the connection stops if it is running
PAUSEPause the connection schedule
RESUMEResume the connection schedule

Email Run

You can run connections in CONVAYR via email by providing the source data as a csv file attachment. This allows people who are not registered CONVAYR users to run a Connection.

Email Run must be switched on for both the account and the connection, and the email of the external user must be added to the permitted emails list. This email will be checked when a run request is received.

The run email is of the form abc123@conveyor-run.frogfoundry.com, so it is a good idea to add it to your address book and give it a more meaningful title e.g. Run Contacts Import <abc123@conveyor-run.frogfoundry.com>

There is an additional configuration option to allow you to set a maximum size for the csv file. This can be Unlimited (default) or up to 1000 in increments of 10.

The template (headers) for the csv file can be obtained from Activation->Run Now->Download CSV Headers.

An email response will be returned for a run request from a valid email.

ServiceNow OAuth Endpoint

CONVAYR uses OAuth to authenticate against your ServiceNow instance. An Administrator needs to set up an OAuth endpoint in your instance to allow this.

You need to navigate to System OAuth - Application Registry and create a new endpoint. The type of endpoint is Create an OAuth API endpoint for external clients.

Leave the Client Secret blank so that this will be generated. Use the following URLs

Redirect URLhttps://app.frogfoundry.com/oauth2/servicenow/oauth_redirect.do.action
Logo URLhttps://www.frogfoundry.com/img/convayr-logo.png

Leave all other settings as the defaults.

Once created you need the Client ID and Client Secret from this endpoint to setup the ServiceNow credentials in CONVAYR

Salesforce Bulk API Query

SOQL queries are by default run using the Bulk API. You should in most case use the Bulk API, there are however differences in how the APIs deal with certain types of SOQL queries.

Binary (base64) fields cannot be included in the fields of a bulk query. Additionally TYPEOF, which is used to retrieve fields of polymorphic relationships is not supported

CONVAYR supports the mapping of binary (base64) data from source to target systems. Turning Bulk API off in this case will allow CONVAYR to retrieve the base64 fields.

Single Sign On

CONVAYR supports integration with a third party Identity Provider (IDP) to provide seamless Single Sign On (SSO). The IDP must support SAML 2.0.

As an Administrator you access the SSO settings through Account Settings -> Single Sign On Settings. You need to provide the following values:

SP Entity IdUnique identifier for CONVAYR in the IDP. Must be the same as the IDP value. Once you have provided this value you can download the metadata for import into the IDP.
IDP Entity IdOnce the connection for CONVAYR is created within the IDP, this will be available.
IDP Single Sign On URLOnce the connection for CONVAYR is created within the IDP, this will be available.
IDP Public CertificatePublic X509 certificate in PKCS#7 or PKCS#8 format.

There is a CONVAYR logo available here https://www.frogfoundry.com/img/convayr-logo.png for use in the IDP connection configuration.

Once setup, SSO must be enabled for each user.

Eloqua App

CONVAYR uses OAuth to authenticate against your Eloqua instance. An Administrator needs to set up an App to allow this.

You need to navigate to Settings - Extensions - AppCloud Developer and create an App.

Use the following URLs

Iconhttps://www.frogfoundry.com/img/convayr-logo.png
OAuth Callback URLhttps://app.frogfoundry.com/oauth2/eloqua/callback

You will need the Client ID and Client Secret from the new App to setup the OAuth connection in CONVAYR.

Salesforce Webhooks

Webhooks are simple and powerful mechanisms to push data into a Connection. Unlike other source types, webhooks are push and therefore have the advantage of creating a real time integration between Salesforce and the target application. To push data you need to call (GET) the CONVAYR webhook url with the source object id (or comma separated ids). This can be accomplished in Saleforce by using an Apex Trigger.

There is a limit of 100 hits per rolling 60 seconds across all webhooks for an account. Exceeding this quota will return an http status code of 420. You should consider this when inplementing a webhook.

The following example will create an Apex trigger against an Opportunity to call a CONVAYR webhook whenever a new Opportunity is created or an existing one is updated. Note: Bulk operations within Salesforce will call the trigger once with all the affected Opportunity ids.

Once you have created the CONVAYR connection with Salesforce Webhook as the source type, copy the webhook url. The webhook url can be found by selecting "Activation" from the connection menu. The url in this case is: https://app.frogfoundry.com/webhook/28j45te5jgw7e21q?id=, you will have to substitute your url in to the code below.

Create the following class in Apex Classes

Apex Class

public class CONVAYR {

  public static void webhookOpportunity(String ids) {
    // add the ids to the opportunity webhook url
    String url = 'https://app.frogfoundry.com/webhook/28j45te5jgw7e21q?id='+ids;
    webhook(url);
  }

  @future(callout=true)
  public static void webhook(String url) {

    Http h = new Http();

    HttpRequest req = new HttpRequest();
    req.setEndpoint(url);
    req.setMethod('GET');

    HttpResponse res = h.send(req);
    System.debug(res.getStatusCode()+' : '+res.getStatus());
  }
}

Create the following trigger in Apex Triggers

Apex Trigger

trigger Opportunity_Change on Opportunity (after insert, after update) {
  // create comma separated list of ids
  Set ids = Trigger.newMap.keySet();
  String idStr = '';
  for(String id : ids) {
    idStr += id+',';
  }
  // remove last comma
  idStr = idStr.substring(0, idStr.length()-1);
  // call CONVAYR webhook
  CONVAYR.webhookOpportunity(idStr);
}

The final thing that you must do to complete the Salesforce configuration is to add https://app.frogfoundry.com to the Remote Sites. This is found under Security->Remote Sites->New Remote Site. Without doing this the webhook call will be blocked by Salesforce and an error email to that effect will be sent to the administrator.

To add more triggers on other Salesforce objects to call CONVAYR webhooks you would add the trigger to the Salesforce object and add an additional method in the CONVAYR Apex Class substituting in the correct webhook url.