Twitter新的DM API,传统的授权方法不起作用
我们正试图从Salesforce实施Twitter新的DM API。如文档中所述,我们正在发送我们的JSON请求,但Oauth授权的传统方法不起作用。任何帮助是极大的赞赏。Twitter新的DM API,传统的授权方法不起作用
要添加,我发送一个DM从销售队伍到Twitter,所以 1)我设置JSON的请求正文。 2)我正在做一个POST。 3)我在'https://api.twitter.com/1.1/direct_messages/events/new.json' 4)Oauth2,获取访问令牌(成功) 5)将头部设置为('Content-Type','application/json')。 6)使用使用者密钥,Nonce,签名,签名方法,时间戳,版本,Twitter创建授权标头。建立与developer.twitter.com/en/docs/basics/authentication/guides/ 的“指南”部分相同的内容7)运行错误代码“{”errors“:[{”code“:32,”message “:“无法验证您的身份。”}]}”。
另一个重要的信息,我一直在使用Twitter旧API发送完美的DM,唯一的区别是它发送请求体的URL参数而不是JSOn正文,但授权方法保持不变。由于一些新功能只能通过Twitter New API实现,并且根据文档需要通过JSON格式发送主体。因此请求部分被更改,但授权相同。
示例代码: -
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);
感谢 Prateek
我写Twitter的库和应用程序在过去,和BST意见,我可以给你是使用现有的实现OAuth而不是尝试写你自己的。在新代码中重新实现OAuth正在重新发明*,这是一个令你厌恶的*。有许多强大且成熟的OAuth库是免费和/或开源的。
感谢DWRoelands的信息,我们尝试过,但无法找到任何支持DM的新Twitter API的库。请让我们知道你是否有任何特别的想法。任何帮助是极大的赞赏。 –
只是发生了绊倒你的查询。我发布了一个代码(c#)(虽然有点晚),这对我来说使用新API将DM发送到twitter是很有用的。希望这可以帮助。由于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;
}
}
要拨打:
var twitter = new TweetDM(consumerKey, consumerKeySecret, accessToken, accessTokenSecret);
await twitter.Tweet(textBox1.Text, textBox2.Text);
你能发布您的代码通过编辑这个问题? –
嗨迪玛,谢谢你的回复。 –
你应该考虑添加关于你的问题的信息,比如什么不工作。另外,您应该考虑添加有关该项目的信息,例如您使用的是哪种技术。代码示例也真的很感激在这种情况下 – Nicolas