0

Nous essayons d'implémenter Twitter nouvelle DM API de Salesforce. Nous envoyons notre requête JSON dans le corps comme mentionné dans la documentation mais la méthode héritée pour l'autorisation Oauth ne fonctionne pas. Toute aide est grandement appréciée. Pour ajouter, j'envoie un DM de salesforce à twitter, donc 1) Je suis en train de définir le corps de la demande dans JSON. 2) Je fais un POST. 3) J'atteins l'extrémité à 'https://api.twitter.com/1.1/direct_messages/events/new.json' 4) Oauth2, obtenant le jeton d'accès (avec succès) 5) Définir l'en-tête comme ('Content-Type', 'application/json'). 6) Création de l'en-tête Authorization sous la forme de mentions Twitter à l'aide de la clé de consommateur, de Nonce, de Signature, de la méthode de signature, d'horodatage, de la version. Construire le même que dans la section "Guide" de developer.twitter.com/fr/docs/basics/authentication/guides/ 7) Sur l'exécution du code d'erreur "{" erreurs ": [{" code ": 32," message ":"Impossible de vous authentifier."}]}". Une autre information importante que j'avais utilisé l'ancienne API de Twitter pour envoyer DM qui fonctionne parfaitement, seule différence est qu'il envoie le corps de la requête dans les paramètres d'URL au lieu du corps JSOn mais la méthode d'autorisation reste la même. Comme certaines nouvelles fonctionnalités ne peuvent être réalisées que via Twitter New API et selon la documentation, le corps doit être envoyé via le format JSON. Par conséquent, la partie de requête est modifiée mais l'autorisation est la même.Twitter nouvelle DM API, ancienne méthode d'autorisation ne fonctionne pas

Exemple de code: -

String accTok = 'redacted'; 
String conKey = 'redacted'; 
String conSec = 'redacted'; 
String accTokSec = 'redacted'; 

String theTweet = 'Hello world!'; 
String screenName ='some_test_username'; 
String jsonString = TwitterJsonReqGenerator.generateJSON(theTweet, screenName); 
system.debug('JSON string ='+jsonString); 

httpRequest newReq = new httpRequest(); 
newReq.setBody(jsonString); 
newReq.setMethod('POST'); 
newReq.setEndpoint('https://api.twitter.com/1.1/direct_messages/events/new.json'); 

//Generate Nonce 
string oAuth_nonce = EncodingUtil.base64Encode(blob.valueOf(string.valueOf(Crypto.getRandomInteger()+system.now().getTime())+string.valueOf(Crypto.getRandomInteger()))).replaceAll('[^a-z^A-Z^0-9]',''); 

map<String, String> heads = new map<String, String>{ 
    'oauth_token'=>accTok, 
    'oauth_version'=>'1.0', 
    'oauth_nonce'=>oAuth_nonce, 
    'oauth_consumer_key'=>conKey, 
    'oauth_signature_method'=>'HMAC-SHA1', 
    'oauth_timestamp'=>string.valueOf(system.now().getTime()/1000) 
}; 

//Alphabetize 
string[] paramHeads = new string[]{}; 
paramHeads.addAll(heads.keySet()); 
paramHeads.sort(); 
string params = ''; 
for(String encodedKey : paramHeads){ 
    params+=encodedKey+'%3D'+heads.get(encodedKey)+'%26'; 
} 

//params+='status'+percentEncode('='+percentEncode(theTweet)); 
params+=percentEncode(theTweet); 

//Build the base string 
string sigBaseString = newReq.getMethod().toUpperCase()+'&'+EncodingUtil.urlEncode(newReq.getEndpoint(),'UTF-8')+'&'+params; 
system.debug('signatureBaseString == '+sigBaseString); 

//calculate signature 
string sigKey = EncodingUtil.urlEncode(conSec,'UTF-8')+'&'+EncodingUtil.urlEncode(accTokSec,'UTF-8'); 
blob mac = crypto.generateMac('hmacSHA1', blob.valueOf(sigBaseString), blob.valueOf(sigKey)); 
string oauth_signature = EncodingUtil.base64Encode(mac); 
heads.put(EncodingUtil.urlEncode('oauth_signature','UTF-8'), EncodingUtil.urlEncode(oauth_signature,'UTF-8')); 

//build the authorization header 
paramHeads.clear(); 
paramHeads.addAll(heads.keySet()); 
paramHeads.sort(); 
string oAuth_Body = 'OAuth '; 
for(String key : paramHeads){ 
    oAuth_Body += key+'="'+heads.get(key)+'", '; 
} 
oAuth_Body = oAuth_Body.subString(0, (oAuth_Body.length() - 2)); 
newReq.setHeader('Authorization', oAuth_Body); 
system.debug('Authroization Header == '+oAuth_Body); 
newReq.setHeader('Content-Type', 'application/json'); 

httpResponse httpRes = new http().send(newReq); 
String response = httpRes.getBody(); 

system.debug(response); 

Merci Prateek

+0

Pouvez-vous envoyer votre code par modifier cette question? –

+0

Bonjour Dima, Merci d'avoir répondu. –

+1

Vous devriez envisager d'ajouter des informations sur votre problème, comme ce qui ne fonctionne pas. En outre, vous devriez envisager d'ajouter des informations sur le projet, comme la technologie que vous utilisez. Échantillon de code sont également très appréciés dans ce cas – Nicolas

Répondre

0

J'ai écrit des bibliothèques et des applications Twitter dans le passé, et les conseils bst que je peux vous donner est d'utiliser un existant implémentation d'OAuth au lieu d'essayer d'écrire les vôtres. Ré-implémenter OAuth dans un nouveau code réinvente la roue, et c'est une roue qui vous déteste. Il existe un certain nombre de bibliothèques OAuth robustes et matures qui sont gratuites et/ou open source.

+0

Merci DWRoelands pour l'info, nous avons essayé mais nous n'avons pas pu trouver de librairies supportant la nouvelle API Twitter pour DM. S'il vous plaît laissez-nous savoir si vous avez quelque chose de particulier à l'esprit. Toute aide est grandement appréciée. –

0

Juste arrivé à trébucher sur votre requête. Je poste un code (C#) (même si c'est un peu en retard) qui a fonctionné pour moi d'envoyer DM à Twitter en utilisant la nouvelle API. J'espère que cela t'aides. Merci à Danny Tuppeny's blog

namespace TweetApp.Droid 
{ 
class TweetDM 
{ 
    const string TwitterApiBaseUrl = "https://api.twitter.com/1.1/"; 
    readonly string consumerKey, consumerKeySecret, accessToken, accessTokenSecret; 
    readonly HMACSHA1 sigHasher; 
    readonly DateTime epochUtc = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); 

    public TweetDM(string consumerKey, string consumerKeySecret, string accessToken, string accessTokenSecret) 
    { 
     this.consumerKey = consumerKey; 
     this.consumerKeySecret = consumerKeySecret; 
     this.accessToken = accessToken; 
     this.accessTokenSecret = accessTokenSecret; 

     sigHasher = new HMACSHA1(new ASCIIEncoding().GetBytes(string.Format("{0}&{1}", consumerKeySecret, accessTokenSecret))); 
    } 

    public Task<string> Tweet(string text, string recipientID) 
    { 
     JSONObject jasonobject = new JSONObject 
     { 
      @event = new TwitterEvent 
      { 
       type = "message_create", 
       message_create = new msg_create 
       { 
        target = new tgt 
        { 
         recipient_id = recipientID 
        }, 
        message_data = new msg_data 
        { 
         text = text 
        } 
       }, 
      } 
     }; 

     var JsonString =JsonConvert.SerializeObject(jasonobject); 


     var data4Auth = new Dictionary<string, string> { 
     }; 
     return PrepareAuth("direct_messages/events/new.json", data4Auth, JsonString); 
     } 

    Task<string> PrepareAuth(string url, Dictionary<string, string> data4Auth, string JsonString) 
    { 
     var fullUrl = TwitterApiBaseUrl + url; 

     var timestamp = (int)((DateTime.UtcNow - epochUtc).TotalSeconds); 

     data4Auth.Add("oauth_consumer_key", consumerKey); 
     data4Auth.Add("oauth_signature_method", "HMAC-SHA1"); 
     data4Auth.Add("oauth_timestamp", timestamp.ToString()); 
     data4Auth.Add("oauth_nonce", "a"); // Required, but Twitter doesn't appear to use it, so "a" will do. 
     data4Auth.Add("oauth_token", accessToken); 
     data4Auth.Add("oauth_version", "1.0"); 

     // Generate the OAuth signature and add it to our payload. 
     data4Auth.Add("oauth_signature", GenerateSignature(fullUrl, data4Auth)); 

     // Build the OAuth HTTP Header from the data. 
     string oAuthHeader = GenerateOAuthHeader(data4Auth); 

     // Setting Content details 
     var JsonData = new StringContent(JsonString, Encoding.UTF8, "application/json"); 
     return SendRequest(fullUrl, oAuthHeader, JsonData); 
    } 

    string GenerateSignature(string url, Dictionary<string, string> data) 
    { 
     var sigString = string.Join(
      "&", 
      data 
       .Union(data) 
       .Select(kvp => string.Format("{0}={1}", Uri.EscapeDataString(kvp.Key), Uri.EscapeDataString(kvp.Value))) 
       .OrderBy(s => s) 
     ); 

     var fullSigData = string.Format(
      "{0}&{1}&{2}", 
      "POST", 
      Uri.EscapeDataString(url), 
      Uri.EscapeDataString(sigString.ToString()) 
     ); 

     return Convert.ToBase64String(sigHasher.ComputeHash(new ASCIIEncoding().GetBytes(fullSigData.ToString()))); 
    } 

    string GenerateOAuthHeader(Dictionary<string, string> data) 
    { 
     return "OAuth " + string.Join(
      ", ", 
      data 
       .Where(kvp => kvp.Key.StartsWith("oauth_")) 
       .Select(kvp => string.Format("{0}=\"{1}\"", Uri.EscapeDataString(kvp.Key), Uri.EscapeDataString(kvp.Value))) 
       .OrderBy(s => s) 
     ); 
    } 

    async Task<string> SendRequest(string fullUrl, string oAuthHeader, StringContent jsondata) 
    { 
     using (var http = new HttpClient()) 
     { 
      http.DefaultRequestHeaders.Add("Authorization", oAuthHeader); 
      var httpResp = await http.PostAsync(fullUrl, jsondata); 
      var respBody = await httpResp.Content.ReadAsStringAsync(); 
      return respBody; 
     } 
    } 
} 
// Classes for creating JSON body 
public class JSONObject 
{ 
    public TwitterEvent @event; 
} 
    public class TwitterEvent 
{ 
    public string type; 
    public msg_create message_create; 
    } 
public class msg_create 
{ 
    public tgt target; 
    public msg_data message_data; 
} 
public class tgt 
{ 
    public string recipient_id; 
} 
public class msg_data 
{ 
    public string text; 
} 
} 

Pour appeler:

var twitter = new TweetDM(consumerKey, consumerKeySecret, accessToken, accessTokenSecret); 
await twitter.Tweet(textBox1.Text, textBox2.Text);