The Lookup app is called : "Record lookup"
Access to the lookup
Connected app
Even if you have selected the option to install the app for admins only, it is necessary to go and allow the system admin profile in the Connected App installed with the package: "connected_app_dqe_one"
- Manage the connected app
- Then add the profile to the list of allowed profiles.
Named credentials
Lookup instance in Unify Server
The named credential is created during the installation called "Customer DQE One" :
Lookup instance outside Unify Server
To perform the configuration, you will need to create a named credential pointing to your instance of Unify Lookup Server.
To do this, go to setup > named credentials > new named credentials
Custom Settings
- Go to the custom settings section, there will be a custom settings called "Unify Lookup".
- Click manage and create an instance at your organization's default level.
- Fill in the API name of the correct named credential (check previous section) and the DQE License (API Key) provided
Access to the Record Lookup app
You can now go to the lightning Record Lookup app and click Connect at the bottom of the Setup tab. This will establish the connection between your Salesforce org and your instance of Unify Lookup Server.
Setup the federated search
If you want to use the Record Lookup app search from your Salesforce org, there's an integration method to search directly through the global search bar
To secure calls to the server, we only allow the organization that has registered to make requests. To set this up, it is necessary to create a connected app as well as an Auth. Provider.
Creating a connected app
To get started, go to the Setup section > App Manager > New Connected App.
- Fill in the mandatory information in the first section, namely:
- App Name
- API Name
- Contact Email
- Then select the Enable OAuth Settings checkbox so that the next section appears.
- Select the full and refresh_token scopes, offline_access.
- Enter a temporary callback url.
- Save your connected app
Creating an auth. provider
To create a new Auth. Provider, then go to the section: Setup > Auth. Provider > New Auth. Provider.
- Select as type: Salesforce
- Give your Provider a name.
- Let the suffix url fill in on its own.
- Copy the Consumer key from your connected app.
- Copy the Consumer secret from your connected app.
- Leave the default URLs.
- Fill in the same scope as entered in your Connected App.
(Normally: full refresh_token offline_access)
Creating an external data source
To add an external data source, simply go to the section: Setup > External data sources > New External Data Source
And to add an external data source by filling in the following information:
- External Data Source: The desired name to identify the source. (For example, Unify Records)
- Name: The API name (autofill)
- Type: Federated Search: OpenSearch
- OpenSearchDescriptionURL: The url exposing the description of the response format in XML. This url is always the one that allows access to your Heroku application and entered in the named credential of Unify Lookup, followed by /api/openSearch.xml.
- Identity type: Named Principal
- Authentication Protocol: OAuth 2.0
- Authentication Provider: Select the previously created Authentication Provider.
- Scope: Fill with exactly the same scope as in your Connected App and Auth. Provider. Normally: full refresh_token offline_access.
- Check the box to authenticate during backup.
As soon as the backup is made, the source must be validated and synchronized with the organization using the "Validate and Sync" button.
After this synchronization, an "External Object" is automatically created describing the structure of the responses that the organization receives when it calls on the external source.
Using the search bar
One of the possibilities to perform pre-existence searches is to use the search bar Global.
Currently, Salesforce's Federated Search does not support drop-down suggestion, it is necessary to validate the search with "enter" to see the different results displayed.
Configuring the search layout
As soon as the external object is created, it is possible to customize the list of fields displayed when presenting the results. In the previous example, the list of fields has been greatly expanded. This is because only the Title column and DisplayURL are present by default.
To customize this section: Setup > External Objects > Unify Records > Search Layout
Creating custom actions and buttons
If you want to allow your users to create Leads, Contacts, or other Salesforce objects from Unify Records that have been identified in external sources, you can create custom actions and buttons for each external object.
Beforehand, you must create a dedicated "External Lookup Relationship" field for each SObject in the "Object Manager". Example for the "Lead" object below:
Select "External Lookup Relationship" and then click "Next"
Fill in the fields like the example below (you can choose your own naming rules), and click "Next"
By default, select all fields as "Visible"
Select all the Layouts on which you want to be able to use this feature and click on "Next"
Finally, fill in as below and click "Save"
You then need to create the dedicated button : Setup > External Objects > Unify Records > Buttons Links & Actions > New Action
This allows you to add a custom action to create a record and pre-populate the values with the values in the Unify Record object.
Note: Before you can create a record of any type, you need to add a relationship link between it and the Unify Record type (Target Object field), hence the field was created in the previous step.
Once the button is created: Setup > External Objects > Unify Records > Buttons Links & Actions > New Lead
Click the row
Carry out your mapping according to the fields you want to pre-fill when retrieving data from the external source, example below
Click "New", select the field name from "Field Name", click "Show Formula Editor", then "Insert Field" and select the field you want to map.
Finally, click on "Save".
Guide API
In this section, we describe the set of APIs exposed by the Record Lookup app.
Federated Search
OpenSearch Description
Salesforce provides a comprehensive integration protocol for external data sources. Its full documentation can be found here.
To meet the standard of this protocol, the Unify Lookup application exposes an API respecting the XML-Atom standard in two parts, the first being the description of the format.
- Road: /api/openSearch.xml
- Call:
curl -X GET \https://[YOUR APP URL]/api/openSearch.xml
- Answer
Since the format must be unique for all responses, the list of fields is immutable. For each type of record you index in the Unify Lookup app, it is possible to map an address, email, phone number as well as first and last name.
The Source field corresponds to the type of record.
For example, if the app indexes the following Salesforce objects, some possible values are Lead, Account, Contact.
For external tables from PostgreSQL, the source is named after the table.
OpenSearch Format
The second API in the OpenSearch format is the request for a resource itself.
When this API is used from the external source search bar in your Salesforce org, the settings are passed automatically.
- Route: /api/openSearch
- Parameter:
- search: (string) search terms
- orgId: (string) the Salesforce org ID
- Call:
curl -X GET \https://[YOUR HEROKU APP URL]/API/OPENSearch?search=Ms. Cha Fadner&orgId=[YOUR ORG ID]
- Answer
REST Api
Aside from the XML APIs that are geared towards being consumed from your Salesforce org, the Unify Lookup server exposes a few other APIs that allow you to perform a real-time pre-existence lookup from your external systems. In this section, we describe them one by one as well as their methods of appeal.
Authentication
It should be noted that all the APIs described below are secured by a Basic Auth. This code is composed as the login of the Identifier of the registered Salesforce organization, and as the password the license key provided by DQE-Software (the same one you had to enter in the environment variables of your Heroku application).
Search
This API is an auto-completion engine on a single search line. It allows you to obtain a list of suggested potential records that match the search criteria.
Route: /api/searchRecords
Parameters:
- search : (string)
Structure of the response:
The response takes the form of a list of objects structured as follows.
Key | Type | Description |
Id | string | Record ID. The internal objects of your Salesforce org are identifiers. |
Spring | string | The name of the Salesforce object or PostgreSQL table from which the record originated |
FirstName | string | Value in record at last indexing |
LastName | string | Value in record at last indexing |
Phone | string | Value in record at last indexing |
string | Value in record at last indexing | |
Street | string | Value in record at last indexing |
City | string | Value in record at last indexing |
PostalCode | string | Value in record at last indexing |
State | string | Value in record at last indexing |
Country | string | Value in record at last indexing |
Example call:
curl -X GET \
-H "Authorization: Basic {authorization_header}" \
https://[YOUR HEROKU APP URL]/API/SEARCHRecords?search=Ms. Chantal Fadner
Sample answer:
[
{
"Id": "00Q0900000E3ded7FUEAZ",
"Source": "Lead",
"FirstName": "rerere",
"LastName": "azazaza",
"Phone": "0*****31",
"Email": "*****@hotmail.fr",
"Street": "R************NIERES",
"City": "A**********X",
"PostalCode": "12345",
"State": ""
"Country": "France",
}
]
Lookup
This API can be used to perform a pre-existence search by comparing a complete record with all indexed records.
Route: /api/lookupRecords
Parameters:
You can provide any key/value pair present in your form, either in the body of your query, or in the query params. Be careful to case the settings because keys not found in the records are simply ignored.
Structure of the response:
The response takes the form of a list of objects structured as follows.
Key | Type | Description |
Id | string | Record ID. The internal objects of your Salesforce org are identifiers. |
Spring | string | The name of the Salesforce object or PostgreSQL table from which the record originated |
FirstName | string | Value in record at last indexing |
LastName | string | Value in record at last indexing |
Phone | string | Value in record at last indexing |
string | Value in record at last indexing | |
Street | string | Value in record at last indexing |
City | string | Value in record at last indexing |
PostalCode | string | Value in record at last indexing |
State | string | Value in record at last indexing |
Country | string | Value in record at last indexing |
Example call:
curl -X GET \
-H "Authorization: Basic {authorization_header}" \
https://[YOUR HEROKU APP URL]/API/LOOKUPRecords? Email=airelue.fc@laposte.net&PostalCode=77961&MobilePhone&Phone=0695473336&Street=Rue du Clos Gillet&FirstName=Aurélie&LastName=FUALKNER
Sample answer:
[
{
"Phone": "**********",
"City": "A*****LE",
"FirstName": "Au****ei",
"MobilePhone": "",
"State": "",
"PostalCode": "12345",
"LastName": "F****ER",
"Country": "France",
"Email": "ai******@laposte.net",
"Street": "Rue ********et",
"Id": "00Q0900000E37F3EAJ",
"Source": "Lead"
},
{
"Phone": "",
"City": "A*****LLE",
"FirstName": "A*****ie",
"MobilePhone": "",
"State": "",
"PostalCode": "12345",
"LastName": "FU*****ER",
"Country": "France",
"Email": "a********c@laposte.net",
"Street": "Ru*****et",
"Id": "00Q0900000E37F1EAJ",
"Source": "Lead"
}
]
If no deduplication rule sets have been imported into your application:
{
"status": "error",
"error": "No rules set loaded yet"
}
Golden record
This API can be used to perform a pre-existence search by comparing a complete record with all indexed records. But unlike the previous one, it will only return the card with the best match score.
Route: /api/lookupGolden
Parameters:
You can provide any key/value pair present in your form either in the body of your query or in the query params. Be careful to case the settings because keys not found in the records are simply ignored.
Structure of the response:
Key | Type | Description |
Certainty | float | Match Rate |
Matched_by | string | The name of the deduplication rule that brought this card closer to your record. |
Id | string | Record ID. The internal objects of your Salesforce org are identifiers. |
Spring | string | The name of the Salesforce object or PostgreSQL table from which the record originated |
FirstName | string | Value in record at last indexing |
LastName | string | Value in record at last indexing |
Phone | string | Value in record at last indexing |
string | Value in record at last indexing | |
Street | string | Value in record at last indexing |
City | string | Value in record at last indexing |
PostalCode | string | Value in record at last indexing |
State | string | Value in record at last indexing |
Country | string | Value in record at last indexing |
Examples of calls:
- GET:
curl -X GET \
-H "Authorization: Basic {authorization_header}" \
https://[YOUR APP URL]/api/lookupGolden? Email=ai************.net&PostalCode=1234&MobilePhone&Phone=*******&Street=Ru*********t&FirstName=A******&LastName=F*****
- POST:
curl --location 'https://[YOUR APP URL] /api/lookupGolden' \
--header "Authorization: Basic {authorization_header}" \
--header 'Content-Type: text/plain' \
--data-raw '{
"recordType": "PersonAccount",
"FirstName": "S*****",
"LastName": "T****",
"PersonEmail": "s************id"
}'
Sample answer:
- If a match has been found in the database and the query is well formed
{
"certainty": 0.05298333333333333335,
"matched_by": "Address",
"record": {
"Phone": "***************",
"City": "**********",
"FirstName": "Au***********",
"MobilePhone": "",
"State": "",
"PostalCode": "12345",
"LastName": "*******************",
"Country": "France",
"Email": "******************.net",
"Street": "Rue ****************et",
"Id": "00Q0900000E37F3EAJ",
"Source": "Lead"
}
}
- If no deduplication rule sets have been imported into your application
{
"status": "error",
"error": "No rules set loaded yet"
}
- In all other cases
{
"status": "error",
"error": "bad request"
}
Add record
If you want to add a record to your indexing registry without having to restart a process across your entire Salesforce database, you can use this API by providing the card you want to index.
Route: /api/add
Parameters:
- recordType: SObject API Name (e.g. Lead, Account, Contact...)
- Id: Salesforce Id
You can also provide any key/value pair present in your record in the query params during this call. Be careful to case the settings because keys not found in the records are simply ignored.
Examples of calls:
- GET:
curl -X GET \
-H "Authorization: Basic {authorization_header}" \
https://[YOUR HEROKU APP URL]/api/add?recordType=Lead&Email=a************e.net&PostalCode=12345&MobilePhone&Phone=0************&Street=Rue*************&FirstName=A**********&LastName=F********R
- POST:
curl --location 'https://[YOUR HEROKU APP URL]/API/ADD' \
--header 'Authorization: Basic {authorization_header}' \
--header 'Content-Type: text/plain' \
--data-raw '{"0": {
"Phone":"0***********6",
"BillingStreet":"R***********t",
"BillingPostalCode":"12345",
"LastName":"*****",
"PersonEmail":"a**************t",
"BillingCity":"H*****************Y",
"id":"[SALESFORCE ID]",
"FirstName":"A****************e",
"attributes": {"type":"PersonAccount"}
}
}'
Sample answer:
- If the operation is successful
{
"status": "success",
"label": "Record added"
}
- If the object's API name isn't one of the objects that are currently allowed to be indexed:
{
"status": "error",
"label": "RecordType not mapped in your application"
}
In this case, it is necessary to go to the ligthning Unify Lookup app and add the object.
- If the record could not be added because the redis database is running out of storage:
{
"status": "error",
"label": "memory > max memory"
}
- In all other cases
{
"status": "error",
"error": "bad request"
}
Remove record
If you want to delete a record from your indexing registry without having to restart a process across your entire Salesforce database, you can use this API by providing the card you want to index.
Route: /api/delete
Parameters:
- recordType: SObject API Name (e.g. Lead, Account, Contact...)
- Id: Salesforce Id
You can also provide any key/value pair present in your record in the query params during this call. Be careful to case the settings because keys not found in the records are simply ignored.
Examples of calls:
- Delete a single record
curl -X GET
-H "Authorization: Basic {authorization_header}"
https://[YOUR HEROKU APP URL]/API/DELETE? Id=00DX00000DJ19Q&recordType=Lead&Email=a*********net&PostalCode=12345&MobilePhone&Phone=0**6&Street=R*et&FirstName=A*e&LastName=*
- Delete a multiple records
curl -X POST https://[YOUR HEROKU APP URL]/API/DELETE
-H "Authorization: Basic {authorization_header}"
-d "[JSON Data]"
The json body should be structured as follows:
{
recordId: {
"attributes": {
"type": recordType
}
},
recordId: {
"attributes": {
"type": recordType
}
}
}
Sample answer:
- If the operation is successful
{
"status": "success",
"label": "Record(s) removed"
}
- In all other cases
{
"status": "error",
"error": "Failed to remove record"
}
Index Database
This API allows you to start the global indexing process on an object. It requires that the object is already added (via the interface) to the list of objects, and that a "ruleset" is configured for it.
Route: /api/add
Parameters:
- recordType: SObject API Name (e.g. Lead, Account, Contact...)
- Target: Salesforce Org URL (in https://xxx format.my.salesforce.com)
- token: valid Salesforce session token
- User: The Salesforce username associated with the session token
Example call:
- GET:
curl -X GET \
-H "Authorization: Basic {authorization_header}" \
https://[YOUR HEROKU APP URL]/API/INDEX?recordType=Lead&token=XXXXXXXXXX&user=myusername@test.com&target=mysforg.my.salesforce.com
Sample answer:
- If the operation is successful:
{
"status": "success",
"label": "indexing by Bulk started"
}
- If the object's API name isn't one of the objects that are currently allowed to be indexed:
{
"status": "error",
"label": "RecordType not mapped in your application"
}
In this case, it is necessary to go to the ligthning Unify Lookup app and add the object.
- In all other cases:
{
"status": "error",
"error": "bad request"
}
APEX Rest Resources
The AppExchange Unify Lookup package provides resources in the form of Apex classes that can be invoked from your Apex classes but also in the form of APIs.
Authentication
The API resources described below can only be accessed by providing a valid Salesforce token retrieved through the OAuth2 API. The {authorization_header} variable in the following examples represents this session token.
UpdateDB
To insert or remove records from the indexed database, you can use this REST resource. All you have to do is provide it with the record identifiers, the type of object and the operation to be applied.
Route: [YOUR SALESFORCE DOMAIN]/services/apexrest/UnifyLookup/updateDB/
Parameters:
- ids : Salesforce Records Identifiers Separated by Commas
- recordType: SObject API Name (e.g. Lead, Account, Contact...)
- Action: Insert or Delete
Example of a call:
curl -X GET https://[YOUR SALESFORCE DOMAIN]/services/apexrest/UnifyLookup/updateDB/?
ids=0017R00002ryGbZQAU,0017R00002kqzFHQAY&sObjectName=Account&action=insert
-H "Authorization: Bearer {authorization_header}"
Sample answer:
- If the operation (insert) is successful:
{
"status": "success",
"label": "Record added"
}
- If any error occurs:
{
"status": "error",
"label": "Failed to add record"
}
Calling from an apex class
It is also possible to call the function directly from your apex functions because the apex function is defined as global.
- deleteRecord
List<String> ids = new List<String>{'0017R00002ryGbZQAU', '0017R00002kqzFHQAY'};
String sObjectName = 'Account';
Map<String, String> res = UnifyLookup.DQE_Lookup_update_db.deleteRecord(ids, sObjectName);
- insertRecord
List<String> ids = new List<String>{'0017R00002ryGbZQAU', '0017R00002kqzFHQAY'};
String sObjectName = 'Account';
Map<String, String> res = UnifyLookup.DQE_Lookup_update_db.insertRecord(ids, sObjectName);
Related to