Salesforce to Salesforce Integration using Metadata Api and get contacts from Org

With the use of OAuth 2.0 Web Server Authentication Flow

The Web server authentication flow is used by applications that are hosted on a secure server. A critical aspect of the Web server flow is that the server must be able to protect the consumer secret. You can also use code challenge and verifier values in the flow to prevent authorization code interception.
The following diagram displays the authentication flow steps for Web server clients. The individual step descriptions follow.
remoteaccess_oauth_web_flow

Now here some steps of get contacts using Metadata Api

Step-1: Create blank page with “CallBackURL” Name
Initially we will create a blank page like:

<apex:page showHeader="false" sidebar="false" standardStylesheets="false">
</apex:page>

Step-2: Create Site
Now we have to create an site for getting access code:
To create a site:

      From Setup, click Develop | Sites.
      In the Sites section, click New.

Enter information to create a site like:
site

When you’ve finished entering the information, click Save to save.

Step-3: Create Connected App
Create a Connected App
To create a connected app:

      From Setup, click Create | Apps.
      In the Connected Apps section, click New.

Enter information to create a connected app.
connectedApp
When you’ve finished entering the information, click Save to save your new app. You can now publish your app, make further edits, or delete it. If you’re using OAuth, saving your app gives you two new values the app uses to communicate with Salesforce:
Consumer Key: A value used by the consumer to identify itself to Salesforce. Referred to as client_id in OAuth 2.0.
Consumer Secret: A secret used by the consumer to establish ownership of the consumer key. Referred to as client_secret in OAuth 2.0.

See in below image:
connectedApp2

Step-4:Now we have to Create Classes
In this class Web server redirects the user to Salesforce to authenticate and authorize the server to access data on their behalf and get access code. we have to create
“authController” class.

public with sharing class authController{    
    public pagereference CallApi(){
        string clientId='XXXXXXXXXXXXXXXXXXXXXX';
        String clientSecret='XXXXXXXXXXXXXXXXXXXXXX'; 
        return new pagereference( 'https://login.salesforce.com/services/oauth2/authorize?response_type=code&client_id=' + clientId + '&redirect_uri=your_global_site/callbackurl&prompt=login&display=popup&state=state' );
    }
}

Now we have to include a MetadataService class from this GitHub click here

After including of above class we have to create another classes:
MetaController Class:

public with sharing class MetaController {     
     public static MetadataService.MetadataPort createService(string accTkn){
        MetadataService.MetadataPort service = new MetadataService.MetadataPort();
        service.SessionHeader = new MetadataService.SessionHeader_element();
        service.SessionHeader.sessionId = accTkn;
        return service;
     }
}

CallBackURLController Class:

public with sharing class CallBackURLController{
    public string bodyCode{get;set;}
    public string bodyInfo{get;set;}
    public string cd{get;set;}
    public string hd{get;set;}
    public list<contact> lstCon{get;set;}
    //constructor
    public CallBackURLController(){
        string vrsn=[select name from version__c].name;
        string Accesscode=ApexPages.currentPage().getParameters().get('code');
        Accesscode=Accesscode.replace('=','%3D').trim();
        cd=Accesscode;
        string clientId='XXXXXXXXXXXXXXXXXXXXXX';
        String clientSecret='XXXXXXXXXXXXXXXXXXXXXX';
        String redireUri='https://forcedroid-developer-edition.ap2.force.com/callbackurl';
        string loginUri='https://login.salesforce.com';
        string ContentType = 'application/json';
 
        ///// Get Access Token
        HttpRequest req = new HttpRequest();  
        req.setMethod('POST');
        string reqbody='grant_type=authorization_code' +
            '&client_id=' + clientId +
            '&client_secret=' + clientSecret +
            '&code=' + Accesscode +
            '&redirect_uri=' + redireUri;
        req.setEndpoint(loginUri+'/services/oauth2/token?'+reqbody);
        Http http = new Http();  
        HTTPResponse res = http.send(req);
        bodyCode=res.getBody();
        Map<String, object> mapReqBody=(Map<String, object>)JSON.deserializeUntyped(res.getBody());
        string header=string.valueOf(mapReqBody.get('token_type'))+' '+string.valueOf(mapReqBody.get('access_token'));
        hd=header;        
        
        ///// Get User Info
        HttpRequest reqInfo = new HttpRequest();  
        reqInfo.setMethod('POST');
        reqInfo.setEndpoint(loginUri+'/services/oauth2/userinfo');
        reqInfo.setHeader('Content-Type', ContentType);
        reqInfo.setHeader('Authorization', header);
        Http httpInfo = new Http();  
        HTTPResponse resInfo = httpInfo.send(reqInfo);
        bodyInfo=resInfo.getBody();
        Map<String, object> mapReqInfoBody=(Map<String, object>)JSON.deserializeUntyped(resInfo.getBody());       
        
        /////Make Query Request
        Map<String, object> tmp=(Map<String, object>)mapReqInfoBody.get('urls');
        string queryUri=string.valueOf(tmp.get('query')).replace('{version}',vrsn);
        MetadataService.MetadataPort service = MetaController.createService(header);
        queryUri=queryUri+'?q=select+id,name,phone+from+contact+where+phone+!=null+limit+1000';  
        HttpRequest reqQry = new HttpRequest();
        reqQry.setEndpoint(queryUri);
        reqQry.setMethod('GET');        
        reqQry.setHeader('Authorization', header);
        reqQry.setHeader('Content-Type', ContentType);
        Http httpQry = new Http();
        HTTPResponse resQry = httpQry.send(reqQry);
        bodyInfo=resQry.getBody();
        Map<String, object> mapReqQryBody=(Map<String, object>)JSON.deserializeUntyped(resQry.getBody());
        string strCons =JSON.serialize(mapReqQryBody.get('records'));
        lstCon=(list<contact>) JSON.deserialize(strCons, List<contact>.class);
    }
}

When we make different-different request we will get different-different JSON responses like:
1) Response of Access Token

{
    "id": "https://login.salesforce.com/id/00D28000000c5B3EAI/00528000000GPjpAAG",
    "issued_at": "xxxxxxxxxxxxxxxxxxxxxxx",
    "token_type": "Bearer",
    "instance_url": "https://ap2.salesforce.com",
    "signature": "xxxxxxxxxxxxxxxxxxxxxxxxxx",
    <strong>"access_token": "xxxxxxxxxxxxxxxxxxx"</strong>
}

Using this access token we can get User Info .

2) Response of User Info
After making a valid request Salesforce returns the information in JSON format, by default, or whatever is specified in the Format parameter.
The following is a response in JSON format:

{"sub":"http://login.salesforce.com/id/00Dx000.../005x000...",
"user_id":"005x000...","organization_id":"00Dx000...",
"preferred_username":"user1@1135222488950007.com",
"nickname":"user1.3860098879512678E12",
"name":"na1 LastName",
"email":"user1@1135222488950007.com",
"email_verified":true,"given_name":"na1","family_name":"LastName",
"zoneinfo":"America/Los_Angeles",
"photos":{"picture":"http://na1.salesforce.com/profilephoto/005/F","thumbnail":"http://na1.salesforce.com/profilephoto/005/T"},
"profile":"http://na1.salesforce.com/005x000...",
"picture":"http://na1.salesforce.com/profilephoto/005/F",
"address":{"country":"us"},
"urls":{"enterprise":"http://na1.salesforce.com/services/Soap/c/{version}/00Dx00...",
"
"partner":"http://na1.salesforce.com/services/Soap/u/{version}/00Dx00...",
"rest":"http://na1.salesforce.com/services/data/v{version}/",
"sobjects":"http://na1.salesforce.com/services/data/v{version}/sobjects/",
"search":"http://na1.salesforce.com/services/data/v{version}/search/",
"query":"http://na1.salesforce.com/services/data/v{version}/query/",
"recent":"http://na1.salesforce.com/services/data/v{version}/recent/",
"profile":"http://na1.salesforce.com/005x000...",
"feeds":"http://na1.salesforce.com/services/data/v{version}/chatter/feeds",
"groups":"http://na1.salesforce.com/services/data/v{version}/chatter/groups",
"users":"http://na1.salesforce.com/services/data/v{version}/chatter/users",
"feed_items":"http://na1.salesforce.com/services/data/v{version}/chatter/feed-items"},
"active":true,"user_type":"STANDARD","language":"en_US","locale":"en_US","utcOffset":-28800000,"updated_at":"2013-12-02T18:46:42.000+0000"
}

3) Response of Query
Using User Info we can get urls for making requests like query which is we want to use for getting contacts.
After making query request we will get contacts in JSON format.

Step-5:Now we have to Create and Upgrade pages

Now we upgrading CallBackURL page.

<apex:page controller="CallBackURLController" showHeader="false" sidebar="false" standardStylesheets="false">
     <apex:pageBlock >
         <apex:pageBlockTable value="{!lstCon}" var="con">
             <apex:column value="{!con.name}"/>
             <apex:column value="{!con.phone}"/>
         </apex:pageBlockTable>
    </apex:pageBlock>
</apex:page>

And also create new page for test our integration with the name of “AuthCall”.

<apex:page controller="authController">
  <apex:form >
  <apex:commandButton value="TEST" action="{!CallApi}"/>
  </apex:form>
</apex:page>

Step-6:Now it’s time to testing
Now we have to click preview button of AuthCall page and then we found that screen:

test

After that we have to click on Test button and then we will seeing login screen:

login

Now we have to login and after login a dialog box will be appear that access permission dialog box. in this dialog box we have to click in allow that dialog box is appear like that screen:

access allow

And after this dialog box we will get contacts and also we get access code see in url like that:
output

Advertisements

3 thoughts on “Salesforce to Salesforce Integration using Metadata Api and get contacts from Org

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s