Monday, August 25, 2014

Creating Calendar event in Google from salesforce using Oauth

To Create a calendar event in google you need to set up OAuth between Salesforce and Google.

You need to create an app in Google. Navigate to
https://code.google.com/apis/console and create a project.

Vf Page:
<apex:page controller="CalenderConnect">
<apex:form >
  <apex:commandButton value="Google" action="{!doGoogleConnectCall}"/><br/>
</apex:form>
</apex:page>

Controller:
public class CalenderConnect {
    private final string googleClientID = ' Your Project ID';
    private final string googleSecretCode = 'Your Project Secret';
    private final string redirectURI = 'https://c.ap1.visual.force.com/apex/calender';
    private string authorizationCode = '';
    private string state = '';
    private string accessToken;
    private string refreshToken;
    private string expiresIn;
    private string tokenType;
 
     public CalenderConnect(){
        authorizationCode = System.currentPageReference().getParameters().get('code');
        if(authorizationCode != null){
            state = System.currentPageReference().getParameters().get('state');
            accessToken = '';
                retrieveGoogleAccessToken();
                if(accessToken <> ''){
                    addCalendarEntry();
                }              
        }
    }

    public pageReference doGoogleConnectCall(){

        PageReference pr = new PageReference('https://accounts.google.com/o/oauth2/auth' +
            '?response_type=code' +
            '&client_id=' + googleClientID +
            '&redirect_uri=' + redirectURI +
            '&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar' +
            '&state=' + 'vcalender ' +
            '&access_type=online' +
            '&approval_prompt=auto' +  //auto, force
            '&login_hint=xxxx@gmail.com');
            System.debug(pr);
        return pr;
    }
    private void retrieveGoogleAccessToken(){
        Http h = new Http();
        HttpRequest req = new HttpRequest();
        string endPointValue = 'https://accounts.google.com/o/oauth2/token';  
        req.setEndpoint(endPointValue);
     
        string bodyRequest = '';
        bodyRequest = 'code=' + EncodingUtil.urlEncode(authorizationCode, 'UTF-8');
        bodyRequest += '&client_id=' + EncodingUtil.urlEncode(googleClientID, 'UTF-8');
        bodyRequest += '&client_secret=' + EncodingUtil.urlEncode(googleSecretCode, 'UTF-8');
        bodyRequest += '&redirect_uri=' + EncodingUtil.urlEncode(redirectURI, 'UTF-8');
        bodyRequest += '&grant_type=authorization_code';
        req.setBody(bodyRequest);    
        req.setHeader('Content-length', string.ValueOf(bodyRequest.length()));
        req.setHeader('Content-Type', 'application/x-www-form-urlencoded');
        req.setMethod('POST');
        req.setTimeout(10000);
        HttpResponse res = h.send(req);  
        map<string, string> jsonValues = new map<string, string>();
     
        System.debug('Response Value:'+res.getBody());
        jsonValues = parseJSONToMap(res.getBody());
        if(jsonValues.containsKey('error')){
        }else{
            //Try to get a cell value in the Google Spreadsheet
            accessToken = jsonValues.get('access_token');
            refreshToken = jsonValues.get('refresh_token');
            expiresIn = jsonValues.get('expires_in');
            tokenType = jsonValues.get('token_type');        
        }    
    }
      private void addCalendarEntry(){
        Http h = new Http();
        HttpRequest req = new HttpRequest();
        string endPointValue = 'https://www.googleapis.com/calendar/v3/calendars/primary/events';
        //This end point does seem to work, but it is not creating an event, just creating a new calendar
        //endPointValue = 'https://www.googleapis.com/calendar/v3/calendars?key=' + googleClientID;
        req.setEndpoint(endPointValue);  
        string bodyRequest = '';
        bodyRequest = '{';
        bodyRequest += '\r\n';
        bodyRequest += '"summary": "Sales Call",';
        bodyRequest += '\r\n';
        bodyRequest += '"location": "Conference Room A",';
        bodyRequest += '\r\n';
        bodyRequest += '"start": {';
        bodyRequest += '\r\n';
        bodyRequest += '"dateTime": "2014-07-26T08:00:00.000-07:00",';
        bodyRequest += '\r\n';
        bodyRequest += '"timeZone": "America/Los_Angeles"';
        bodyRequest += '\r\n';
        bodyRequest += '},';
        bodyRequest += '\r\n';
        bodyRequest += '"end": {';
        bodyRequest += '\r\n';
        bodyRequest += '"dateTime": "2014-07-26T08:30:00.000-07:00",';
        bodyRequest += '\r\n';
        bodyRequest += '"timeZone": "America/Los_Angeles"';
        bodyRequest += '\r\n';
        bodyRequest += '},';
        bodyRequest += '\r\n';
        bodyRequest += '"recurrence": [';
        bodyRequest += '\r\n';
        bodyRequest += '"RRULE:FREQ=WEEKLY;UNTIL=20131226T000000Z"';
        bodyRequest += '\r\n';
        bodyRequest += '],';      
        bodyRequest += '\r\n';
        bodyRequest += '"attendees": [';
        bodyRequest += '\r\n';
        bodyRequest += '{';
        bodyRequest += '\r\n';
        bodyRequest += '"email": "xxxxx@gmail.com"';
        bodyRequest += '\r\n';
        bodyRequest += '}';
        bodyRequest += '\r\n';
        bodyRequest += ']';
        bodyRequest += '}';
     
        req.setBody(bodyRequest);    
        System.debug(bodyRequest);
        req.setHeader('Authorization', 'Bearer ' + accessToken);
        req.setHeader('Content-length', string.ValueOf(bodyRequest.length()));
        req.setHeader('Content-Type', 'application/json; charset=UTF-8');
        req.setMethod('POST');
        req.setTimeout(10000);
        HttpResponse res = h.send(req);
        System.debug(res.getBody());
    }
 
    private map<string, string> parseJSONToMap(string JSONValue){
        JSONParser parser = JSON.createParser(JSONValue);
        map<string, string> jsonMap = new map<string, string>();
        string keyValue = '';
        string tempValue = '';
        while (parser.nextToken() != null) {
            if(parser.getCurrentToken() == JSONToken.FIELD_NAME){
                keyValue = parser.getText();
                parser.nextToken();
                tempValue = parser.getText();
                jsonMap.put(keyValue, tempValue);            
            }
        }
        return jsonMap;
    }
 
}

6 comments :

  1. Hello. I am getting the below error when i click on the button. Please help me and let me know the settings i need to configure.

    Error: invalid_client

    The OAuth client was not found.
    Request Details

    scope=https://www.googleapis.com/auth/calendar
    response_type=code
    redirect_uri=https://c.ap1.visual.force.com/apex/calender
    access_type=online
    login_hint=ashishbaranwal242@gmail.com
    approval_prompt=auto
    state=vcalender
    client_id= Your Project ID

    ReplyDelete
  2. Hi Ashish

    You need to provide client_id
    This is my google client id
    306772550204-ms9hsdbhba2tr915sqlq9iue3msid9ue.apps.googleusercontent.com

    ReplyDelete
  3. How can we acheive same thing using trigger.

    ReplyDelete
    Replies
    1. Can do that even with trigger. Will update you once i do that. I will do that in a couple of days

      Delete
    2. I am facing same problem while implementing it using trigger.

      Delete
    3. Hi Raju,

      Even I tried with using trigger. But it didn't succeed the reason is that it is having a callback which is pointing to a page and the code is generated. With that code we need make authorization.

      Delete

Labels

visualforce page ( 13 ) apex integration ( 5 ) apex trigger ( 4 ) csv file from vf page ( 4 ) javascript ( 4 ) csv visualforce page ( 3 ) Too many ( 2 ) call out ( 2 ) integration ( 2 ) rest api ( 2 ) salesforce rest api ( 2 ) salesforce to salesforce integration ( 2 ) sfdc rest api ( 2 ) trigger ( 2 ) 15 digit to 18 digit ( 1 ) DML rows in Apex ( 1 ) Date Conversion ( 1 ) Date/Time conversion ( 1 ) Deploy ( 1 ) Objects to Future Annotated Methods ( 1 ) SFDC limits ( 1 ) Sobject to Future Annotated Methods ( 1 ) Test Class ( 1 ) TimeZone Conversion ( 1 ) Too many dml rows ( 1 ) Too many future calls ( 1 ) annotations ( 1 ) apex code ( 1 ) closed opportunities ( 1 ) commit ( 1 ) convert ( 1 ) create records ( 1 ) csv create records ( 1 ) custom setting ( 1 ) deployment ( 1 ) deployment changeset ( 1 ) disable apex class ( 1 ) disable apex trigger ( 1 ) disable in production ( 1 ) document ( 1 ) download ( 1 ) field name ( 1 ) formula fields ( 1 ) iframe ( 1 ) inactive ( 1 ) intellisense ( 1 ) jsforce ( 1 ) limits ( 1 ) matrix report in vf page ( 1 ) multi select ( 1 ) multi select salesforce ( 1 ) multiselect ( 1 ) paypal ( 1 ) picklist ( 1 ) record type ( 1 ) rollback ( 1 ) salesforce limits ( 1 ) salesforce list ( 1 ) salesforce map ( 1 ) salesforce rest ( 1 ) salesforce set ( 1 ) salesforce1 ( 1 ) sandbox deployment ( 1 ) sfdc collection ( 1 ) sfdc list ( 1 ) sfdc map ( 1 ) sfdc rest ( 1 ) sfdc set ( 1 ) uncommitted ( 1 ) updated field ( 1 ) user ( 1 ) validation rule opportunity ( 1 ) validation rules opportunities ( 1 ) vf page ( 1 )

Ad