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

  1. 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.

  2. Obtain the URL to call the API.
    Example: https://secure.rpmtelco.com/rpm/api2.svc.

  3. Create the Term Process in RPM
    Use the following template.
  4. The name of each API call is added to that URL.
    For example: ProcForm – these will be covered below

Prepare Salesforce for HTTP requests:

  1. 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 SalesforceFields in Term Process of RPM
Account NameCustomer Name (a customer reference field)
Contract OwnerSold By (a custom list field)
End DateContract End Date (a custom date field)
Start DateContract 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.TermSetup

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; // form name
    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”;
    // Initialize the http request
    HttpRequest req = new HttpRequest();
    Http http = new Http();
 
    // add the endpoint to the request
    req.setEndpoint(url);   
    req.setHeader('Content-Type','application/json; charset=utf-8');
    req.setMethod('POST');
    req.setBody(‘{\"Key\":\"' + key +  '\",'  + body  + ‘}’);
 
    // create the response object
    HTTPResponse resp = http.send(req);
 
    // service is returning a line feed so parse it out
    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)
{
    // set the method
    // generate the url for the request
    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';
    }
 
    // get contract owner info of Contract
    User contractOwner;
    if (curContract.OwnerId!=null)
    {
        contractOwner = [SELECT Name from User where id = :curContract.OwnerId];
    }
 
    // get account info of Contract
    Account account;
    if (curContract.AccountId!=null)
    {
        account = [SELECT Name from Account where id = :curContract.AccountId];
    }
 
    // Check if customer exists in RPM, if not create it
    if (account !=null && account.Name != '')
    {
        String name = account.Name;
        if (Customer.GetCustomerFromName(name) == null)
        {
            account.RPM_Customer_ID__c =  string.valueof(Customer.CreateSimpleCustomer(name));
        }
    }
 
    // Send API call to create/update the Term in RPM
    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:'') ;
    }
 
    // Term owner and status
    sendFormResult.Form.Owner =  'Tai Huynh';
    sendFormResult.Form.Status = (curContract.Status != null ?  curContract.Status:'');
 
    // Set custom fields of Term
    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))
    };
 
    // add the endpoint to the request
    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

1
2
3
4
5
6
7