Let say I have two Salesforce org say ORG A and
ORG B. Our requirement is whenever Account record is created in Salesforce ORG
A and when certain conditions are meet we need to create the same Account
record in ORG B. The integration between ORG A and ORG B should be done using
client credential flow.
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 create the contact record.
Create A Connected App In ORG B:
Configure a connected app as shown below in ORG
B and Click Save.
Select Enable Client Credentials Flow as shown below.
Note down the Consumer key, Consumer secret (We
need to provide it to ORG A 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.
Although there’s no user interaction in the
client credentials flow, Salesforce still requires you to specify an execution
user. By selecting an execution user, you allow Salesforce to return access
tokens on behalf of this user.
From the connected app detail page, click
Manage.
Click Edit Policies.
Under Client Credentials Flow, for Run As, click
Magnifying glass icon, and find the user that you want to assign the client
credentials flow.
Create A
Webservice As Shown Below In ORG B:
Now, create a Webservice as shown below in ORG
B.
The below Webservice is expecting Name,
Description, Type, Industry and is creating an Account record and is returning
True or False based on if Account record is created successfully or not.
@RestResource(urlMapping='/createAccountRecord/*')
global with sharing class
createAccountRecord {
@HttpPost
global Static string createAccount(){
RestRequest req = RestContext.request;
RestResponse res = Restcontext.response;
string
jsonString=req.requestBody.tostring();
system.debug('jsonString'+jsonString);
boolean successCheck;
List<responseWrapper>
wRespList=(List<responseWrapper>) JSON.deserialize(jsonString,List<responseWrapper>.class);
Account obj=new Account();
List<Account> accList= new
List<Account>();
for(responseWrapper wResp: wRespList){
obj.Name=wResp.Name;
obj.Description=wResp.Description;
obj.Type=wResp.Type;
obj.Industry=wResp.Industry;
accList.add(obj);
}
try{
if(accList.size() > 0){
Insert accList;
successCheck=true;
}
}
catch(Exception e){
successCheck=false;
}
if(successCheck)
return 'Success';
else
return 'Failure';
}
global class responseWrapper{
global string Name;
global string Description;
global string Type;
global string Industry;
}
}
ACTIVITIES WE NEED TO DO IN
ORG A.
1) Create an
apex trigger and apex controller.
2) Create a
remote site setting for the URL of ORG B.
Create a custom
metadata to store the Consumer key, Consumer secret provided by ORG B as shown
below.
Now, create a
record under the above custom metadata as shown below.
APEX TRIGGER IN ORG A:
The below apex
trigger will be invoked after Account record is inserted in ORG A and it will
call controller created in ORG A if Account Type is not null and equal to
Prospect and this apex controller will further call Webservice in ORG B to
create the same Account record.
trigger Accounttrigger on Account (after insert) {
Set<id>
accIdSet=new Set<id>();
for(Account
acc:trigger.new){
if(acc.Type!=Null && acc.Type=='Prospect'){
accIdSet.add(acc.id);
}
}
if(accIdSet.size()
> 0){
restApiToCreateRecord.createAccount(accIdSet);
}
}
CREATE AN APEX
CONTROLLER:
Now,
create an Apex controller which will call Webservice in ORG B. This apex
controller method will be invoked from apex trigger created above.
public class restApiToCreateRecord {
private string cKey;
private string cSecret;
private string uName;
private string passwd;
public string instanceURL;
public restApiToCreateRecord () {
}
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;
}
System.debug('Store_Cred__mdt' + connectionParam);
string reqBody = 'grant_type=client_credentials&client_id=' + cKey +
'&client_secret=' + cSecret;
Http h = new Http();
HttpRequest req = new HttpRequest();
req.setBody(reqBody);
req.setMethod('POST');
req.setEndpoint('https://farukh-dev-ed.my.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;
}
@future (callout=true)
public static void createAccount(Set < id > accIdSet) {
list < account > accList = new list < account > ();
String accToken;
String instanceUrl;
string responseBody;
restApiToCreateRecord obj = new restApiToCreateRecord();
responseWrapper obj1= obj.getRequestToken();
accToken = obj1.access_token;
instanceUrl = obj1.instance_url;
string endPoint = instanceURL+'/services/apexrest/createAccountRecord';
system.debug('endPoint'+endPoint );
system.debug('access token' + accToken);
if (accToken != '') {
for (Account acc: [SELECT Id,Name,Description,Type,Industry from account
where id in: accIdSet]) {
accList.add(acc);
}
Http h1 = new Http();
HttpRequest req1 = new HttpRequest();
req1.setHeader('Authorization', 'Bearer ' + accToken);
req1.setHeader('Content-Type', 'application/json');
req1.setMethod('POST');
req1.setEndpoint(endPoint);
req1.setBody(JSON.serialize(accList));
HttpResponse hresp1 = h1.send(req1);
system.debug('hresp1'+hresp1 );
system.debug('hresp1.getStatusCode()'+hresp1.getStatusCode());
system.debug('hresp1.getBody()'+hresp1.getBody());
if (hresp1.getStatusCode() == 200) {
system.debug('Callout Success');
}
}
}
}
REMOTE SITE STORED IN ORG A:
The remote site
url here is nothing but the instance URL of ORG B.
Now, Lets try to
create an account record in ORG A manually with Account Type as Prospect.
Now, Check the
same record will be created in ORG B as well.
thank you.
ReplyDeleteI have an error in trigger variable does not exists:callWebserviceClass
ReplyDeleteThanks for resource bro. But how to Integrate salesforce to SAP by using code.?
ReplyDelete