Let say I have two Salesforce org say ORG A and ORG B. Our requirement is to fetch data from ORG B and display it in ORG A.
Let's start,
ACTIVITIES WE NEED TO DO IN ORG B.
1) Create a
Connected App in ORG B.
2) Create a Webservice in ORG B which will be invoked from ORG A to get the data.
Create A
Connected App In ORG B:
Configure a connected app as shown below in ORG B and Click Save.
Note down the Consumer key, Consumer secret (We need to provide it ORG A for authentication purpose along with username, password, security token of the user from ORG B which ORG A will be using for authentication).
A callback URL is the URL that is invoked after OAuth
authorization for the consumer (connected app). In some contexts, the URL must
be a real URL that the client’s web browser is redirected to. In others, the
URL isn’t actually used, but the value between your client app and the server
(the connected app definition) must be the same. Here we are providing the URL
of ORG A in the format as asked in comment for Callback URL.
Create A Webservice
As Shown Below In ORG B:
Now, create a Webservice as shown below in ORG B.
The below Webservice is expecting email and phone number of
the contact in request and is returning the associated contact record back.
@RestResource(urlMapping='/getContactFromEmailAndPhone/*')
global with sharing class getContactRecord {
@Httpget
global static Contact fetchContact(){
Contact obj=new Contact();
RestRequest req = RestContext.request;
RestResponse res = Restcontext.response;
Map<String, String> requestParam = req.params;
String conEmail=requestParam.get('email');
String conPhone=requestParam.get('phone');
obj=[Select id,lastname,email,phone from contact where email=:conEmail
and phone=:conPhone];
/***Modify the HTTP status code that will be returned to external
system***/
res.statuscode=201;
/***Modify the HTTP status code that will be returned to external
system***/
return obj;
}
}
ACTIVITIES
WE NEED TO DO IN ORG A.
1) Create an Apex controller which will call Webservice in
ORG B.
2) Create a Visualforce page to display the contact
information received from ORG B.
3) Create a remote site setting for the URL of System B.
Let’s start,
To store the Username, Password, Consumer key, Consumer
secret provided by ORG B, create a custom metadata as shown below in ORG A.
Note: The password will be combination of
password and security token of the user from ORG B without any space.
Now, create a record under the above custom metadata as shown below.
CREATE AN APEX CONTROLLER:
Now, create an Apex controller which will call Webservice in
ORG B. This apex controller method will be invoked from Visualforce Page to get
the necessary data from ORG B. As of now, for explanation we are hardcoding the
email and phone number of the contact as shown in below class to get the
contact associated with this email and phone from ORG B. This can be made
dynamic as per the requirement.
public class restApiTofetchSingleRecord {
private string cKey;
private string cSecret;
private string uName;
private string passwd;
public string instanceURL;
public static list < resultWrapper > listWrap {
get;
set;
}
public restApiTofetchSingleRecord() {
listWrap = new list < resultWrapper > ();
}
public class responseWrapper {
public string id;
public string access_token;
public string instance_url;
}
public responseWrapper getRequestToken() {
List < Store_Cred__mdt > connectionParam = [SELECT Id,
MasterLabel, client_id__c, client_secret__c, username__c, password__c from
Store_Cred__mdt];
if(connectionParam.size() >0){
cKey=connectionParam[0].client_id__c;
cSecret=connectionParam[0].client_secret__c;
uName=connectionParam[0].username__c;
passwd=connectionParam[0].password__c ;
}
System.debug('Store_Cred__mdt' + connectionParam);
string reqBody = 'grant_type=password&client_id=' + cKey +
'&client_secret=' + cSecret + '&username=' + uName + '&password=' +
passwd;
Http h = new Http();
HttpRequest req = new HttpRequest();
req.setBody(reqBody);
req.setMethod('POST');
req.setEndpoint('https://login.salesforce.com/services/oauth2/token');
HttpResponse hresp = h.send(req);
responseWrapper wResp = (responseWrapper) JSON.deserialize(hresp.getBody(),
responseWrapper.class);
system.debug('reqBody '+reqBody );
system.debug('wResp'+wResp );
system.debug('Instance url' + wResp.instance_url);
system.debug('session id' + wResp.access_token);
return wResp;
}
public void getConList() {
string integration1 = 'Testing integration';
list < account > accList1 = new list < account > ();
String accToken;
String instanceUrl;
string responseBody;
string email = 'testemail123@gmail.com';
string phone = '123';
restApiTofetchSingleRecord obj = new restApiTofetchSingleRecord();
responseWrapper obj1= obj.getRequestToken();
accToken = obj1.access_token;
instanceUrl = obj1.instance_url;
string endPoint = instanceURL+'/services/apexrest/getContactFromEmailAndPhone/?'
+ 'email=' + email + '&phone=' + phone;
system.debug('endPoint'+endPoint );
system.debug('access token' + accToken);
if (accToken != '') {
Http h1 = new Http();
HttpRequest req1 = new
HttpRequest();
req1.setHeader('Authorization',
'Bearer ' + accToken);
req1.setHeader('Content-Type',
'application/json');
req1.setMethod('GET');
req1.setEndpoint(endPoint);
HttpResponse hresp1 =
h1.send(req1);
system.debug('hresp1'+hresp1 );
system.debug('hresp1.getStatusCode()'+hresp1.getStatusCode());
system.debug('hresp1.getBody()'+hresp1.getBody());
if (hresp1.getStatusCode() == 201)
{
resultWrapper wResp1 =
(resultWrapper) JSON.deserialize(hresp1.getBody(), resultWrapper.class);
listWrap.add(wResp1);
}
}
}
public class resultWrapper {
public string id {
get;
set;
}
public string LastName{
get;
set;
}
public string Email{
get;
set;
}
public string Phone{
get;
set;
}
}
}
CREATE A VISUALFORCE
PAGE:
<apex:page controller="restApiTofetchSingleRecord">
<apex:form >
<apex:pageBlock >
<apex:pageblockButtons >
<apex:commandButton value="TEST"
action="{!getConList}"/>
</apex:pageblockButtons>
<apex:pageblocktable
value="{!listWrap}" var="a" >
<apex:column
value="{!a.LastName}"/>
<apex:column value="{!a.Email}"/>
<apex:column
value="{!a.Phone}"/>
</apex:pageBlockTable>
</apex:pageBlock>
</apex:form>
</apex:page>
Remote Site URL:
The remote site
url here is nothing but the instance URL of ORG B.
Now, we are done
with complete setup of customization and configuration needed in ORG A and ORG
B.
Before testing
try to ensure that the contact with email “testemail123@gmail.com” and phone “123”
exist in ORG B as we are trying to get contact associated with this information
from ORG B.
Now, Lets
preview the Visualforce page, click the “TEST” button.
How to we do the same if we need to display any Images?
ReplyDeleteSorry for the late reply. I have not checked yet, but I will update here if i try the same.
DeleteIf its using Named Credentials, what changes we need to make on Apex controller?
ReplyDeleteSorry but could you please explain in detail what exactly you want.
DeleteHi, after login is success how can we open SYSTEM B's home page? Thanks
ReplyDeleteHow can we hide username, password, client secret etc from the apex class?
ReplyDeleteYou can use custom labels or custom settings or custom metadata to store username, password, client secret etc and than refer them in apex class.
DeleteJust use Named Credentials
DeleteHello, the response of the oauth call is "access_token":"SESSION_ID_REMOVED"?
ReplyDeleteHow fix this?
In debug log you will not be able to see it. however in class you can access it.
DeleteHi, How to I include composite data in request body?
ReplyDeleteHello, Iam not able to see connected app under create apps? can anyone help me please
ReplyDeleteCleared 90% of my doubts... Thanks a lot for the resource
ReplyDelete