Salesforce 推特集成 |错误 - {"errors":[{"code":32,"message":"Could not authenticate you."}]}

Salesforce Twitter Integration | Error - {"errors":[{"code":32,"message":"Could not authenticate you."}]}

我在使用“https://api.twitter.com/1/statuses/update.json?status=Test

时出现以下错误

遵循的步骤:

  1. 获取请求令牌 - POST oauth / request_token
  2. 授权
  3. 将请求令牌转换为访问令牌 - POST oauth / access_token
  4. 在第 3 步响应中得到 oauth_token 和 oauth_token_secret。

现在我想使用“https://api.twitter.com/1/statuses/update.json?status=Test”从 salesforce 到 twitter 发推文,但出现以下错误:

response - System.HttpResponse[Status=Authorization Required, StatusCode=401]

response.getBody() - {"errors":[{"code":32,"message":"Could not authenticate you."}]}

OauthString = OAuth oauth_consumer_key="ILFzs0lcUiHwJsbpuWU4tTdk3",oauth_nonce="RElxMGNiWFJMOGp2V2VRcHB5aU96REhqYnVnbHZXc2o",oauth_signature="2aWbL3JASeSgNRaDQ%2BgLNXpH8dA%3D",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1466659830",oauth_token="743383838253002753-L4gdS3UCxKZVGTtQ0SHxSMlVtJREIBk",oauth_version="1.0"

提前致谢

谢谢, 拉胡尔

如果您添加更多创建和 post 推文的代码,我们可以更快地了解问题所在。我可以与您分享 APEX 代码,我在我的项目中使用它来处理 Twitter API:

public class SO2TP_TwitterUtil{
    public static final String[] SIGNATURE_KEYS = new String[]{
        'oauth_consumer_key', 
        'oauth_nonce', 
        'oauth_signature_method', 
        'oauth_timestamp', 
        'oauth_token', 
        'oauth_version', 
        'status'
    };

    public static final String[] OAUTH_KEYS = new String[]{
        'oauth_consumer_key',
        'oauth_nonce',
        'oauth_signature',
        'oauth_signature_method',
        'oauth_timestamp',
        'oauth_token',
        'oauth_version'
    };

    public String algorithmName{
        get{
            if(algorithmName == null)
                return 'hmacSHA1';
            return algorithmName;
        } 
        set;}
    public String oauth_signature_method{
        get{
            if(oauth_signature_method == null)
                return 'HMAC-SHA1';
            return oauth_signature_method;
        }
        set;}
    public String oauth_version{
        get {
            if(oauth_version == null)
                oauth_version = '1.0';
            return oauth_version;
        } 
        set;}          
    public String http_method {get; set;}
    public String base_url {get; set;}
    public String status {get; set;}
    public String oauth_consumer_key {get; set;}
    public String oauth_consumer_secret {get; set;}
    public String oauth_token {get; set;}
    public String oauth_token_secret {get; set;}

    public String oauth_nonce {get; private set;}
    public String oauth_signature {get; private set;}
    public String oauth_timestamp {
        get {
            if(oauth_timestamp == null)
                oauth_timestamp = String.valueOf(DateTime.now().getTime()/1000);
            return oauth_timestamp;
        }
        private set;}

    private map<String, String> signaturePairs {get; set;}
    private String parameterString {get; set;}
    private String signatureBaseString {get; set;}
    private String signingKey {get; set;}
    private String oauth_header {get; set;}
    private String http_body {get; set;}

    public SO2TP_TwitterUtil () {}

    public SO2TP_TwitterUtil(String oauth_consumer_key, String oauth_consumer_secret, 
            String oauth_token, String oauth_token_secret) {
        this.oauth_consumer_key = oauth_consumer_key;
        this.oauth_consumer_secret = oauth_consumer_secret;
        this.oauth_token = oauth_token;
        this.oauth_token_secret = oauth_token_secret;
    }

    public Boolean sendTweet(String status, map<String, String> additionalParams){
        if(this.oauth_consumer_key == null ||
                this.oauth_consumer_secret == null ||
                this.oauth_token == null || 
                this.oauth_token_secret == null)
            return false;

        this.http_method = 'POST';
        this.base_url = 'https://api.twitter.com/1.1/statuses/update.json';
        this.status = status;
        generateNonce();
        initializeSignatureKeyValuePairs(additionalParams);
        generateOauthSignature();
        generateOauthHeader();
        generateHttpBody(additionalParams);

        Http h = new Http();
        HttpRequest req = new HttpRequest();
        req.setMethod(this.http_method);
        req.setEndpoint(this.base_url);
        req.setBody(this.http_body);
        req.setHeader('Content-Type', 'application/x-www-form-urlencoded');
        req.setHeader('Content-Length', String.valueOf(req.getBody().length()));
        req.setHeader('Authorization', this.oauth_header);

        try {
            HttpResponse res = h.send(req);           
            if(res.getStatusCode() == 200)
                return true;
            else 
                return false;
        } catch (CalloutException e) {
            return false;
        }
        return true;
    }

    private void generateNonce() {
        String validChars = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
        Integer len = validChars.length();
        String randomString = '';        
        for(Integer i=0; i<32; i++) {
            Integer rInt = Integer.valueOf(Math.rint(Math.random()*(len-1)));
            randomString += validChars.substring(rInt, rInt+1);
        }
        this.oauth_nonce = randomString;
    }

    private void initializeSignatureKeyValuePairs(map<String, String> additionalParams) {
        this.signaturePairs = new map<String, String>();
        this.signaturePairs.put('status', this.status);
        this.signaturePairs.put('oauth_consumer_key', this.oauth_consumer_key);
        this.signaturePairs.put('oauth_nonce', this.oauth_nonce);
        this.signaturePairs.put('oauth_signature_method', this.oauth_signature_method);
        this.signaturePairs.put('oauth_timestamp', this.oauth_timestamp);
        this.signaturePairs.put('oauth_token', this.oauth_token);
        this.signaturePairs.put('oauth_version', this.oauth_version);
        if(additionalParams != null && additionalParams.keySet().size() > 0) {
            for(String key : additionalParams.keySet()) {
                if(!this.signaturePairs.containsKey(key) && additionalParams.get(key) != null) {
                    //system.debug('**** adding key: ' + key + ' and value: ' + additionalParams.get(key));
                    this.signaturePairs.put(key, additionalParams.get(key));
                    SIGNATURE_KEYS.add(key);
                }
            }
        }
        SIGNATURE_KEYS.sort();
    }

    private void generateOauthSignature() {
        this.parameterString = createParameterString();
        this.signatureBaseString = createSignatureBaseString();
        this.signingKey = createSigningKey();
        this.oauth_signature = createOauthSignature();
    }

    private String createParameterString() {
        String paramString = '';
        system.debug(json.serializepretty(signaturePairs));
        for(String key : SIGNATURE_KEYS) {
            paramString += SO2TP_StringUtil.percentEncode(key);
            paramString += '=';
            paramString += SO2TP_StringUtil.percentEncode(signaturePairs.get(key));
            paramString += '&';
        }
        paramString = removeLastNLetters(paramString, 1);
        system.debug('**** Parameter String');
        system.debug(paramString);
        return paramString;
    }

    private String createSignatureBaseString() {
        String sigBase = '';
        sigBase += this.http_method.toUpperCase() ;
        sigBase += '&';
        sigBase += SO2TP_StringUtil.percentEncode(this.base_url);
        sigBase += '&';
        sigBase += SO2TP_StringUtil.percentEncode(this.parameterString);
        system.debug('**** Signature Base String');
        system.debug(sigBase);
        return sigBase;
    }

    private String createSigningKey() {
        String signKey = SO2TP_StringUtil.percentEncode(this.oauth_consumer_secret);
        signKey += '&';
        signKey += SO2TP_StringUtil.percentEncode(this.oauth_token_secret);
        system.debug('**** Signing Key');
        system.debug(signKey);
        return signKey;
    }

    private String createOauthSignature() {
        Blob mac = Crypto.generateMac(this.algorithmName, 
                Blob.valueOf(this.signatureBaseString), Blob.valueOf(this.signingKey)); 
        string hashedValue = EncodingUtil.convertToHex(mac);
        String oauthSig = EncodingUtil.base64Encode(mac);
        system.debug('**** Hashed Value');
        system.debug(hashedValue);
        system.debug('**** Oauth Signature');
        system.debug(oauthSig);
        return oauthSig;  
    }

    private void generateOauthHeader() {
        map<String, String> oauthParams = new map<String, String>();
        oauthParams.put('oauth_consumer_key', this.oauth_consumer_key);
        oauthParams.put('oauth_nonce', this.oauth_nonce);
        oauthParams.put('oauth_signature', this.oauth_signature);
        oauthParams.put('oauth_signature_method', this.oauth_signature_method);
        oauthParams.put('oauth_timestamp', this.oauth_timestamp);
        oauthParams.put('oauth_version', this.oauth_version);
        oauthParams.put('oauth_token', this.oauth_token);
        String header = 'OAuth ';
        for(String key : OAUTH_KEYS) {
            header += SO2TP_StringUtil.percentEncode(key);
            header += '="';
            header += SO2TP_StringUtil.percentEncode(oauthParams.get(key));
            header += '", ';
        }
        this.oauth_header = removeLastNLetters(header, 2);
        system.debug('**** Oauth Header');
        system.debug(this.oauth_header);
    }

    private void generateHttpBody(map<String, String> additionalParams) {
        String httpBody = 'status='+EncodingUtil.urlEncode(this.status, 'UTF-8');
        if(additionalParams != null && additionalParams.keySet() != null) {
            for(String key : additionalParams.keySet()) {
                if(additionalParams.get(key) != null) {
                    httpBody += '&';
                    httpBody += EncodingUtil.urlEncode(key, 'UTF-8');
                    httpBody += '=';
                    httpBody += EncodingUtil.urlEncode(additionalParams.get(key), 'UTF-8');
                }
            }
        }
        this.http_body = httpBody.replace('*', '%2A');
        system.debug('**** Request Body: ');
        system.debug(this.http_body);
    }

    private static String removeLastNLetters(String source, Integer numToRemove) {
        return source.subString(0, source.length()-numToRemove);
    }
}

请找到我下面的代码,它不起作用。

VF 页面:

<apex:page controller="TestTwitterIntegrationController"> 
<apex:form > 
    <apex:commandButton value="OAuth" action="{!getAuthToken}" /> 
    <br/> 
    <br/> 
    <apex:commandButton value="Tweet" action="{!tweetPost}" /> 
</apex:form> 

控制器:

    public class TestTwitterIntegrationController  
    {    
        public String testInput{get;set;} 
        final String oauthVersion = '1.0';
        final String oauthConsumerKey = 'ILFzs0lcUiHwJsbpuWU4tTdk3';
        final String oauthConsumerSecret = 'C3mxd7GpRzBs88WJeaXBcRFELdRyI56F7VZZIOiq74uXz3hJFi';
        final String baseUrl = 'https://api.twitter.com';
        final String oauthSignatureMethod = 'HMAC-SHA1';
        final String oauth_callback = 'https://lightningdemo1492-dev-ed--rahullightning.ap2.visual.force.com/apex/TestTwitterIntegration';

        String oauthTimestamp;
        String oauthNonce;
        String oauthToken;
        String oauthTokenSecret;
        String accessToken;
        String accessTokenSecret;
    String oauth_token;
    String oauth_verifier;

    public TestTwitterIntegrationController(){

        this.oauth_token = ApexPages.currentPage().getParameters().get('oauth_token');
        this.oauth_verifier = ApexPages.currentPage().getParameters().get('oauth_verifier');
        /*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)});
        }*/

    }


    private void getTimeStamp(){
        DateTime dateTimeNow = dateTime.now();
        this.oauthTimestamp = ''+(dateTimeNow.getTime()/1000);
    }

    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('=');
    }

    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');
           }   
           system.debug('signingKey - '+signingKey);

           Blob data = Crypto.generateMac('hmacSHA1', Blob.valueOf(baseString), Blob.valueOf(signingKey));
           String signature =  EncodingUtil.base64Encode(data);
           system.debug('data - '+data);
           system.debug('signature - '+signature);
           return signature;
    }  

    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);

           system.debug('authParams - '+authParams);

           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 - '+OathString);
           return  OathString ;

    }

   public PageReference 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);

        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();

        response = http.send(request);
        system.debug('response - '+response);
        String responseBody = response.getBody();
        this.oauthToken = responseBody.substringBefore('&').substringAfter('=');
        system.debug('response.getBody() - '+response.getBody());
        system.debug('oauthToken - '+oauthToken);
        this.oauthTokenSecret = responseBody.substringAfter('&').substringBetween('=','&');
        system.debug('oauthTokenSecret - '+oauthTokenSecret);
        ApexPages.currentPage().setCookies(new Cookie[]{new Cookie('TSecret', oauthTokenSecret, null, -1, false)});


        String finalRequestUrl = baseUrl + '/oauth/authorize?oauth_token=' + this.oauthtoken;         
        return  new PageReference(finalRequestUrl).setRedirect(true);
    }   

    public void  tweetPost(){

       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)});
            }

            system.debug('this.oauthTokenSecret - '+this.oauthTokenSecret);

            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);
                system.debug('response - '+response);
                system.debug('response.getBody() - '+response.getBody());
                String responseBody = response.getBody();
                this.oauthToken = responseBody.substringBetween('oauth_token=', '&');
                this.oauthTokenSecret = responseBody.substringBetween('oauth_token_secret=', '&');
                system.debug('this.oauthToken - '+this.oauthToken);
                system.debug('this.oauthTokenSecret - '+this.oauthTokenSecret);
                twitterId = responseBody.substringBetween('user_id=', '&');

                tweetPostMethod();
            }catch(Exception e){
                system.debug(e.getMessage());
            }

        }

    }

    public void tweetPostMethod(){

        String requestUrl = 'https://api.twitter.com/1.1/statuses/update.json';
        String requestMethod = 'POST';

        this.getTimeStamp();
        this.generateNounce();

        Map<String, String> params = new Map<String, String>(); 

        params.put('oauth_token', this.oauthToken);
        params.put('status', 'TestFromSFDC123');
        system.debug('tweetPostMethod | this.oauthToken - '+this.oauthToken);
        system.debug('tweetPostMethod | this.oauthTokenSecret - '+this.oauthTokenSecret);

        String authSignature = this.generateSignature(requestMethod, requestUrl, params);
        params = new Map<String, String>();
        params.put('oauth_token',this.oauthtoken);
        params.put('oauth_signature',authSignature);

        HttpRequest request = new HttpRequest();
        request.setMethod(requestMethod);
        request.setEndpoint(requestUrl);
        String httpBody = 'status='+EncodingUtil.urlEncode('TestFromSFDC', 'UTF-8');
        request.setBody(httpBody);
        request.setBody(httpBody);         
        request.setHeader('Content-Type', 'application/x-www-form-urlencoded');
        request.setHeader('Content-Length', String.valueOf(request.getBody().length()));
        request.setHeader('Authorization', this.generateAuthHeader(params));

        HttpResponse response = new HttpResponse();
        Http http = new Http();

        response = http.send(request);
        system.debug('response - '+response);
        system.debug('response.getBody() - '+response.getBody());


    }
}

*步骤:

  1. 单击 "Oauth" 按钮
  2. 授权应用
  3. 单击 "Tweet" 按钮