Why "https://stream.twitter.com/1.1/statuses/filter.json" isn't working at all in C#?


#1

I’m making an application to get the statuses of certain users
So, I’m using “https://stream.twitter.com/1.1/statuses/filter.json” to get it through the “follow” parameter
here is my code

using System;
using System.IO;
using System.Net;
using System.Security.Cryptography;
using System.Text;

namespace testTwitterOAuth
{
    class Program
    {

        public static void Authenticate()
        {
            // oauth application keys
            var oauth_consumer_key = "******";
            var oauth_consumer_secret = "*******";
            var oauth_token = "*******";
            var oauth_token_secret = "********";

            // 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();

            var valueToFollow = "Ahmed_n1";
            var resource_url = "https://stream.twitter.com/1.1/statuses/filter.json";

            // 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}&follow={6}";
            var baseString = string.Format(baseFormat,
                                                oauth_consumer_key,
                                                oauth_nonce,
                                                oauth_signature_method,
                                                oauth_timestamp,
                                                oauth_token,
                                                oauth_version,
                                                Uri.EscapeDataString(valueToFollow)
                                                );

            baseString = string.Concat("POST&", 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)
            );


            // make the request

            ServicePointManager.Expect100Continue = false;

            var postBody = "follow=" + Uri.EscapeDataString(valueToFollow);
            resource_url += "?" + postBody;
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(resource_url);
            request.Headers.Add("Authorization", authHeader);
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";
            request.PreAuthenticate = true;
            request.AllowWriteStreamBuffering = true;

            try
            {
                WebResponse response = request.GetResponse();
                string responseData = new StreamReader(response.GetResponseStream()).ReadToEnd();
            }
            catch (WebException ex)
            {
                Console.WriteLine(new StreamReader(ex.Response.GetResponseStream()).ReadToEnd());
            }
        }

        static void Main(string[] args)
        {
            Authenticate();
            Console.ReadKey();
        }
    }
}

It always gives me the “Unauthorized 401 exception”

I tried other requests and they are all working perfect
I tested “https://api.twitter.com/1.1/statuses/update.json” to update my status and it worked
I even tested “https://stream.twitter.com/1.1/statuses/filter.json” with the “track” parameter and it worked very fine

Why doesn’t the “Follow” parameter work ?


#2

From a brief look through your code, it looks like your follow parameter is the last in your signature base string:

"oauth_consumer_key={0}&oauth_nonce={1}&oauth_signature_method={2}" + "&oauth_timestamp={3}&oauth_token={4}&oauth_version={5}&follow={6}";

The base string parameters need to be sorted alphabetically, so follow should be first in this string.


#3

Also I believe the follow needs to be the userID and not a string.
"A comma separated list of user IDs, indicating the users to return statuses for in the stream. See the follow parameter documentation for more information."
You can they the user id here: http://www.idfromuser.com/