windows-phone-7twitteroauthtweetsharphammock

Twitter, OAuth, Hammock, TweetSharp and Windows Phone 7


I've been trying for days to get OAuth working with Twitter in my Windows Phone app, but all the information I find is out dated or difficult to follow. I eventually got somewhere when I found this blog post http://samjarawan.blogspot.co.uk/2010/09/building-real-windows-phone-7-twitter_18.html which got me all the way to getting the access token, at which point it failed.

My code is almost identical to the one in the blog post, pretty much just changed the consumer key and consumer secret. Even their app doesn't work. It displays the Twitter login screen fine, and successfully authenticates, but in the RequestAccessToken function, it fails at this point:

if (String.IsNullOrEmpty(twitteruser.AccessToken) || String.IsNullOrEmpty(twitteruser.AccessTokenSecret))
{
    Dispatcher.BeginInvoke(() => MessageBox.Show(response.Content));
    return;
}

The really annoying thing is the message box only shows the Unicode replacement character (�) and nothing else. I also checked the response.StatusCode and it is OK, so there is no error as far as I can tell.

If someone could help me out with this, that would be great. I've seen other tutorials which require the user type in a PIN, but I haven't been able to get any of those to work either.

EDIT: I've just tried getting TweetSharp to work, but once again it fails to get the access token. Here is the code I'm using for TweetSharp:

public partial class TwitterAuthorisationPage : PhoneApplicationPage
{
    private const string consumerKey = "myKey";
    private const string consumerSecret = "mySecret"; // These are the correct values for my app
    private const string requestTokenUri = "https://api.twitter.com/oauth/request_token";
    private const string oAuthVersion = "1.0a";
    private const string authorizeUri = "https://api.twitter.com/oauth/authorize";
    private const string accessTokenUri = "https://api.twitter.com/oauth/access_token";
    private const string callbackUri = "http://bing.com";

    private TwitterService twitterService = new TwitterService(consumerKey, consumerSecret);
    private OAuthRequestToken _requestToken = null;

    public TwitterAuthorisationPage()
    {
        InitializeComponent();
    }

    protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);
        twitterService.GetRequestToken((requestToken, response) =>
        {
            if (response.StatusCode == HttpStatusCode.OK)
            {
                _requestToken = requestToken;
                Dispatcher.BeginInvoke(() => BrowserControl.Navigate(twitterService.GetAuthorizationUri(requestToken)));
            }
            else
            {
                Dispatcher.BeginInvoke(() => MessageBox.Show("Failed to connect to Twitter. Please try again.\n" + response.StatusDescription));
            }
        });
    }

    private void ConfirmButton_Click(object sender, RoutedEventArgs e)
    {
        twitterService.GetAccessToken(_requestToken, PINEntry.Text, (accessToken, response) =>
        {
            if (response.StatusCode == HttpStatusCode.OK)
            {
                //These lines just print ?
                System.Diagnostics.Debug.WriteLine(accessToken.Token);
                System.Diagnostics.Debug.WriteLine(accessToken.TokenSecret);
                twitterService.AuthenticateWith(accessToken.Token, accessToken.TokenSecret);
                twitterService.VerifyCredentials((user, verifyResponse) =>
                {
                    if (verifyResponse.StatusCode == HttpStatusCode.OK)
                    {
                        Dispatcher.BeginInvoke(() => MessageBox.Show(user.Name));
                    }
                    else
                    {
                        // Fails here
                        Dispatcher.BeginInvoke(() => MessageBox.Show("Failed to connect to Twitter. Please try again.1\n" + verifyResponse.StatusDescription));
                    }
                });
            }
            else
            {
                Dispatcher.BeginInvoke(() => MessageBox.Show("Failed to connect to Twitter. Please try again.0\n" + response.StatusDescription));
            }
        });
    }
}

EDIT 2: Could it be to do with this? https://dev.twitter.com/blog/ssl-upgrade-for-twitterapi


Solution

  • I worked it out! It turns out Twitter was returning the access token Gzipped. Using the method described in the blog post, I had to change the second RestClient to be constructed like so:

    var client = new RestClient
    {
        Authority = "https://api.twitter.com/oauth",
        Credentials = credentials,
        HasElevatedPermissions = true,
        SilverlightAcceptEncodingHeader = "gzip",
        DecompressionMethods = DecompressionMethods.GZip
    };
    

    And now it works!