Twitter OAuth 'request_token' response issues with ofxHTTP for 0.9.0

Hi =)

I am trying to get the request token from Twitter but what ever I do I only get an exception: “Connection reset by peer” (Code 54).

I followed @bakercp’s instructions quite accurately I guess:

To request the OAuth request token from a server, using only the consumer (client) key
and consumer (client) secret:

  1. Create an OAuth10Credentials object using the two consumer credentials, either using the two argument constructor, or by using the default constructor and setting the credentials using the setter methods.
  2. Specify the callback URI using setCallback().
  3. Create a URI containing the full request URI to obtain the token.
  4. Create an appropriate HTTPRequest object.
  5. Sign the request by calling authenticate(). This will add an OAuth Authorization header to the request.
  6. Send the request using a HTTPClientSession.
  7. The response will contain the request token and request token secret. These can be extracted from the response body using a HTMLForm object.

Here is my code:

void ofApp::setup(){
	ofSetFrameRate(30);
	ofSetLogLevel(OF_LOG_VERBOSE);
	
	string consumerKey = "********";
	string consumerSecret = "********";
	
	ofx::HTTP::OAuth10Credentials oauth(consumerKey, consumerSecret);
	
	oauth.setCallback("http://website.com/callback.html");
	
	Poco::URI uri("https://api.twitter.com/oauth/request_token");
	std::string path(uri.getPathAndQuery());
	if (path.empty()) path = "/";
	
	
	Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, path, Poco::Net::HTTPMessage::HTTP_1_1);
	
	request.set("User-Agent", "My App Name");
	request.setHost(uri.getHost(), uri.getPort());
	request.set("Accept", "*/*");
	request.setContentType("application/x-www-form-urlencoded");
	
	oauth.authenticate(request, uri);
	
	
	Poco::Net::HTTPClientSession session(uri.getHost(), uri.getPort());
	
	
	try {
		session.sendRequest(request);
		
		Poco::Net::HTTPResponse response;
		std::istream& is = session.receiveResponse(response);
		
		std::cout << response.getStatus() << " " << response.getReason() << std::endl;
		
		
		Poco::Net::HTMLForm form(request, is);
		ofLog(OF_LOG_VERBOSE) << form.getEncoding();
		//ofLog(OF_LOG_VERBOSE) << form["oauth_token"];
		//ofLog(OF_LOG_VERBOSE) << form["oauth_token_secret"];
	}
	catch(const Poco::Exception& exc)
	{
		ofLogError("ofApp::setup") << "Got Exception " << exc.displayText() << " " << exc.code();
	}
	catch(...)
	{
		ofLogError("ofApp::setup") << "Got unknown exception.";
	}
}

session.sendRequest(request) seems to work but session.receiveResponse(response) throws the exception.

Any ideas?

Ok, looks like I fixed it with some inspiration from here: https://github.com/bakercp/ofxHTTP/tree/master/example_basic_client_twitter

void ofApp::setup(){
	ofSetFrameRate(30);
	ofSetLogLevel(OF_LOG_VERBOSE);
	
	string consumerKey = "********";
	string consumerSecret = "********";
	
	ofx::HTTP::OAuth10Credentials oauth(consumerKey, consumerSecret);
	
	oauth.setCallback("http://website.com/callback.html");
	
	
	Poco::URI uri("https://api.twitter.com/oauth/request_token");
	
	
	ofx::HTTP::PostRequest request("https://api.twitter.com/oauth/request_token", Poco::Net::HTTPMessage::HTTP_1_1);
	request.set("User-Agent", "My App Name");
	request.setHost(uri.getHost(), uri.getPort());
	request.set("Accept", "*/*");
	request.setContentType("application/x-www-form-urlencoded");
	request.setContentLength(0);
	
	oauth.authenticate(request, uri);
	
	
	try {
		ofx::HTTP::BaseResponse response;

		std::istream& responseStream = client.execute(request, response, context);
		
		std::cout << response.getStatus() << " " << response.getReason() << std::endl;
		
		std::string buffer;
		
        	Poco::StreamCopier::copyToString(responseStream, buffer);
		
		ofLog(OF_LOG_VERBOSE) << buffer;
		
	}
	catch(const Poco::Exception& exc)
	{
		ofLogError("ofApp::setup") << "Got Exception " << exc.displayText() << " " << exc.code();
	}
	catch(...)
	{
		ofLogError("ofApp::setup") << "Got unknown exception.";
	}
}
2 Likes

Sorry, hoped to respond to this sooner. Likely
Looks like you got it under control now!

thx @bakercp =) I got a PIN authorization working. But I don’t understand the ofxHTTP server events yet. Can’t I just simply catch up the redirect url and extract the parameters from there?

Is there a way to track the server activity?

Hi there, I’m also playing around with the Twitter API and trying to get the timeline of a public user.
after using asdf’s code I have come as far as this:

[verbose] oauth_token=WqRLeetcetcetydfhsghdhg&oauth_token_secret=aG5Gdsdghfdhsrthdligjsodihgksdgj&oauth_callback_confirmed=true

As far as I understand (or dont understand) the next step to get the JSON file would be an authenticated GetRequest to “https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=USER
Am I right? And if yes, how? If not, whats the next step?
Thanks in advance for your help :-/

Hey @schnurbert I’ve got a working Twitter addon. Send me your github username and I’ll add you.

Hi, thanks bakercp for adding me, I’m still trying to get the addon working,
still somehow I’m curious if there is a way to have more Influence on the HTTPRequests and maybe write the HTTP Headers by hand?

since the communication with the Twitter server is explained very well here: https://dev.twitter.com/oauth/application-only , the only thing I can’t get working with ofxHTTP is the Authentication part:
Twitter is demanding something like this:

GET /1.1/statuses/user_timeline.json?count=100&screen_name=twitterapi HTTP/1.1
Host: api.twitter.com
Authorization: Basic eHZ6MWV2RlM0d0VFUFRHRUZQSEJvZzpMOHFxOVBaeVJn
NmllS0dFS2hab2xHQzB2SldMdzhpRUo4OERSZHlPZw==Content-Type: application/x-www-form-urlencoded;charset=UTF-8

and mine looks like this:

GET /1.1/statuses/user_timeline.json?screen_name=USER HTTP/1.1
User-Agent: example_app
Authorization: OAuth oauth_consumer_key=“XcmAAAAAAAAAAAAAAAA7Hw”, oauth_nonce=“j1iJeAAAAAAAAAAAAm0LTBlPc”, oauth_signature=“ImMqAAAAAAAAAAAAAAAAAAAA7o%3D”, oauth_signature_method=“HMAC-SHA1”, oauth_timestamp=“1477312065”, oauth_token=“9oaieuhAAAAAAAAAAAA”, oauth_version=“1.0”

my version returns {"errors":[{"code":89,"message":"Invalid or expired token."}]} :slight_frown:

Okay I have it, in the end its not that complicated:
(Just writing the Authorization part by hand seams to be enough)

Poco::URI uri1("https://api.twitter.com/oauth2/token");

ofx::HTTP::PostRequest accessrequest("https://api.twitter.com/oauth2/token", Poco::Net::HTTPMessage::HTTP_1_1);
        accessrequest.setHost(uri1.getHost(), uri1.getPort());
        accessrequest.set("User-Agent", "example_basic_client_0");
        accessrequest.set("Authorization", "Basic " +authstring);  //build the string on your own base64 encoded
        accessrequest.setContentType("Content-Type: application/x-www-form-urlencoded;charset=UTF-8");  
        accessrequest.addFormField("grant_type","client_credentials");    //HTTPRequest Body
        accessrequest.set("Accept-Encoding", "gzip");

ofx::HTTP::BaseResponse accessresponse;
std::istream& responseStream = client.execute(accessrequest, accessresponse, context);

and after extracting the access token from the response:

Poco::URI  uri2("https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=realdonaldtrump");
   
ofx::HTTP::GetRequest getrequest("https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=realdonaldtrump", Poco::Net::HTTPMessage::HTTP_1_1);
        getrequest.setHost(url2.getHost(), url2.getPort());
        getrequest.set("User-Agent", "example_basic_client_0");
        getrequest.setContentType("application/x-www-form-urlencoded");
               
     std::string accessToken = jsonFromResponse["access_token"].asString();
        
        getrequest.set("Authorization","Bearer "+accessToken);
        getrequest.set("Accept-Encoding", "gzip");

ofx::HTTP::BaseResponse getresponse;
std::istream& responseStream = client.execute(getrequest, getresponse, context);

:smiley:

1 Like

Hey @bakercp, is that Twitter add-on you had up public yet? I’m having these issues myself.

Not public yet … working on getting it out in the next few weeks since a current project depends on it, so it’s getting more attention now!

hi @bakercp ,also i’m searching some twitter add-on can you share me your version?

Hello all, I got it all working pretty reliably now and made the addon public here:

Please check the README for requirements (including the master branch of OF).

It currently has REST search and Streaming implemented, and a lot of other stuff implemented but commented out (including posting to twitter, etc).

CB