Salesforce to Twitter: There is no request token for this page error. That's the special key we need from applications asking to use your Twitter account


#1

We are trying to call Twitter app from our portal based out of Salesforce.

While trying to make the call, we are facing the following error.

**Whoa there! **
There is no request token for this page. That’s the special key we need from applications asking to use your Twitter account. Please go back to the site or application that sent you here and try again; it was probably just a mistake

Would be great if someone from Salesforce could help us with the same.

Here is the code snippet we are using:

public class socialMediaControllerTwitter {

    //Constants Declaration
    final String oauthVersion = '1.0';
    final String oauthConsumerKey = 'xxxxxx';
    final String oauthConsumerSecret = 'xxxxxxx';
    final String baseUrl = 'https://api.twitter.com';
    final String oauthSignatureMethod = 'HMAC-SHA1';
    final String oauth_callback = 'https://diageodirect--sk2--c.cs3.visual.force.com/apex/testFB';
    
    String oauthTimestamp;
    String oauthNonce;
    String oauthToken;
    String oauthTokenSecret;
    String accessToken;
    String accessTokenSecret;
    
    //Generating oauth_timestamp in apex code
    private void getTimeStamp(){
        DateTime dateTimeNow = dateTime.now();
        this.oauthTimestamp = ''+(dateTimeNow.getTime()/1000);
        system.debug('oauthTimestamp-->' + oauthTimestamp);
    }
    
    //Generating oauth_nonce in apex code
    private void generateNounce() {
        final String chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz';
        String randStr = '';
        
        while (randStr.length() < 32) {
           Integer idx = Math.mod(Math.abs(Crypto.getRandomInteger()), chars.length());
           randStr += chars.substring(idx, idx+1);
        }
        this.oauthNonce =  EncodingUtil.base64Encode(Blob.valueOf(randStr)).remove('=');
        system.debug('oauthNonce-->' + oauthNonce);
    }
    
    //Generating oauth_signature  in apex code
    private String generateSignature(String httpMethod, String baseUrl, Map<String, String> params){
              
           String encodedString = '';
           Map<String, String> encodeParams = new Map<String, String>();       
           encodeParams.putAll(params);
           encodeParams.put('oauth_nonce', this.oauthNonce);
           encodeParams.put('oauth_signature_method', this.oauthSignatureMethod);
           encodeParams.put('oauth_timestamp', this.oauthTimestamp);
           encodeParams.put('oauth_consumer_key', this.oauthConsumerKey);
           encodeParams.put('oauth_version', this.oauthVersion);
           
           List<String> keyList = New List<String>();
           keyList.addAll(encodeParams.keySet());
           keyList.sort();
           
           for(String key: keyList){
               encodedString +=  EncodingUtil.urlEncode(key,'UTF-8') + '=' + EncodingUtil.urlEncode(encodeParams.get(key),'UTF-8') + '&';
           }
           encodedString = encodedString.removeEnd('&');
            
           String baseString = httpMethod.toUpperCase() + '&' + EncodingUtil.urlEncode(baseUrl,'UTF-8') + '&' + EncodingUtil.urlEncode(encodedString,'UTF-8');
           String signingKey = EncodingUtil.urlEncode(this.oauthConsumerSecret,'UTF-8') + '&';
           if(params.containsKey('oauth_token') && String.isNotBlank(this.oauthTokenSecret)){
               signingKey += EncodingUtil.urlEncode(this.oauthTokenSecret,'UTF-8');
           }   
           
           Blob data = Crypto.generateMac('hmacSHA1', Blob.valueOf(baseString), Blob.valueOf(signingKey));
           String signature =  EncodingUtil.base64Encode(data);
           system.debug('signature-->' + signature);
           return signature;
    }  
    
    //Generating the authorization header in apex code
    private String generateAuthHeader(Map<String, String> params){
           
           Map<String, String> authParams = new Map<String, String>();
           authParams.putAll(params);
           authParams.put('oauth_consumer_key', this.oauthConsumerKey);
           authParams.put('oauth_signature_method', this.oauthSignatureMethod);
           authParams.put('oauth_timestamp', this.oauthTimestamp);
           authParams.put('oauth_nonce', this.oauthNonce);
           authParams .put('oauth_version', this.oauthVersion);
           
           List<String> keyList = New List<String>();
           keyList.addAll(authParams .keySet());
           keyList.sort();
           String OathString = '';    
           for(String key: keyList){
              OathString += EncodingUtil.urlEncode(key,'UTF-8') + '=' + '"' + EncodingUtil.urlEncode(authParams.get(key),'UTF-8') + '"' + ', '; 
           }
           OathString = 'OAuth ' + OathString.removeEnd(', ');
           system.debug('OathString header-->' + OathString);
           return  OathString ;
    
    }
    
    //Apex callout to get the Request Token
    public void getAuthToken(){
    
         String requestUrl = this.baseUrl + '/oauth/request_token';
         String requestMethod = 'POST';
         
         this.getTimeStamp();
         this.generateNounce();
         
         Map<String, String> params = new Map<String, String>();
         params.put('oauth_callback', this.oauth_callback);         
         String authSignature = this.generateSignature(requestMethod, requestUrl, params);
         system.debug('authSignature inside getauthtoken method-->' + authSignature);
         
         params = new Map<String, String>();
         params.put('oauth_callback',this.oauth_callback);
         params.put('oauth_signature', authSignature);
          
          HttpRequest request = new HttpRequest();
          request.setHeader('Authorization', this.generateAuthHeader(params));
          request.setMethod(requestMethod);
          request.setEndpoint(requestUrl);
          HttpResponse response = new HttpResponse();
          this.oauthToken = '';
          Http  http = new Http();
          try{
              response = http.send(request);
              String responseBody = response.getBody();
              system.debug('responseBody-->' + responseBody);
              this.oauthToken = responseBody.substringBefore('&').substringAfter('=');
              system.debug('oauthToken -->' + oauthToken );
              this.oauthTokenSecret = responseBody.substringAfter('&').substringBetween('=','&');  //DOUBT - variable detail replaced with responsebody
              system.debug('oauthTokenSecret -->' + oauthTokenSecret );
              ApexPages.currentPage().setCookies(new Cookie[]{new Cookie('TSecret', oauthTokenSecret, null, -1, false)});
              Cookie test1stcookie = ApexPages.currentPage().getCookies().get('TSecret');
              system.debug('test1stcookie -->' + test1stcookie );
          }catch(Exception e){
              system.debug(e.getMessage());
          }
          
          //return null;  //DOUBT
    }
    
    //Authorize with User - Changed from Authenticate to Authorize
    public PageReference authenticate(){
         getAuthToken();
         String requestUrl = baseUrl + '/oauth/authenticate?oauthToken=' + this.oauthtoken + '&force_login=true';
         system.debug('requestUrl--->' + requestUrl);        
         return  new PageReference(requestUrl).setRedirect(true);
        
     }

    //Obtain the Access Token
    public void  getAccesToken(){
    
         this.oauthtoken = ApexPages.currentPage().getparameters().get('oauth_token');
       
       if(String.isNotBlank(this.oauthtoken)){
           
            String twitterId;
            Cookie counter = ApexPages.currentPage().getCookies().get('TSecret');
            if(counter != null) {
                this.oauthTokenSecret = counter.getValue();
                ApexPages.currentPage().setCookies(new Cookie[]{new Cookie('TSecret', '', null, -1, false)});
            }
    
           String requestUrl = this.baseUrl + '/oauth/access_token';
           String httpMethod = 'POST';        
           String oauthVerifier = ApexPages.currentPage().getparameters().get('oauth_verifier');
           
           this.getTimeStamp();
           this.generateNounce();
           
           Map<String, String> params = new Map<String, String>();
           params.put('oauth_token', this.oauthToken);
           params.put('oauth_verifier', oauthVerifier);           
           String authSignature = this.generateSignature(httpMethod, requestUrl, params);
           
           params = new Map<String, String>();
           params.put('oauth_token',this.oauthtoken);
           params.put('oauth_signature',authSignature);
           
           HttpRequest request = new HttpRequest();
           HttpResponse response = new HttpResponse();
           Http  http = new Http();
           request.setEndPoint(requestUrl);
           request.setMethod(httpMethod);
           request.setHeader('Authorization', this.generateAuthHeader(params));
           request.setBody('oauth_verifier='+EncodingUtil.urlEncode(oauthVerifier, 'UTF-8'));
           try{
              response = http.send(request);
              String responseBody = response.getBody();
              this.oauthToken = responseBody.substringBetween('oauth_token=', '&');
              this.oauthTokenSecret = responseBody.substringBetween('oauth_token_secret=', '&');
              twitterId = responseBody.substringBetween('user_id=', '&');
              
              //detail = twitterId; --DOUBT commented
          }catch(Exception e){
              system.debug(e.getMessage());
          }
          
      }
       
    }
    
}

#2

Hi @RoyCWC, we’re not going to be able to provide much guidance on a SalesForce integration. Since this is a SalesForce error message and not a message returned by Twitter, you’ll need to reach out to them through their channels.