Pega and Salesforce Integration

From PegaWiki
Pega Salesforce Integration / This is the approved revision of this page, as well as being the most recent.
Jump to navigation Jump to search

Pega and Salesforce Integration

Description This guide is intended as a starting point or help if you need to use or update data from a Salesforce environment, focused mainly on Salesforce REST API.
Version as of 8.7
Application Pega Platform
Capability/Industry Area Data Integration



Introduction[edit]

This guide is intended to be used as a starting point whenever you are requested, in a project, to integrate Pega with a Salesforce environment. For additional information you can refer to Salesforce documentation in the References section.

Salesforce provides an API that allows to fetch information from their data model and, in some cases, update it.

On the other hand, Salesforce can use Pega API, Mashup, and Pega Extender for Salesforce to handle integration in the other direction.

This is a quick guide of the resources available to integrate Pega and Salesforce. See the References section for more information.

Use Pega from Salesforce[edit]

Pega Extender for Salesforce

Case Management can be used from Salesforce by using the Pega Extender for Salesforce component.

https://www.pega.com/es/insights/resources/pega-extender-salesforce-data-sheet

Pega Web Mashup

You can display a Pega application inside Salesforce by embedding Pega Web Mashup using a lighting component. Mashup allows communication in both directions so information can travel from Pega to Salesforce and from Salesforce to Pega.

Pega API + DX API

You can use all Pega capabilities with the Pega API.

  • Fetch information with Pega REST API.
  • Use Case Management through both Pega REST API and DX API.

Salesforce Data Model[edit]

In a Salesforce app you can use out-of-the-box (OOTB) objects and custom objects. Similarly to Pega Objects, they can have instances. Salesforce objects also have defined properties, and sections. Both OOTB and custom objects can be referred by using Salesforce API, main difference being the naming convention, as custom objects and fields have a __c suffix.

Objects include fields that can have different types, both simple (string, number, date…) and complex (currency, picklist…).

Salesforce REST API[edit]

Salesforce provides a powerful REST API. It provides access to Salesforce without using their user interface.

URIs[edit]

REST API URIs are very similar from resource to resource, with the following structure:

https://MyDomain.my.salesforce.com/services/data/vXX.XX/resource/

  • MyDomain: Corresponds to your client’s domain.
  • vXX.XX: API version.
  • Resource: Method used to recover.

Authorization[edit]

To use the Salesforce REST API, every call needs to include an authorization code. Authorization uses OAuth 2.0. Please refer to the configuration example at the end.

The token can be obtained by performing a REST call to token service. This service uses existing user and security credentials to obtain a token that can be later used in calls.

Token Authorization 2.png

Request:

  • grant_type: you can indicate the method to use to validate user credentials. The “password” method allows you to directly send username and password. However other methods are allowed depending on the need.
  • client_id, client_secret: A connected app needs to be created in salesforce to use Oauth 2.0 in REST API. When configuring the connected app, client ID and secret will be generated. This information is needed when obtaining the token.
  • username, password: User credentials.
  • redirect_uri: OAuth 2.0 redirect URI. It may vary depending on your connected app configuration.

Response:

{
    "access_token": "00D0Q0000000MWt!ARMAQKRpmQbs4kkv5G1k.FuAZ3.kPVEqb5IU3GfzVcJQ8xtD9Yk5R3TeY2eclyZKm5p6ynw6IHL72xVTqAb_u91Q0zMxdCua",
    "instance_url": "https://xxxxxxx--www.my.salesforce.com",
    "id": "https://test.salesforce.com/id/11D0F0033000hWttAM/1022V030500fi4bQeQ",
    "token_type": "Bearer",
    "issued_at": "1645000283087",
    "signature": "12349q7x123d2wMDtuEUdfeR0YidTmZd8FmNTASi323u="
}

The request property access_token and token_type contains the header authorization value that you need to set on your REST API calls.

Token Authorization Response

Objects[edit]

This resource retrieves information from Salesforce Data Model Objects. This includes both information about the object itself (metadata, and links to object resources) and instances of the object.

URI

Resource key to use is “sobjects”. After the resource key, the object to get information from is indicated. After the object, you can indicate what kind of information you want or object ID to retrieve an instance.

https://MyDomain.salesforce.com/services/data/v53.0/sobjects/Object/

Retrieve Metadata

By not passing anything to the URL, the service returns all metadata of the object, along with recents and possible URLs to query the object data. With those URLs it is possible to get an object instance, obtain information of the existing fields of the object by using describe, or fetch Salesforce layouts and views.

{
    "objectDescribe": {
        "activateable": false,
        "createable": false,
        "custom": false,
        "customSetting": false,
        "deepCloneable": false,
        "deletable": false,
        "deprecatedAndHidden": false,
        "feedEnabled": true,
        "hasSubtypes": false,
        "isInterface": false,
        "isSubtype": false,
        "keyPrefix": "001",
        "label": "Account",
        "labelPlural": "Accounts",
        "layoutable": true,
        "mergeable": false,
        "mruEnabled": true,
        "name": "Account",
        "queryable": true,
        "replicateable": true,
        "retrieveable": true,
        "searchable": true,
        "triggerable": true,
        "undeletable": false,
        "updateable": false,
        "urls": {
            "compactLayouts": "/services/data/v49.0/sobjects/Account/describe/compactLayouts",
            "rowTemplate": "/services/data/v49.0/sobjects/Account/{ID}",
            "approvalLayouts": "/services/data/v49.0/sobjects/Account/describe/approvalLayouts",
            "listviews": "/services/data/v49.0/sobjects/Account/listviews",
            "describe": "/services/data/v49.0/sobjects/Account/describe",
            "quickActions": "/services/data/v49.0/sobjects/Account/quickActions",
            "layouts": "/services/data/v49.0/sobjects/Account/describe/layouts",
            "sobject": "/services/data/v49.0/sobjects/Account"
        }
    },
    "recentItems": [
        {
            "attributes": {
                "type": "Account",
                "url": "/services/data/v49.0/sobjects/Account/0011w00000rnxdsAAA"
            },
            "Id": "1111w012300rnsdsABA",
            "Name": "Test Account 1"
        },
        {
            "attributes": {
                "type": "Account",
                "url": "/services/data/v49.0/sobjects/Account/0011w00000vL3ktAAC"
            },
            "Id": "1341r12340vL3ktAAT",
            "Name": " Test Account 1"
        }
    ]
}

Object Describe

Adding keyword describe to the URL allows to fetch all object fields and possible values on picklists. For example sobjects/Account/describe will return all the fields along with their format and possible values, if it is a dropdown (called picklist in Salesforce). For example (truncated fields to save space):

 	{
            "aggregatable": true,
            "aiPredictionField": false,
            "autoNumber": false,
            "byteLength": 30,
            "compoundFieldName": "BillingAddress",
            "controllerName": "BillingCountryCode",
            "picklistValues": [
                {
                    "active": true,
                    "defaultValue": false,
                    "label": "Aargau",
                    "validFor": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAA",
                    "value": "AG"
                },
                {
                    "active": true,
                    "defaultValue": false,
                    "label": "Acre",
                    "validFor": "AAAAAQAA",
                    "value": "AC"
                }
            ],
        },

Instances

By adding the ID of the object to search after the object, you can recover an entire instance of the given object. For example sobjects/Account/1010T003G1R43o2Q9R returns the following response:

{
    "attributes": {
        "type": "Account",
        "url": "/services/data/v49.0/sobjects/Account/0011w00000rnxdsAAA"
    },
    "Id": "AAAAr00312rntfgAAA",
    "IsDeleted": false,
    "MasterRecordId": null,
…
}(Response is truncated for space purposes)

It is possible to create, update and delete records by using REST methods, POST, PATCH and DELETE.

  • CREATE using POST
    • URL sobjects/Account/
    • Body: JSON with fields to set, for example:
      • { "Name" : "New Account" }
    • Response:
{
  "id"": "AAAAr00312rntfgAAA",
  "errors"s: [ ],
  "success"s: true
}
  • Update using PATCH
    • URL sobjects/Account/ID
    • Body: JSON with fields to update, for example:
      • { "BillingCity" : "Madrid" }
    • Response: none returned
  • Delete using DELETE
    • URL sobjects/Account/ID
    • Body: none
    • Response: none returned

Recently Viewed[edit]

This resource allows recovery of recent viewed objects from user. This is restricted to the user used in Oauth 2.0 authorization, you can’t access another user’s recent list.

URI

Resource key to use is “recent”. The SOSL (Salesforce Object Search Language) query string includes parameter limit=n to set maximum number of records returned.

https://MyDomain.salesforce.com/services/data/v53.0/recent/?limit=5

Response

Response JSON contains Attributes type and URL, ID, Name of the recently viewed objects for the authorized user.

[
    {
        "attributes": {
            "type": "Account",
            "url": "/services/data/v49.0/sobjects/Account/AAAAr00312rntfgAAA"
        },
        "Id": "AAAAr00312rntfgAAA",
        "Name": "Test Account 1"
    },
    {
        "attributes": {
            "type": "User",
            "url": "/services/data/v49.0/sobjects/User/AAAAr00312rntfgAAA"
        },
        "Id": "AAAAr00312rntfgRRR",
        "Name": "Test User 1"
    }
]

Query[edit]

Use query resource to execute a SOQL (Salesforce Object Query Language) query that returns results in a single response. SOQL is a SQL like language, it allows selection of fields and filter results including a where condition. Use SOQL when you know which objects data resides in and you want to:

  • Retrieve data from a single object or from multiple objects that are related to one another
  • Count the number of records that meet specified criteria
  • Sort results as part of the query
  • Retrieve data from the number, date, or checkbox fields

URI

Resource key to use is “query”. The SOSL query string is included as URI parameter “q”

https://MyDomain.salesforce.com/services/data/v53.0/query/?q=SELECT+name+from+Account

SOSL Query String

The use of * wildcard is not allowed. This means you need to know beforehand the fields you want to include in response. Please note that when used in query you need to URL Encode the query.

SOQL does not support advanced SQL command features, so the query is limited. However, it is possible to use an Alias notation to recover information from other tables (similar to Join) that are logically linked (for example an Account is owned by a User).

For example, you can recover User Role information when querying User object by using UserRole alias:

Select ID, Username, LastName, FirstName, MiddleName, Name, Email, UserRoleId, UserRole.Name From User

It is possible to use Limit keyword to restrict the number of records returned by query, also ORDER BY can be used. The following query will return the first 5 accounts only, ordered by name.

              Select id,Name from Account LIMIT 5 ORDER BY Name ASC

Response

Response JSON contains the records corresponding to the query along with attributes, size, and status of the call. Following example for query “?q=Select+Id,Name+From+Account+LIMIT+1”

{
    "totalSize": 1,
    "done": true,
    "records": [
        {
            "attributes": {
                "type": "Account",
                "url": "/services/data/v49.0/sobjects/Account/AAAAr00312rntfgAAA"
            },
            "Id": "AAAAr00312rntfgAAA",
            "Name": "EXAMPLE TEST ACCOUNT"
        }
    ]
}

Attributes normally return type and URL of Object that can be used to retrieve the entire record.

Search[edit]

Use search resource to execute an SOSL query that returns text-based filtered results in a single response. This resource allows you to use the Salesforce search engine which in turn makes text-based search more effective. It is possible to use the LIKE command in SOQL but it is inefficient. Instead you can use SOSL. Use SOQL when you do not know in which objects data resides and you want to:

  1. Retrieve data for a specific term that you know exists within a field. Because SOSL can tokenize multiple terms within a field and build a search index from this, SOSL searches are faster and can return more relevant results.
  2. Retrieve multiple objects and fields efficiently where the objects might or might not be related to one another.
  3. Retrieve data for a particular division in an organization using the divisions feature.
  4. Retrieve data that’s in Chinese, Japanese, Korean, or Thai. Morphological tokenization for CJKT terms helps ensure accurate results.

URI

Resource key to use is “search”. The SOQL search string is included as URI parameter “q”

https://MyDomain.salesforce.com/services/data/v53.0/search/?q=FIND+{*TEXT*}+IN+ALL+FIELDS+RETURNING+Account(id,Name)WHERE+Id=’XXX’

SOSL Search String Syntax

FIND {Search query} – Specify the text you want to search. Length must be longer than 2. You can use wild cards.

IN SearchGroup – Specify the scope of the search, possible values: ALL FIELDS, NAME FIELDS, EMAIL FIELDS, PHONE FIELDS, SIDEBAR FIELDS. Defaulted to ALL FIELDS.

RETURNING FieldSpec (fields to return) – Information to return back. Search engine searches in all objects in the system by default. You can restrict the search to specific objects and the fields to return back. If you do not specify any fields in the list, system will only return ID.

It is possible to use the Limit keyword to restrict the number of records returned by query, also ORDER BY can be used. The following query will return the first 5 accounts only, ordered by name.

              Select id,Name from Account LIMIT 5 ORDER BY Name ASC

OFFSET n – It is possible to paginate results by using offset and limit. Offset starts in 0, so in the case you want to paginate, you can do it by setting the limit to N and Offset to (N+1) * (page-1).

Response

Response contains the records corresponding to the search along with attributes, size and status of the call. Following example for search ”?q=FIND+{*TEXT*}+IN+ALL+FIELDS+RETURNING+Account+LIMIT+1”

{
    "searchRecords": [
        {
            "attributes": {
                "type": "Account",
                "url": "/services/data/v49.0/sobjects/Account/AAAAr00312rntfgAAA"
            },
            "Id": "AAAAr00312rntfgAAA"
        }
    ]
}

UI API[edit]

In a similar way as our DX API, Salesforce User Interface API allows you to fetch information from UI elements. This includes all information necessary to display a record in another application.

URIs

  • Objects: https://MyDomain.my.salesforce.com/services/data/v49.0/ui-api/object-info/

Returns a list of all existing objects in Salesforce.

{
    "objects": {
        "Account": {
            "apiName": "Account",
            "keyPrefix": "001",
            "label": "Account",
            "labelPlural": "Accounts",
            "nameFields": [
                "Name"
            ],
            "objectInfoUrl": "/services/data/v49.0/ui-api/object-info/Account"
        },…
  • Object Info: https://MyDomain.my.salesforce.com/services/data/v49.0/ui-api/object-info/Object

Returns information for the given object. Fields, relationships…

{
    "apiName": "Account",
    "childRelationships": [
        {
            "childObjectApiName": "Account",
            "fieldName": "ParentId",
            "junctionIdListNames": [],
            "junctionReferenceTo": [],
            "relationshipName": "ChildAccounts"
        },…
  • Record Info: https://MyDomain.my.salesforce.com/services/data/v49.0/ui-api/record-ui/Id

Returns all necessary information to display an individual instance. Thus returns both UI information (formats, dropdown values…) and instance data.

{
    "eTag": "bed28f6e186d8dcd4fb8ae389d74e052",
    "layoutUserStates": {
        "12t0N12345XSGBCRB3": {
            "id": "12t0N12345XSGBCRB3",
            "sectionUserStates": {
                "01B0N00000CtD9NUAV": {
                    "collapsed": false,
                    "id": "12t0N12345XSGBCRB3"
                },
                "01B0N00000CtD9OUAV": {
                    "collapsed": false,
                    "id": "12t0N12345XSGBCRB3"
                },…

Picklist Recovery

It is a possible use case that we need to display a dropdown inside Pega with values that are configured in Salesforce, for example, a country list. It is possible to have a static copy inside a Data Type in Pega, and have a manual process to update. In case those values are not likely to be changed frequently, it could have sense. But in the case the dropdown needs to be in line, it is possible to fetch values from Salesforce by using the UI API picklist-values resource.

URI: /ui-api/object-info/{objectApiName}/picklist-values/{recordTypeId}/{fieldApiName}

{objectApiName}: Corresponds to the object name, i.e. Account.

{recordTypeId}: Corresponds to the object Salesforce ID.

{fieldApiName}: Corresponds to a field that is sourced with the picklist values we need.

To obtain the recordTypeId we can use UI API as well.

By using URL: /services/data/v49.0/ui-api/layout/{objectApiName}

This URL returns JSON which contains recrdTypeId field. For instance, for Account object it returns:

{
    "eTag": "97d7a4ba47f787fa6fcd7d464210f7a6",
    "id": "12t0N12345XSGBCRB3",
    "layoutType": "Full",
    "mode": "View",
    "objectApiName": "Account",
    "recordTypeId": "012000000000000AAA",
    "sections": […

With the record type ID we can then query dropdown values for a given field, for example, if we want to recover the country codes we could use BillingCountryCode from the Account object:

/services/data/v49.0/ui-api/object-info/Account/picklist-values/012000000000000AAA/BillingCountryCode

Response:

{
    "controllerValues": {},
    "defaultValue": null,
    "eTag": "28511895e1eb8ec26640cef8816762bf",
    "url": "/services/data/v49.0/ui-api/object-info/Account/picklist-values/012000000000000AAA/BillingCountryCode",
    "values": [
        {
            "attributes": null,
            "label": "Afghanistan",
            "validFor": [],
            "value": "AF"
        },
        {
            "attributes": null,
            "label": "Aland Islands",
            "validFor": [],
            "value": "AX"
        },…

Examples[edit]

Accounts[edit]

When working with Salesforce, it is likely that a project requires to use SalesForce accounts. In order to fetch accounts, a Data Page can be created, sourced with a connector. Depending on the requirements (search or get Account information) we can use different resources.

  • Get Account Information.
    • Resource: Objects
    • Connector Parameters: AccountID
    • URI: sobjects/Account/{AccountID}
  • Get Account Information filtered by owner.
    • Resource: Query
    • Connector Parameters: q
    • URI sobjects/query/?q={SOQL Query}
    • Query: SELECT id, Name, Description, ,BillingCountry, BillingCity, BillingStreet, CurrencyIsoCode, Owner.Name from Account WHERE OwnerId = ‘OwnerID’
  • Search Accounts by name in 50 elements pages
    • Resource: Search
    • Connector Parameters: q
    • URI sobjects/search/?q={SOSL Query}
    • Query: FIND {*{Search Text}*} IN ALL FIELDS RETURNING Account (id, Name, Description, BillingCountry, BillingCity, BillingStreet, CurrencyIsoCode, Owner.Name LIMIT 50 OFFSET {(page-1)*50} )

Currency[edit]

Salesforce maintains a Currency conversion object which is possible to query. To fetch an actual currency conversion table (along with all existing currencies inside Salesforce) it is possible to run a query connector with the following query:

SELECT Id, IsoCode, Name, IsCorporate, ConversionRate, DecimalPlaces
FROM CurrencyType WHERE IsActive=true

Field IsCorporate is true for a single record, being then considered the default currency for the entire system. Also, this currency record is used as reference for the conversion rate. This means, Conversion Rate is the relation between the record currency and the corporate currency. To explain that, here are some examples.

IsoCode IsCorporate Conversion Rate
EUR true 1.0
USD false 1.12
GBP false 0.87


2 EUR to USD: Amount multiplied by To Conversion Rate = 2USD * 1.12 = 2.24USD

2 USD to EUR: Amount divided by From Conversion Rate = 2EUR / 1.12 = 1.79EUR

2 GBP to USD: First convert to EUR, then convert to USD = (2GBP / 0.87) * 1.12 = 2.57USD

Integration Configuration Exercise[edit]

Create Salesforce test environment[edit]

Salesforce allows to create developer test instances.

URL: https://developer.salesforce.com/signup

Salesforce Sandbox 1.png

You will be requested to enter your information. This step creates your own instance and Salesforce user credentials. On submit, on first screen you receive Email to activate your account.

Salesforce Sandbox 2.png
Salesforce Sandbox 3.png

On Activation account, you get your application URL and username. After first login, you can see Salesforce welcome screen.

Create Salesforce connected Application[edit]

In order to allow access to Salesforce by REST API, a connected application must be created or configured. It can be done by accessing environment setup.

Salesforce Configuration 1.png

On the left menu select Apps -> App Manager.

Salesforce Configuration 2.png

Then click on “New Connected App”.

Salesforce Configuration 3.png

Enter application information as you desire.

Salesforce Configuration 4.png

Then enable OAuth and configure it. Callback URL corresponds to your Pega instance (it is available when you run the integration wizard under Authorization section).

Salesforce Configuration 5.png

Select from the OAuth Scopes “Manage user data via APIs (api)”.

Salesforce Configuration 6.png

Create new Pega - Salesforce Integration[edit]

Start REST Integration wizard from Configure -> Integration -> Connectors -> Create REST Integration.

Pega REST Wizard 1.png

Enter Name and Endpoint of your Salesforce instance. In this example we query accounts by name. The URL is of “query” method and Query String “q”.

Pega REST Wizard 2.png

Click on Add Authentication and select New Salesforce Oauth 2.0 with Grant type Authorization code.

Pega REST Wizard 3.png

Enter Client Information. Client Identifier and secret can be found in Salesforce application configuration. Enter the environment setup again, in the left navigation select Apps -> App Manager, then look for your application and click View from the dropdown.

Pega REST Wizard 4.png

Client Identifier corresponds to Consumer Key in Salesforce. Client Secret corresponds to Consumer Secret.

Pega REST Wizard 5.png
Pega REST Wizard 6.png

To authorize click the Connect button. A pop-up screen appears in your Salesforce Application. Enter your user credentials to grant access.

Pega REST Wizard 7.png

Continue Wizard by clicking Next. Name the resource and click again Next to advance to the JSON configuration screen.

Pega REST Wizard 8.png

To configure JSON to be used as base for this integration use the example from Salesforce. Click Add a REST response.

Pega REST Wizard 9.png

Enter the query you want to run and click on Run button. This will run the request against your instance providing the output JSON. This output will be used to generate a data model so it has properties as you select on the query. In our example we are only using “name” from Account object.

Pega REST Wizard 10.png

Salesforce will return all existing accounts along with the name.

Pega REST Wizard 11.png

Click on submit and continue Wizard. Last screen will request Data model and Ruleset information. You can use existing classes and Rulesets or create new. Filling Data layer section will end on the wizard creating the Data- class and Data Page, in case you need to use existing data model (where you will map the integration layer with your data layer) select “Skip (I’ll do it later)”. Click Create.

Pega REST Wizard 12.png

Wizard will start creating all needed resources. Progress will advance until it finishes.

Pega REST Wizard 13.png

Data Page can be tested after wizard finishes. Open and Run it. Enter same or similar query when running. Parameters for query can be removed from the Data Page, then edit Request Data Transform to setup the Query.

Pega REST Wizard 14.png

References[edit]

Salesforce Data Model

https://developer.salesforce.com/docs/atlas.en-us.sfFieldRef.meta/sfFieldRef/salesforce_field_reference.htm

Salesforce REST API

https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/intro_what_is_rest_api.htm

OAuth 2.0 Authorization

https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/intro_oauth_and_connected_apps.htm

Objects

https://developer.salesforce.com/docs/atlas.en-us.234.0.api_rest.meta/api_rest/dome_sobject_basic_info.htm

Recently Viewed

https://developer.salesforce.com/docs/atlas.en-us.234.0.api_rest.meta/api_rest/dome_see_recently_viewed.htm

SOQL Query

https://developer.salesforce.com/docs/atlas.en-us.234.0.api_rest.meta/api_rest/dome_query.htm

SOSL Search

https://developer.salesforce.com/docs/atlas.en-us.soql_sosl.meta/soql_sosl/sforce_api_calls_sosl.htm

SOQL and SOSL

https://developer.salesforce.com/docs/atlas.en-us.soql_sosl.meta/soql_sosl/sforce_api_calls_soql.htm

UI API

https://developer.salesforce.com/docs/atlas.en-us.uiapi.meta/uiapi/ui_api_quick_start.htm

Get Picklist Values

https://developer.salesforce.com/docs/atlas.en-us.210.0.uiapi.meta/uiapi/ui_api_resources_picklist_values.htm

Recommendations and limitations[edit]

  • Use search resource instead of Query for text search (like)
  • Search text is limited to a minimum of 2 characters
  • Both Query and Search require specifying the list of fields to recover, not possible to use WildCard. This requires knowing in advance the available field list and specify on query/search.
  • No complex Queries possible. Only possible using Alias when objects are related.
  • Picklist recovery is tricky, not possible to directly link to a list, needs to use a field.