I have a bot running happily under v1 API and thought I’d write a new one but it seems the v1 endpoint for posting a tweet no longer works by default, you need elevated access.

I thought I’d just use v2 instead, namely POST /2/tweets but none of the existing C# libraries have implemented this aspect of v2! They’ve mostly implemented the read-only endpoints, and after two days of swearing I think I can imagine why!

First question, does anyone know of any C# libraries that have implemented v2 posting of tweets? That would be ideal.

Second, trying to do this myself, it seems Twitter docs are a bit split on this:
developer . twitter . com/en/docs/twitter-api/tweets/manage-tweets/api-reference/post-tweets#cURL

Says to use: “Authorization: Bearer $ACCESS_TOKEN”

However, when I do that I get the message “Authenticating with OAuth 2.0 Application-Only is forbidden for this endpoint. Supported authentication types are [OAuth 1.0a User Context, OAuth 2.0 User Context]”

The API tool here: developer . twitter . com/apitools/api?endpoint=%2F2%2Ftweets&method=post

Says to use: “Authorization: OAuth $OAUTH_SIGNATURE”

And this is where I’m at - I can’t seem to generate a signature that works here - I just get ‘Unauthorized’

I assumed I’d be able to use Twitter’s auth URL to generate this: api . twitter . com/oauth/authenticate?oauth_token=xxxxx

But this gives me: “The request token for this page is invalid”. I took the auth_token from the app dashboard’s ‘Access Token and Secret’ section.

is this right? Or do I need to get the oauth_token from somewhere else?

I utterly hate oAuth so any step-by-step idiot’s guide to generating this and then an example curl (with dummy values) to POST to the POST /2/tweets would be amazing - I simply don’t know what exactly that $OAUTH_SIGNATURE is supposed to look like.

And I’ve applied for elevated access anyway, see if they give it to me!

Thanks.

You’ll need to do all of these steps to generate the signature (whether you’re using v2 or v1, doesn’t matter) - https://developer.twitter.com/en/docs/authentication/oauth-1-0a/creating-a-signature

1 Like

Thanks for the reply, but I’ve just spent two days attempting to get this working. I have of course seen this page and a dozen others. Linking to that and saying ‘you need to do this’ isn’t helpful at all, it’s like saying Google it. I came here for help as I obviously have been through all the developer pages and can’t get it working. I asked two questions in my post, you answered neither.

With all due respect, I’m not staff (a lot of people here aren’t), so there is no need to talk like that.

That aside, trying to implement the entire backend of literally any interfacing with an API is going to be a hard time. You said you don’t know what the OAUTH_SIGNATURE is meant to look like - it’s described pretty clearly in the article. It shows you the signature string, to start with, looks like this:

POST&https%3A%2F%2Fapi.twitter.com%2F1.1%2Fstatuses%2Fupdate.json&include_entities%3Dtrue%26oauth_consumer_key%3Dxvz1evFS4wEEPTGEFPHBog%26oauth_nonce%3DkYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1318622958%26oauth_token%3D370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb%26oauth_version%3D1.0%26status%3DHello%2520Ladies%2520%252B%2520Gentlemen%252C%2520a%2520signed%2520OAuth%2520request%2521

From a quick glance it looks like this is what you do:

  1. Get your signature string: the method “POST” or “GET”, the percent encoded URL to the endpoint, and the percent encoded parameter string. Join those three strings together with &.

  2. Get your signing key: your app’s client secret in percent encoding, the user’s access token secret in percent encoding. Join them with an &.

  3. Get the HMAC-SHA1 of the signature and signing key, by using hash_hmac function (there is presumably a standard function in C# for this).

  4. Apply base64 encoding to the resulting string. There is presumably a standard function for this as well.

That’s all you should need to do.

2 Likes

Thanks for this reply, I’ll go away and work through it. Apologies if my frustration with this came across in my reply to you. I do appreciate this.

1 Like

Np, I know the feeling :joy:

Hi again!

So I installed the Postman v2 Twitter API tools, and input the app values and sent a POST to the v2 tweets endpoint, and it worked. So I know the keys are correct at least!

However, when I send the same POST in my code, I get a 401 error ‘Unauthorized’ message. I generate the signature for the request using .NET oAuth library, with the same values as Postman uses.

Postman’s request (OK):
Content-Type: application/json
Authorization: OAuth oauth_consumer_key=“QWERTYUIOP”,oauth_token=“123456789-QWERTYUIOP”,oauth_signature_method=“HMAC-SHA1”,oauth_timestamp=“1646646428”,oauth_nonce=“LKJHGFDSA”,oauth_version=“1.0”,oauth_signature=“ZXCVBNM%3D”
Cookie: guest_id=v1%3A164647635225899999

My request (error 401 ‘Unauthorized’):
Content-Type: application/json
Authorization: OAuth oauth_consumer_key=“QWERTYUIOP”,oauth_nonce=“POIUYTREWQ”,oauth_signature=“ZXCVBNM%3D”,oauth_signature_method=“HMAC-SHA1”,oauth_timestamp=“1646648142”,oauth_token=“123456789-QWERTYUIOP”,oauth_version=“1.0”

I don’t get it. Is the cookie important that Postman sends? Or am I doing something wrong?

I’m uncertain about the body. Does Postman somehow include the JSON payload in the signature? It’s not clear :frowning: if so, how is that done I wonder?

I wouldn’t imagine the cookie parameter is relevant here… I can’t see anything particularly obvious wrong. Can you show us the code that you are using to generate the oauth_signature?

Thanks, yeah I assume the signature is incorrect for some reason :frowning:

The oAuth library is this, and now I look it’s pretty old! I wonder if that’s the problem? GitHub - rhargreaves/oauth-dotnetcore: An implementation of OAuth 1.0a for .NET Core based on Daniel Crenna's vaulted OAuth library

I’m still not sure about the JSON body, it’s kind of outside the calculated signature, but I read that’s how you do JSON body contents?

Thanks for help!

                // Create a new connection to the OAuth server, with a helper method
                OAuthRequest client = OAuthRequest.ForProtectedResource("GET", CONSUMER_KEY, CONSUMER_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET);
                client.RequestUrl = "https://api.twitter.com/2/tweets";
                string auth = client.GetAuthorizationHeader();
                
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(client.RequestUrl);
                request.Method = "POST";
                request.Headers.Add("Content-Type", "application/json");
                request.Headers.Add("Authorization", auth);
                using (var streamWriter = new StreamWriter(request.GetRequestStream()))
                {
                    streamWriter.Write("{\"text\":\"Hello World\"");
                }
                var response = (HttpWebResponse)request.GetResponse();
                var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
1 Like

Well, one thing I can see is that your client doesn’t look like it’s set up correctly - shouldn’t the client line have POST instead of GET in it? Went looking through that .NET library, the method use looks correct.

It may be affecting how the client generates its request, even with the request method set to POST for the request object… it’s also possible that the JSON isn’t being given to the endpoint the right way, this library sure has a weird way of adding parameters to a web request.

1 Like

OH MY

IT WORKS. I altered the client line to POST and it just worked. I had assumed that that was GET no matter what!

I also switched out to use RestSharp which handles params and the JSON better!

Thanks so much for your help, and once again, apologies for the initial negative reply!

2 Likes

Haha, np. Glad it works :smiley:

Banging my head for 2 days already with the same problem - I can’t post a tweet from c# code.

Ralph, I took your code from above and got Forbidden response.
Same forbidden response getting from Postman.

Something is missing here, but I can’t figure out what exactly.

Any ideas, why I’m getting forbidden?

Did you alter the GET here to POST?

If you open a new thread rather than using this one, then I’ll see if I can help out? Post your code there with your returned auth string from the oAclient.GetAuthorizationHeader() ?

For me it was all about the auth string!

1 Like

Ralph,

Here is the new topic: Using POST /2/tweets in C# - not working
Git source code: Bobetti/TwitterApi
Your code → TwitterAPI_5 class
Signature is:

OAuth oauth_consumer_key="...",oauth_nonce="a7lx2x7rn6e9f1oa",oauth_signature="...",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1647429861",oauth_token="...",oauth_version="1.0"