So far as I can tell, I'm following the instructions accurately
according to http://dev.twitter.com/pages/auth, but regardless of any
minute variations, I keep getting a 401, authorization error on
posting (i.e. the method pushMessage() fails). So far as I can tell,
I'm not doing anything different, other than using POST, than I did
during the initial authorization.

public class Twitter {
        private string tokenSecret = "";

        private string createTimestamp() {
                var now = DateTime.UtcNow;
                var then = new DateTime(1970, 1, 1);
                var timespan = now - then;
                return ("" + (long)timespan.TotalSeconds);
        }

        private string createNonce() {
                const string ALPHANUMERIC =
                          "qwertyuiopasdfghjklzxcvbnm"
                        + "QWERTYUIOPASDFGHJKLZXCVBNM"
                        + "1234567890"
                ;

                var sb = new StringBuilder();
                var random = new Random();
                for (int L = 0; L < 42; L++)
                {
                        sb.Append(
                                ALPHANUMERIC[random.Next(ALPHANUMERIC.Length)]
                        );
                }
                return sb.ToString();
        }

        private string createSignature(string signatureBase) {
                string key = clientSecret + "&" + tokenSecret;
                var keyBytes = Encoding.UTF8.GetBytes(key);
                var sigMethod = new HMACSHA1(keyBytes);

                byte[] data = Encoding.UTF8.GetBytes(signatureBase);
                var hash = sigMethod.ComputeHash(data);
                var sig = Convert.ToBase64String(hash);

                sig = Uri.EscapeDataString(sig);
                return sig;
        }

        private void myInit() {
                int found = 0;
                string[] words = sessionData.Split('&');
                for (uint L = 0; L < words.Length; L++)
                {
                        if (words[L].StartsWith("oauth_token="))
                        {
                                ++found;
                                accessToken = words[L];
                        }
                        else if (words[L].StartsWith("oauth_token_secret="))
                        {
                                ++found;
                                tokenSecret = 
words[L].Substring("oauth_token_secret=".Length);
                        }
                        else if (words[L].StartsWith("user_id=")) {
                                ++found;
                                userID = words[L].Substring("user_id=".Length);
                        }
                        else if (words[L].StartsWith("screen_name=")) {
                                ++found;
                                screenName = 
words[L].Substring("screen_name=".Length);
                        }
                }
                if (found != 4) {
                        throw new Exception("Unknown response from server");
                }
        }

        public new void createSession(System.Web.UI.Page page)
        {
                if (
                        
!string.IsNullOrEmpty(page.Request.QueryString["oauth_token"])
                ) {
                        string timestamp = createTimestamp();
                        string nonce = createNonce();

                        var sigBase =
                                "GET"
                                + "&" + 
Uri.EscapeDataString("https://api.twitter.com/oauth/
access_token")
                                + "&" + 
Uri.EscapeDataString("oauth_consumer_key=" + clientID)
                                + "%26" + Uri.EscapeDataString("oauth_nonce=" + 
nonce)
                                + "%26" + 
Uri.EscapeDataString("oauth_signature_method=HMAC-SHA1")
                                + "%26" + 
Uri.EscapeDataString("oauth_timestamp=" + timestamp)
                                + "%26" + Uri.EscapeDataString("oauth_token=" +
page.Request.QueryString["oauth_token"])
                                + "%26" + 
Uri.EscapeDataString("oauth_version=1.0")
                        ;
                        string signature = createSignature(sigBase);

                        string url = 
"https://api.twitter.com/oauth/access_token";;
                        WebClient client = new WebClient();
                        client.Headers["Authorization"] =
                                "OAuth "
                                + "oauth_consumer_key=\"" + clientID + "\", "
                                + "oauth_nonce=\"" + nonce + "\", "
                                + "oauth_signature=\"" + signature + "\", "
                                + "oauth_signature_method=\"HMAC-SHA1\", "
                                + "oauth_timestamp=\"" + timestamp + "\", "
                                + "oauth_token=\"" + 
page.Request.QueryString["oauth_token"] +
"\", "
                                + "oauth_version=\"1.0\""
                        ;
                        byte[] data = client.DownloadData(url);
                        sessionData = Encoding.UTF8.GetString(data);

                        myInit();
                }
                else {
                        string timestamp = createTimestamp();
                        string nonce = createNonce();
                        var sigBase =
                                "GET"
                                + "&" + 
Uri.EscapeDataString("https://api.twitter.com/oauth/
request_token")
                                + "&" + 
Uri.EscapeDataString("oauth_consumer_key=" + clientID)
                                + "%26" + Uri.EscapeDataString("oauth_nonce=" + 
nonce)
                                + "%26" + 
Uri.EscapeDataString("oauth_signature_method=HMAC-SHA1")
                                + "%26" + 
Uri.EscapeDataString("oauth_timestamp=" + timestamp)
                                + "%26" + 
Uri.EscapeDataString("oauth_version=1.0")
                        ;
                        string signature = createSignature(sigBase);

                        string url = 
"https://api.twitter.com/oauth/request_token";;
                        WebClient client = new WebClient();
                        client.Headers["Authorization"] =
                                "OAuth oauth_consumer_key=\"" + clientID + "\", 
"
                                + "oauth_nonce=\"" + nonce + "\", "
                                + "oauth_signature=\"" + signature + "\", "
                                + "oauth_signature_method=\"HMAC-SHA1\", "
                                + "oauth_timestamp=\"" + timestamp + "\", "
                                + "oauth_version=\"1.0\""
                        ;
                        byte[] data = client.DownloadData(url);
                        string requestToken = Encoding.UTF8.GetString(data);

                        bool found = false;
                        string[] words = requestToken.Split('&');
                        for (uint L = 0; L < words.Length; L++) {
                                if (words[L].StartsWith("oauth_token="))
                                {
                                        found = true;
                                        requestToken = words[L];
                                        break;
                                }
                        }
                        if (!found) {
                                throw new Exception("Unknown response from 
Twitter server");
                        }

                        page.Response.Redirect(
                                "https://api.twitter.com/oauth/authorize?";
                                + requestToken
                        );
                }
        }

        public new void continueSession(string data)
        {
                sessionData = data;
                myInit();
        }

        public new void pushMessage(string message) {
                string timestamp = createTimestamp();
                string nonce = createNonce();
                var sigBase =
                        "POST"
                        + "&" + 
Uri.EscapeDataString("http://api.twitter.com/1/statuses/
update.json")
                        + "&" + Uri.EscapeDataString("oauth_consumer_key=" + 
clientID)
                        + "%26" + Uri.EscapeDataString("oauth_nonce=" + nonce)
                        + "%26" + 
Uri.EscapeDataString("oauth_signature_method=HMAC-SHA1")
                        + "%26" + Uri.EscapeDataString("oauth_timestamp=" + 
timestamp)
                        + "%26" + Uri.EscapeDataString(accessToken)
                        + "%26" + Uri.EscapeDataString("oauth_version=1.0")
                        + "%26" + Uri.EscapeDataString("status=" + message)
                ;
                string signature = createSignature(sigBase);

                string url = "http://api.twitter.com/1/statuses/update.json";;
                var request = (HttpWebRequest)WebRequest.Create(url);
                request.Method = "POST";
                request.Headers["Authorization"] =
                        "OAuth "
                        + "oauth_nonce=\"" + nonce + "\","
                        + "oauth_signature_method=\"HMAC-SHA1\","
                        + "oauth_timestamp=\"" + timestamp + "\","
                        + "oauth_consumer_key=\"" + clientID + "\","
                        + "oauth_token=\"" + 
accessToken.Substring("oauth_token=".Length) +
"\","
                        + "oauth_signature=\"" + signature + "\","
                        + "oauth_version=\"1.0\""
                ;

                byte[] data = Encoding.UTF8.GetBytes("status=" + message);
                request.ServicePoint.Expect100Continue = false;
                request.ContentType = "application/x-www-form-urlencoded";
                request.ContentLength = data.Length;

                using (Stream stream = request.GetRequestStream()) {
                                stream.Write(data, 0, data.Length);
                }

                request.GetResponse();
        }
}

-- 
Twitter developer documentation and resources: http://dev.twitter.com/doc
API updates via Twitter: http://twitter.com/twitterapi
Issues/Enhancements Tracker: http://code.google.com/p/twitter-api/issues/list
Change your membership to this group: 
http://groups.google.com/group/twitter-development-talk?hl=en

Reply via email to