Невозможно пройти аутентификацию в Twitter APIC#

Место общения программистов C#
Ответить
Anonymous
 Невозможно пройти аутентификацию в Twitter API

Сообщение Anonymous »

Я пытаюсь написать невероятно простое консольное приложение на C#, которое просто опубликует один твит в моем Твиттере от моего имени.
У меня есть учетная запись разработчика, и я прочитал ссылку, включая части, которые не имеют смысла и те, которые противоречат сами себе, я просмотрел старые вопросы и форумы в Твиттере, и что бы я ни пытался, я никогда не смогу пройти аутентификацию.
Моя цель - НЕ перенаправляться в веб-браузер для входа в мою учетную запись вручную, а использовать ключи и секреты учетной записи разработчика для аутентификации.
Я пробовал все следующее:

Код: Выделить всё

static async Task Main()
{
var consumerKey = "";
var consumerSecret = "";
var accessToken = "";
var accessTokenSecret = "";

var tweetText = "test";

var oauthNonce = Convert.ToBase64String(Encoding.ASCII.GetBytes(DateTime.Now.Ticks.ToString()));
var oauthTimestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString();

var url = "https://api.twitter.com/1.1/statuses/update.json";

var parameters =
"oauth_consumer_key=" + consumerKey +
"&oauth_nonce=" + oauthNonce +
"&oauth_signature_method=HMAC-SHA1" +
"&oauth_timestamp=" + oauthTimestamp +
"&oauth_token=" + accessToken +
"&oauth_version=1.0" +
"&status=" + UrlEncode(tweetText);

var signatureBaseString = "POST&" + UrlEncode(url) + "&" + UrlEncode(parameters);
var signingKey = UrlEncode(consumerSecret) + "&" + UrlEncode(accessTokenSecret);

string oauthSignature;
using (var hasher = new HMACSHA1(Encoding.ASCII.GetBytes(signingKey)))
{
oauthSignature = Convert.ToBase64String(hasher.ComputeHash(Encoding.ASCII.GetBytes(signatureBaseString)));
}

var authHeader =
"OAuth " +
"oauth_consumer_key=\"" + consumerKey + "\"," +
"oauth_nonce=\"" + oauthNonce + "\"," +
"oauth_signature=\"" + UrlEncode(oauthSignature) + "\"," +
"oauth_signature_method=\"HMAC-SHA1\"," +
"oauth_timestamp=\"" + oauthTimestamp + "\"," +
"oauth_token=\"" + accessToken + "\"," +
"oauth_version=\"1.0\"";

using var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", authHeader);

var content = new FormUrlEncodedContent([new KeyValuePair("status", tweetText)]);

var response = await client.PostAsync(url, content);
var result = await response.Content.ReadAsStringAsync();

Console.WriteLine(result);
}

static string UrlEncode(string value) =>
HttpUtility.UrlEncode(value)
.Replace("+", "%20")
.Replace("*", "%2A")
.Replace("%7E", "~");
.

Код: Выделить всё

const string API_KEY = "";
const string API_SECRET = "";
const string CONSUMER_KEY = "";
const string CONSUMER_SECRET = "";
const string ACCESS_TOKEN = "";
const string ACCESS_TOKEN_SECRET = "";

public static async Task ReplyToTweet(string replyText)
{
if (string.IsNullOrWhiteSpace(replyText))
{
return "Reply text cannot be empty.";
}

var ConsumerKey = CONSUMER_KEY; // also tried with API_KEY
var ConsumerSecret = CONSUMER_SECRET;  // also tried with API_SECRET
var Token = ACCESS_TOKEN;
var TokenSecret = ACCESS_TOKEN_SECRET;

var oAuth1 = OAuth1Authenticator.ForAccessToken(
consumerKey: ConsumerKey,
consumerSecret: ConsumerSecret,
token: Token,
tokenSecret: TokenSecret,
OAuthSignatureMethod.HmacSha256);

var options = new RestClientOptions("https://api.x.com")
{
Authenticator = oAuth1
};

var client = new RestClient(options);
var request = new RestRequest("2/tweets", Method.Post);
request.AddHeader("Content-Type", "application/json");

// Creating the body
var bodyObject = new
{
text = replyText
};

string body = JsonSerializer.Serialize(bodyObject);
request.AddParameter("application/json", body, ParameterType.RequestBody);

var response = await client.ExecuteAsync(request);

if (response.IsSuccessful)
{
var responseData = JsonSerializer.Deserialize(response.Content);
return $"tweet created successfully! Tweet ID: {responseData.data.id}";
}
else
{
return $"Failed to create reply tweet.  Error: {response.ErrorMessage}\nResponse: {response.Content}";
}
}
.

Код: Выделить всё

class Program
{
static void Main(string[] args)
{

Console.WriteLine("Enter the Tweet ID: ");
string tweetID = Console.ReadLine(); // no error checking here!

// convenient to load keys and tokens from a config file for testing
// edit .env.sample (and rename to .env) to add your keys and tokens (no quotation marks)
DotNetEnv.Env.Load();

string CONSUMER_KEY = "";
string CONSUMER_TOKEN = "";
string ACCESS_TOKEN = "";
string ACCESS_TOKEN_SECRET = "";

// this is the endpoint we will be calling
StringBuilder apiPath = new StringBuilder("https://api.twitter.com");
apiPath.Append("/2/tweets");
apiPath.AppendFormat("?ids={0}", tweetID);
apiPath.Append("&tweet.fields=attachments,author_id,context_annotations,created_at,entities,geo,id,in_reply_to_user_id,lang,possibly_sensitive,public_metrics,referenced_tweets,source,text,withheld");
apiPath.Append("&media.fields=duration_ms,height,media_key,preview_image_url,type,url,width");
apiPath.Append("&expansions=attachments.poll_ids,attachments.media_keys,author_id,geo.place_id,in_reply_to_user_id,referenced_tweets.id");
apiPath.Append("&poll.fields=duration_minutes,end_datetime,id,options,voting_status");
apiPath.Append("&place.fields=contained_within,country,country_code,full_name,geo,id,name,place_type");
apiPath.Append("&user.fields=created_at,description,entities,id,location,name,pinned_tweet_id,profile_image_url,protected,public_metrics,url,username,verified,withheld");
string REQUEST_URL = apiPath.ToString();

// if you would like to compare to v1.1 then this alternative REQUEST_URL does that for Tweet ID 20
// string REQUEST_URL = "https://api.twitter.com/labs/2/tweets/20?tweet.fields=author_id,created_at,entities,source,public_metrics,lang,geo&expansions=author_id&user.fields=created_at,description,entities,id,location,name,pinned_tweet_id,profile_image_url,protected,url,username,verified,public_metrics";

// Create a new connection to the OAuth server, with a helper method
OAuthRequest client = OAuthRequest.ForProtectedResource("GET", CONSUMER_KEY, CONSUMER_TOKEN, ACCESS_TOKEN, ACCESS_TOKEN_SECRET);
client.RequestUrl = REQUEST_URL;

// add HTTP header authorization
string auth = client.GetAuthorizationHeader();
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(client.RequestUrl);
request.Headers.Add("Authorization", auth);

Console.WriteLine("\nCalling " + REQUEST_URL + "\n");

// make the call and print the string value of the response JSON
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
string strResponse = reader.ReadToEnd();

Console.WriteLine(strResponse); // we have a string (JSON)
}
}
.

Код: Выделить всё

// Source - https://stackoverflow.com/a/79676911
// Posted by Himanshu Kumar Sinha
// Retrieved 2025-12-01, License - CC BY-SA 4.0

public async Task  ReplyToTweet(string replyText)
{
if (string.IsNullOrWhiteSpace(replyText))
{
return "Reply text cannot be empty.";
}

var ConsumerKey = "";
var ConsumerSecret = "";
var Token = "";
var TokenSecret = "";

var oAuth1 = OAuth1Authenticator.ForAccessToken(
consumerKey: ConsumerKey,
consumerSecret: ConsumerSecret,
token: Token,
tokenSecret: TokenSecret,
OAuthSignatureMethod.HmacSha256);

var options = new RestClientOptions("https://api.x.com")
{
Authenticator = oAuth1
};

var client = new RestClient(options);
var request = new RestRequest("2/tweets", Method.Post);
request.AddHeader("Content-Type", "application/json");

// Creating the body
var bodyObject = new
{
text = replyText
};

string body = JsonConvert.SerializeObject(bodyObject);
request.AddParameter("application/json", body, ParameterType.RequestBody);

var response = await client.ExecuteAsync(request);

if (response.IsSuccessful)
{
var responseData = JsonConvert.DeserializeObject(response.Content);
return $"tweet created successfully! Tweet ID: {responseData.data.id}";
}
else
{
return $"Failed to create reply tweet. Error: {response.ErrorMessage}\nResponse: {response.Content}";
}
}
Ничто из этого не работает. Я всегда получаю сообщение «Не авторизовано»/«Не удалось пройти аутентификацию».
Я на пределе возможностей и буду признателен за любую помощь в том, как просто опубликовать простой твит в моем твиттере, используя мою учетную запись, используя любые ключи и секреты, к которым у меня есть доступ в моей учетной записи разработчика без аутентификации в браузере.

Подробнее здесь: https://stackoverflow.com/questions/798 ... witter-api
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»