C# API 1.1 Get method returns


#1

I want to use the following code to get data from the Twitter API. Every time I run it though it returns (401) Unauthorized. It will work if I POST instead of GET. Any help would be greatly appreciated.

void getTwitterData(string URL, string query,string page, string per_page)
    {
        UserAccount sua = (UserAccount)Session["SessionUser"];
        // oauth application keys
        var oauth_token = sua.TWToken; //"insert here...";
        var oauth_token_secret = sua.TWSecret; //"insert here...";
        var oauth_consumer_key = ConfigurationManager.AppSettings["consumerKey3"];// = "insert here...";
        var oauth_consumer_secret = ConfigurationManager.AppSettings["consumerSecret3"];// = "insert here...";

        // oauth implementation details
        var oauth_version = "1.0";
        var oauth_signature_method = "HMAC-SHA1";

        // unique request details
        var oauth_nonce = Convert.ToBase64String(
            new ASCIIEncoding().GetBytes(DateTime.Now.Ticks.ToString()));
        var timeSpan = DateTime.UtcNow
            - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
        var oauth_timestamp = Convert.ToInt64(timeSpan.TotalSeconds).ToString();

        // create oauth signature
        var baseFormat = "oauth_consumer_key={0}&oauth_nonce={1}&oauth_signature_method={2}" +
                        "&oauth_timestamp={3}&oauth_token={4}&oauth_version={5}&q={6}&page={7}&per_page={8}";

        var baseString = string.Format(baseFormat,
                                    oauth_consumer_key,
                                    oauth_nonce,
                                    oauth_signature_method,
                                    oauth_timestamp,
                                    oauth_token,
                                    oauth_version,
                                    Uri.EscapeDataString(query),
                                    Uri.EscapeDataString(page),
                                    Uri.EscapeDataString(per_page)
                                    );

        baseString = string.Concat("GET&", Uri.EscapeDataString(URL), "&", Uri.EscapeDataString(baseString));
        
        var compositeKey = string.Concat(Uri.EscapeDataString(oauth_consumer_secret),
                                "&", Uri.EscapeDataString(oauth_token_secret));

        string oauth_signature;
        using (HMACSHA1 hasher = new HMACSHA1(ASCIIEncoding.ASCII.GetBytes(compositeKey)))
        {
            oauth_signature = Convert.ToBase64String(
                hasher.ComputeHash(ASCIIEncoding.ASCII.GetBytes(baseString)));
        }

        // create the request header
        var headerFormat = "OAuth oauth_nonce=\"{0}\", oauth_signature_method=\"{1}\", " +
                           "oauth_timestamp=\"{2}\", oauth_consumer_key=\"{3}\", " +
                           "oauth_token=\"{4}\", oauth_signature=\"{5}\", " +
                           "oauth_version=\"{6}\"";

        var authHeader = string.Format(headerFormat,
                                Uri.EscapeDataString(oauth_nonce),
                                Uri.EscapeDataString(oauth_signature_method),
                                Uri.EscapeDataString(oauth_timestamp),
                                Uri.EscapeDataString(oauth_consumer_key),
                                Uri.EscapeDataString(oauth_token),
                                Uri.EscapeDataString(oauth_signature),
                                Uri.EscapeDataString(oauth_version)
                        );


        myDiv.InnerHtml = baseString + "<br/><br/><br/>" + authHeader;
        //return;
        ServicePointManager.Expect100Continue = false;

        // make the request
        URL = URL + "?q=" + Uri.EscapeDataString(query) + "&page=" + Uri.EscapeDataString(page)+"&per_page=" + Uri.EscapeDataString(per_page);//

        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
        request.Headers.Add("Authorization", authHeader);
        request.Method = "GET";
        request.ContentType = "application/x-www-form-urlencoded";

        WebResponse response = request.GetResponse();
        var reader = new StreamReader(response.GetResponseStream());
        var objText = reader.ReadToEnd();
        myDiv.InnerHtml = objText;
    }

#2

Any one know what I am doing wrong?


#3

I figured it out I took out the page and per_page on the query string and it works now just in case someone needs the same code here it is I used:

string query = "Britney " + “Johnson”;
string url = “https://api.twitter.com/1.1/users/search.json”;
findUserTwitter(url, query);

To call the twitter api 1.1

void findUserTwitter(string resource_url, string q)
{
UserAccount sua = (UserAccount)Session[“SessionUser”];
// oauth application keys
var oauth_token = sua.TWToken; //“insert here…”;
var oauth_token_secret = sua.TWSecret; //“insert here…”;
var oauth_consumer_key = ConfigurationManager.AppSettings[“consumerKey3”];// = “insert here…”;
var oauth_consumer_secret = ConfigurationManager.AppSettings[“consumerSecret3”];// = “insert here…”;

    // oauth implementation details
    var oauth_version = "1.0";
    var oauth_signature_method = "HMAC-SHA1";

    // unique request details
    var oauth_nonce = Convert.ToBase64String(
        new ASCIIEncoding().GetBytes(DateTime.Now.Ticks.ToString()));
    var timeSpan = DateTime.UtcNow
        - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
    var oauth_timestamp = Convert.ToInt64(timeSpan.TotalSeconds).ToString();


    // create oauth signature
    var baseFormat = "oauth_consumer_key={0}&oauth_nonce={1}&oauth_signature_method={2}" +
                    "&oauth_timestamp={3}&oauth_token={4}&oauth_version={5}&q={6}";

    var baseString = string.Format(baseFormat,
                                oauth_consumer_key,
                                oauth_nonce,
                                oauth_signature_method,
                                oauth_timestamp,
                                oauth_token,
                                oauth_version,
                                Uri.EscapeDataString(q)
                                );

    baseString = string.Concat("GET&", Uri.EscapeDataString(resource_url), "&", Uri.EscapeDataString(baseString));

    var compositeKey = string.Concat(Uri.EscapeDataString(oauth_consumer_secret),
                            "&", Uri.EscapeDataString(oauth_token_secret));

    string oauth_signature;
    using (HMACSHA1 hasher = new HMACSHA1(ASCIIEncoding.ASCII.GetBytes(compositeKey)))
    {
        oauth_signature = Convert.ToBase64String(
            hasher.ComputeHash(ASCIIEncoding.ASCII.GetBytes(baseString)));
    }

    // create the request header
    var headerFormat = "OAuth oauth_nonce=\"{0}\", oauth_signature_method=\"{1}\", " +
                       "oauth_timestamp=\"{2}\", oauth_consumer_key=\"{3}\", " +
                       "oauth_token=\"{4}\", oauth_signature=\"{5}\", " +
                       "oauth_version=\"{6}\"";

    var authHeader = string.Format(headerFormat,
                            Uri.EscapeDataString(oauth_nonce),
                            Uri.EscapeDataString(oauth_signature_method),
                            Uri.EscapeDataString(oauth_timestamp),
                            Uri.EscapeDataString(oauth_consumer_key),
                            Uri.EscapeDataString(oauth_token),
                            Uri.EscapeDataString(oauth_signature),
                            Uri.EscapeDataString(oauth_version)
                    );



    ServicePointManager.Expect100Continue = false;

    // make the request
    var postBody = "q=" + Uri.EscapeDataString(q);//
    resource_url += "?"+postBody;
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(resource_url);
    request.Headers.Add("Authorization", authHeader);
    request.Method = "GET";
    request.ContentType = "application/x-www-form-urlencoded";
    var response = (HttpWebResponse)request.GetResponse();
    var reader = new StreamReader(response.GetResponseStream());
    var objText = reader.ReadToEnd();
    myDiv.InnerHtml = objText;/**/
    string html="";
    try
    {
        JArray jsonDat = JArray.Parse(objText);
        for (int x = 0; x < jsonDat.Count(); x++)
        {
            html += jsonDat[x]["id"].ToString() + "<br/>";

        }
        myDiv.InnerHtml = html;
    }
    catch (Exception twit_error)
    {
        myDiv.InnerHtml = html + twit_error.ToString();
    }
}
I have a div on the frount page.
This div displays all the ids of the users I am searching for on twitter.

#4

hi am sorry i dont have any solution for you but i need your help , because i think that you can help in my project so if you please give me your email , and this is my email
ahmadkamal1991_psut@hotmail.com am studying CS and i also working on my graduation project :smiley:


#5

Thanks for posting this code! It worked for me, so I will meet the March 5th Twitter 1.1 API deadline. Yeah!
Make sure you change “&q=” on lines 24 & 69 of the corrected code if you are doing something other than a search for user id’s.


#6

Thanks a lot for the code. The code is working with me. But Can I ask how can I manage it to work if I’m using a long or int value like “&id=” in the request “https://api.twitter.com/1.1/statuses/show.json?id=210462857140252672”?. I keep getting ‘401 Unauthorized’. If I use a string like looking for username or anything similar, it works perfectly but with id it does not work with me and I think I’m missing something. Can you help me with that?


#7

on line 24 and 69 are you changing “q=” to “id=“
If not go to the oauth tool and see how they make there base string
for example I was working on doing a search on twitter and was trying to add a count but I was getting 401 until I put count at the beginning.
my base string

count=100&oauth_consumer_key={0}&oauth_nonce={1}
&oauth_signature_method={2}” +
”&oauth_timestamp={3}&oauth_token={4}
&oauth_version={5}&q={6}&result_type=mixed

twitter base string

GET&https%3A%2F%2Fapi.twitter.com%2F1.1%2Fsearch%2Ftweets.json
&count%3D100
…oauth tokens…
%26q%3Dobama%26result_type%3Dmixed%26until%3D2013-03-02

You have to put everything in the right order or it will send back 401.
I hope that helps. :slight_smile:


#8

Wow, that finally worked with me :slight_smile: I changed the base string as you said and put the id at first. Thanks a lot for your help, don’t know how to thank you enough for that. Thank you so much :slight_smile:


#9

Hi Britney
thanks for posting this code, it has helped me out a lot. one question though, line 77, reader.ReadToEnd(), how long will this reader stay open for? will it stay open for the length of time specified in oauth_timestamp or for the length of time it take to return information for your query string?
using your query string i wouldn’t expect it to take to long to pull back all the information for your name. however, I am finding for line 77 my application just hangs.


#10

What information are you trying to pull? can you give me an example so I can try it.


#11

Hi Britney, i just realised i am trying to use the twitter userstream api not the search api which you are using.
i was able to get the search api working with the example you have but not the userstream api. Would you have any experience using this userstream api? i have followed you example code everything look good, but just having that problem i mentioned

David


#12

try this

string objText = “c”;
string objText2 = “”;
while (objText!="")//;//.Read();//.ReadToEnd();
{
objText = “”;
try
{
objText = reader.ReadLine();
objText2 += " " + objText2;
html += objText + “
”;
myDiv.InnerHtml = html;/**/
//string html = “”;
}
catch (Exception er)
{
myDiv.InnerHtml = html + “er:” + er.ToString() + “
”;
}

    }
    try
    {
        JArray jsonDat = JArray.Parse(objText2);
        for (int x = 0; x < jsonDat.Count(); x++)
        {
            html += jsonDat[x]["id"].ToString() + "<br/>";
        }
        myDiv.InnerHtml = html;
    }
    catch (Exception twit_error)
    {
        myDiv.InnerHtml = html + twit_error.ToString() + "<br/>";
    }

#13

Curious. I see you created the basestring, but it’s never used when you make the actual call to Twitter.

What’s the point of creating the basestring?


#14

You use the base string to create the oauth_signature. Then the oauth_signature is used in the authHeader. Which is used to authorize your call to twitter. :slight_smile:


#15

Thanks. I saw that after I had asked :). Unfortunately this doesn’t work for me. The signature created using this method is always different than the signature I see on the “oAuth Tool” even when I use the same nonce and timestamp from the oAuth Tool.

I always get a 401 Unauthorized.


#16

please can anyone help me in how to finding the remaining rate limit???


#17

thanx great help you can add the count
String baseFormat = “count=25&oauth_consumer_key={0}&oauth_nonce={1}&oauth_signature_method={2}” +
"&oauth_timestamp={3}&oauth_token={4}&oauth_version={5}&q={6}";

resource_url += “?” +postBody +"&count=25" ;


#18

Thanks LeathalChicken for posting this Code… …


#19

Wow… thanks so much… was trying to use other libraries, however this is the most straight forward approach given the twitter API is just REST… however +1 for the comments above about the “correct order” of the header! really gave me some hassles initially as I wanted to get a users timeline via https://api.twitter.com/1.1/statuses/user_timeline.json and had to add the user name/screen name and count.


#20

I also get 401 unauthorised. Can you share how you got around it?