Monday, November 26, 2012

[C#] Using the Reddit API in .NET - Vote on a link

To get the most out of this tutorial, it's useful to have read the previous post in this series.


Today we are using the information we got from the Reddit server to vote on a thread. We can upvote, remove our vote, or downvote the thread. All through simple C# code, thanks to Reddits simple API.

Here is some code to get you started:


Take a look at the API description here:


In the previous post, we extracted two parameters: modhash and cookie. These are the proof that we are a legit user. 
To vote, we require four things: the modhash (uh), the vote (dir), the id of the thread (id) and the cookie.
And as detailed in the above link, we need to format our id in a certain way.

Look at this reddit thread link: http://www.reddit.com/r/csharp/comments/13rei1/i_made_a_short_tutorial_of_how_to_interact_with/

The "13rei1" substring is the id, but we need to append "t3_" at the beginning to make it accepted by Reddit.
If you are not a god at Regex (which I am not) we can extract it in the following manner, as all Reddit links looks essentially the same:

String LinkURL = "http://www.reddit.com/r/csharp/comments/13rei1/i_made_a_short_tutorial_of_how_to_interact_with/"
String linkID;

String[] split = linkURL.Split('/');
if (split[0] == "http:")
     linkID = split[6]; 

Now we can POST, as we did last time, but with different data. Post 1 for upvote, 0 for removal, and -1 for downvote. Use the modhash we extracted before to idenfity ourselves. The modhash is sufficient, and we do not need our account-name or password again

Int direction = 1;

NameValueCollection userdata = new NameValueCollection();
userdata.Add("id", linkID);
userdata.Add("dir", direction.ToString());
userdata.Add("uh", modhash);

Make a web client again.

System.Net.ServicePointManager.Expect100Continue = false; //some servers choke without 
var wc = new WebClient();

Now Reddit wants the cookie to further security reasons, and they call it "reddit_session". The cookie we have is an authentication cookie and has a date-parameter, to identify if our session should be timed out due to inactivity, among other things. We add it simply like this, and POST it.

wc.Headers.Add(HttpRequestHeader.Cookie, "reddit_session=" + cookie);
byte[] byteJsonResponse = wc.UploadValues("http://www.reddit.com/api/vote",
                "POST",
                userdata);
wc.Dispose();

Then we transform the response to a useful String, as before.
String stringJsonResponse = System.Text.Encoding.UTF8.GetString(byteJsonResponse);

If everything went well, you will receive a very small string of "{}" in the response stringJsonResponse variable.

Congratulations. You can now log in and upvote to Reddit, all in beautiful C#.

--------

Edit:

After some suggestions, it is better to use the webclient in this manner:

using (var wc = new WebClient())
{
wc.Headers.Add(HttpRequestHeader.Cookie, "reddit_session=" + cookie);
byte[] byteJsonResponse = wc.UploadValues("http://www.reddit.com/api/vote",
                "POST",
                userdata);
}

This way, you do not need to call the Dispose() method afterwards. It gets cleaned up automatically. So much cleaner code with less probability of error.

And instead of the WebClient, some people use the restsharp library. http://restsharp.org/ It's more of a black box though.





1 comment: