Salesforce allows custom programming, including the functionality for communicating with the API that RPM offers.
In this example, we set up a scenario where you have a “Contract” in Salesforce that you want to sync with the “Term” process in RPM and the fields will be synchronized between them.
Required Software
Requirements
This integration does not require special accounts on either RPM or Salesforce. This document assumes you are comfortable coding in Salesforce, have a basic understanding of using a REST API and JSON, and a basic understanding of RPM.
Before you start, you should determine what you want to integrate down to the field level. The reason we don’t have a standard body of code you can just use without custom work is that everyone has a slightly different RPM and Salesforce setup. There are custom fields in each system and your Salesforce may also have other custom code or modules that affect the data structure and workflow.
Development
The RPM API will be referred to as the API and Salesforce will be SF.
Prepare RPM
You need to complete the following steps in RPM
Obtain an API key. Go to Setup → API and use an existing key or make a new one.
If you don’t have access to your RPM subscription then ask someone who does have access for assistance. RPM Software can not give out API keys.
Obtain the URL to call the API.
Example: https://secure.rpmtelco.com/rpm/api2.svc.
- Create the Term Process in RPM
Use the following template. The name of each API call is added to that URL.
For example: ProcForm – these will be covered below
Prepare Salesforce for HTTP requests:
You need to enable the sending of outbound HTTP requests from your SF configuration. Add a “Remote Site” (Setup → Security Controls → Remote Site Setting) with the RPM domain name: Example: http://agentrpm.com)
Scenario
Like we said at the beginning, this example sets up a scenario where you have a “Contract” in SF that you want to sync with the “Term” process in RPM (in RPM we refer to each Term as a form), and the fields will be synchronized between them as follows:
Fields in Contract of Salesforce | Fields in Term Process of RPM |
Account Name | Customer Name (a customer reference field) |
Contract Owner | Sold By (a custom list field) |
End Date | Contract End Date (a custom date field) |
Start Date | Contract Start Date (a custom date field) |
The goal is that when a user looks at a Contract detail in SF, it will be updated with the latest information from Term in RPM, and when a user edits the Contract, it will update the Term in RPM.
When a user creates a Contract, it will create a Term in RPM and then save the Term ID to Contract for future synchronization.
Create the Term Process
Set up Field in process of Term is as shown in the following figure, you can use this template file.
Create Classes
Create the following classes that match the naming and structure of the elements in the JSON strings we will use for communication between the RPM API and SF.
Download this code snippet
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | public class Process {
public String Process;
public Integer ProcessID;
public Form Form;
public Process(String p, Integer id)
{
Process = p;
ProcessID=id;
Form = new Form();
}
}
public class Form {
public String FormNumber;
public Integer FormID;
public String Owner;
public String Status;
public String ApprovalResult;
public Date Started;
public Date Modified;
public CustomField[] Fields;
public String GetField(String Field)
{
for (CustomField f : Fields)
{
if (f.Field == Field)
return f.Value;
}
return '' ;
}
}
public class CustomField {
public String Field;
public String Value;
public CustomField(String f, String v)
{
Field = f;
Value = v;
}
}
public class Customer {
public String CustomerName;
public Integer CustomerID;
public Customer(String name, Integer id)
{
CustomerName = name;
CustomerID= id;
}
}
|
Sending API Calls
Download this code snippet
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | public static String SendAPI ( String url, String body)
{
string key = “xxxxxxxxxxxxxxxx”;
HttpRequest req = new HttpRequest();
Http http = new Http();
req.setEndpoint(url);
req.setHeader( 'Content-Type' , 'application/json; charset=utf-8' );
req.setMethod( 'POST' );
req.setBody(‘{\"Key\":\" ' + key + ' \",' + body + ‘}’);
HTTPResponse resp = http.send(req);
json = resp.getBody().replace( '\n' , '' );
return json;
}
|
First we instantiate the HTTP request, set the method to POST, and then we attach the JSON string which contains the properties and values that we need to send to the API (more on this below). After the API receives the HTTP request, it responds with a string in JSON format.
Methods
Create a Customer in RPM
Download this code snippet
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | public static Integer CreateSimpleCustomer(String name)
{
String apiCall = 'CustomerAdd' ;
String JSONRequest = '\"Customer\":{' + '\"Name\":\"' + name + + '\"}' ;
String json = APIRequest.Send(apiCall, JSONRequest);
try
{
Customer customerResult = GetCustomer(json);
return customerResult.CustomerID;
}
catch (Exception e)
{
system.debug( 'error=' + e);
return 0;
}
}
public static Customer GetCustomer(String json)
{
json = json.substring( '{"Result:{"' .Length()-1,json.Length()-1);
json = json.Replace( 'Name' , 'CustomerName' );
json = json.substring(0,json.IndexOf( '"Aliases"' )-1) + '}}' ;
system.debug(json);
try
{
Customer customerResult = (Customer)System.Json.deserialize(json, Customer.CustomerResult. class );
return customerResult;
}
catch (Exception e)
{
system.debug( 'ERROR=' + e);
return null ;
}
}
|
We want to have the function in place so we can have RPM create the new customer if it does not yet exist in RPM. The API call is CustomerAdd.
Update Term
Download this code snippet
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | public static void UpdateTerm(Contract curContract, Boolean isCreate)
{
String apiCall;
if (isCreate)
{
curContract = [ select AccountId, Name,OwnerID,EndDate, StartDate, Status,ContractNumber from Contract where id = :curContract.Id];
apiCall= 'ProcFormAdd' ;
}
else
{
apiCall= 'ProcFormEdit' ;
}
User contractOwner;
if (curContract.OwnerId!= null )
{
contractOwner = [SELECT Name from User where id = :curContract.OwnerId];
}
Account account;
if (curContract.AccountId!= null )
{
account = [SELECT Name from Account where id = :curContract.AccountId];
}
if (account != null && account.Name != '' )
{
String name = account.Name;
if (Customer.GetCustomerFromName(name) == null )
{
account.RPM_Customer_ID__c = string .valueof(Customer.CreateSimpleCustomer(name));
}
}
Process sendFormResult = new Process( 'Term' ,0);
sendFormResult.Form = new Form();
if (isCreate)
{
sendFormResult.Form.FormNumber = (curContract.ContractNumber != null ? curContract.ContractNumber: '' ) ;
}
else
{
sendFormResult.Form.FormID = (curContract.RPM_Form_ID__c != null ? Integer.valueof(curContract.RPM_Form_ID__c):0) ;
sendFormResult.Form.FormNumber = (curContract.RPM_Order_ID_Number__c != null ? curContract.RPM_Order_ID_Number__c: '' ) ;
}
sendFormResult.Form.Owner = 'Tai Huynh' ;
sendFormResult.Form.Status = (curContract.Status != null ? curContract.Status: '' );
sendFormResult.Form.Fields = new CustomField[]{
new CustomField( 'Customer Name' , (account != null )? account.Name : '' ),
new CustomField( 'Sold By' , (contractOwner.Name != null )? contractOwner.Name : '' ),
new CustomField( 'Contract Start Date' , string .valueof(curContract.StartDate) ),
new CustomField( 'Contract End Date' , string .valueof(curContract.EndDate))
};
string JSONRequest =System.JSON.serialize(sendFormResult);
JSONRequest = JSONRequest.Replace( 'FormNumber' , 'Number' );
JSONRequest = JSONRequest.substring(1,JSONRequest.Length()-1);
String json = APIRequest.Send(apiCall, JSONRequest);
try
{
Form form = GetForm(json);
curContract.RPM_Form_ID__c = double .valueOf(form.FormID);
update curContract;
}
catch (Exception e)
{
system.debug( 'error=' + e);
}
}
|
Get RPM Term info
Download this code snippet