www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - oauth, Twitter, and std.net.curl

reply "Taylor Gronka" <mr.gronka gmail.com> writes:
Hello,

I've picked up a web design project, and I would love to use 
vibe.d/dlang. I need to use oauth to search on a number of web 
api's, such as searching for Twitter tweets.

I tried using Adam's oauth (Thanks!). However, it doesn't appear 
support the validation needed for searching Twitter.
https://github.com/adamdruppe/arsd/blob/master/oauth.d


Now I'm looking at std.net.curl, and this is my thought: is 
HTTP.addRequestHeader(key, val) able to set the oauth 
authentication headers? It would look a bit odd, but if something 
like this works, then it wouldn't be difficult to code for each 
set of headers specifically:
	
     auto client = HTTP("https://api.twitter.com"); // not sure if 
https should be set here or somewhere else
     string bearerUrl = "https://api.twitter.com/oauth2/token";
     client.addRequestHeader("Authorization", "Basic 
eHZ6MWV2RlM0d0VFUFRHRUZQSEJvZzpMOHFxOVBaeVJnNmllS0dFS2hab2xHQzB2SldMdzhpRUo4OERSZHlPZw");
     client.postData("grant_type=client_credentials");
     client.perform();

(The above example is based on Step 2 of this page)
https://dev.twitter.com/oauth/application-only


Of course, the oauth headers look a bit different, but I imagine 
it being something like this:
     client.addRequestHeader("Authorization", "OAuth2 token: 
\"string\", tokensecret: \"string\", appkey, \"string\" ...");
\\ not sure if that's how to escape quotes in dlang


Can I get some guidance on this? I would really like to use 
dlang, but I can't afford to be stuck on this for too long. I'd 
be happy to try and write a modification of Adam's code, but I 
lack experience, so it's a slow process for me.

I'd also be happy to write up little tutorials/blogposts about 
how I accomplish various tasks.

Thanks,
Jun 15 2015
next sibling parent "Adam D. Ruppe" <destructionator gmail.com> writes:
On Monday, 15 June 2015 at 14:41:32 UTC, Taylor Gronka wrote:
 I tried using Adam's oauth (Thanks!). However, it doesn't 
 appear support the validation needed for searching Twitter.
 https://github.com/adamdruppe/arsd/blob/master/oauth.d
I haven't actually used the twitter search api for like a year now... but looking at the docs, it doesn't look like it has changed much, you should still be able to get to it by modifying the tweet function in my lib. Though, my thing only really supports the user model (I wrote it because we needed to send tweets on behalf of various users) rather than the application authorization. But, application auth is the easier of the two!
     client.addRequestHeader("Authorization", "OAuth2 token: 
 \"string\", tokensecret: \"string\", appkey, \"string\" ...");
 \\ not sure if that's how to escape quotes in dlang
That looks basically right to me, without actually running it, it should do what you need for the search. One thing you could do btw is to get the bearer token manually, then copy/paste it right into your code and use it like a password. Then the code can skip the Authorization: Basic step and only worry about the Bearer part. Give me a sec, I'll write up an example using just the std.net.curl using this strategy.
Jun 15 2015
prev sibling next sibling parent "Adam D. Ruppe" <destructionator gmail.com> writes:
Here's a working example using std.net.curl to search:

http://arsdnet.net/dcode/twitter.d


I show how you can get a token from the command line and code 
that I think will also work from std.net.curl in the top comment.

Once you get that token, paste it in here, pulling it out of the 
json. Then you can run the code below.


It is pretty simple to use the oauth2 things: you just set that 
authorization header:

     client.addRequestHeader("Authorization", "Bearer " ~ 
bearer_token);


And be sure to use https in the url, and the rest is just a basic 
http request and read. OAuth 1, needed to tweet for other users, 
is a lot more complicated and that's where you want to look back 
at the library if you need to do that. (My tweet() function in 
there is the one to use.)
Jun 15 2015
prev sibling parent reply "wobbles" <grogan.colin gmail.com> writes:
On Monday, 15 June 2015 at 14:41:32 UTC, Taylor Gronka wrote:
 Hello,

 I've picked up a web design project, and I would love to use 
 vibe.d/dlang. I need to use oauth to search on a number of web 
 api's, such as searching for Twitter tweets.

 I tried using Adam's oauth (Thanks!). However, it doesn't 
 appear support the validation needed for searching Twitter.
 https://github.com/adamdruppe/arsd/blob/master/oauth.d


 Now I'm looking at std.net.curl, and this is my thought: is 
 HTTP.addRequestHeader(key, val) able to set the oauth 
 authentication headers? It would look a bit odd, but if 
 something like this works, then it wouldn't be difficult to 
 code for each set of headers specifically:
 	
     auto client = HTTP("https://api.twitter.com"); // not sure 
 if https should be set here or somewhere else
     string bearerUrl = "https://api.twitter.com/oauth2/token";
     client.addRequestHeader("Authorization", "Basic 
 eHZ6MWV2RlM0d0VFUFRHRUZQSEJvZzpMOHFxOVBaeVJnNmllS0dFS2hab2xHQzB2SldMdzhpRUo4OERSZHlPZw");
     client.postData("grant_type=client_credentials");
     client.perform();

 (The above example is based on Step 2 of this page)
 https://dev.twitter.com/oauth/application-only


 Of course, the oauth headers look a bit different, but I 
 imagine it being something like this:
     client.addRequestHeader("Authorization", "OAuth2 token: 
 \"string\", tokensecret: \"string\", appkey, \"string\" ...");
 \\ not sure if that's how to escape quotes in dlang


 Can I get some guidance on this? I would really like to use 
 dlang, but I can't afford to be stuck on this for too long. I'd 
 be happy to try and write a modification of Adam's code, but I 
 lack experience, so it's a slow process for me.

 I'd also be happy to write up little tutorials/blogposts about 
 how I accomplish various tasks.

 Thanks,
You can use vibe.d to send requests rather than going the lowlevel curl library. Check out the requestHTTP method [1] From code I've written in the past, your setup looks correct. This is some vibe.d code I've used to get a refresh token from Youtube (I know it's different from twitter, but the idea is the same) YoutubeToken is a local struct that contains the access_token we need to perform searches/post videos etc in any subsequent requests. /** * Returns a new YoutubeToken */ public YoutubeToken getRefreshToken(){ string url = "https://accounts.google.com/o/oauth2/token"; string postBody = "client_id=$CLIENT_ID$&client_secret=$CLIENT_SECRET$&refresh_token=$REFRESH_TOKEN$&grant_type=$GRANT_TYPE$" .replaceMap( [ "$CLIENT_ID$" : credentials.clientID, "$CLIENT_SECRET$" : credentials.clientSecret, "$REFRESH_TOKEN$" : credentials.refreshToken, "$GRANT_TYPE$" : "refresh_token" ] ); logInfo("Getting new refresh token with URL: %s and postBody: %s", url, postBody); auto response = requestHTTP(url, (scope req){ req.method = HTTPMethod.POST; req.contentType = "application/x-www-form-urlencoded"; req.writeBody(cast(ubyte[])postBody); }).bodyReader.readAllUTF8().parseJsonString; return YoutubeToken(response["access_token"].get!string, response["expires_in"].get!long, response["token_type"].get!string ); } [1] http://vibed.org/api/vibe.http.client/requestHTTP
Jun 15 2015
parent reply "Taylor Gronka" <mr.gronka gmail.com> writes:
You two are phenomenal! Thanks!
Jun 15 2015
parent "wobbles" <grogan.colin gmail.com> writes:
On Monday, 15 June 2015 at 15:23:43 UTC, Taylor Gronka wrote:
 You two are phenomenal! Thanks!
Oh, replaceMap is a custom funciton I wrote too... Eases replacing multiple values in a string with 1 function call. I wont pretend that it's fast as it allocates a lot of memory :) public string replaceMap(string str, string[string] keys){ import std.array; foreach(key, val; keys){ str = str.replace(key, val); } return str; }
Jun 15 2015