4

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

  • Whats is on the response statusText? Also, if you only need Twitter, you could look at [TweetSharp](https://github.com/danielcrenna/tweetsharp) – pradeek May 08 '12 at 00:30
  • response doesn't have a property statusText, it does have StatusDescription though, which just says "OK". I am planning on using Facebook login as well, so it would be nice to get this version working since I imagine Facebook will require similar steps. I did look at TweetSharp at one point but couldn't get it to build, I might take another look. –  May 08 '12 at 07:31
  • See my edit, TweetSharp doesn't work either, or I'm missing something. –  May 08 '12 at 08:23

2 Answers2

4

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!

0

I am having the same problem but I didn't understand your solution, could you explain a bit more where you changed the rest client?

-----EDIT----

I finally was able to make it work with TweetSharp. I downloaded the source code and added the lines you mentioned to the rest client configuration it uses and the compiled the project again. Since i cannot push my changes to that github, I upload the dll here. TweetSharp recompiled dll

This is the code I use which with it works

// Step 1 - Retrieve an OAuth Request Token
        Service.GetRequestToken((requestToken, response) =>
        {
            if (response.StatusCode == HttpStatusCode.OK)
            {
                Request = requestToken;
                Uri uri = Service.GetAuthorizationUri(requestToken);
                Dispatcher.BeginInvoke(() =>
                {
                    Browser.Navigate(uri);
                }
               );
            }
        });


//Step 2, get the pincode

string html = Browser.SaveToString(); //gets the DOM as a string
            Regex expression = new Regex(@"<code>(?<word>\w+)</code>"); 
            Match match = expression.Match(html);
            string pin = match.Groups["word"].Value;
            if (pin != "")
            {                    
                loginTwitter(pin); //we login with the pin extracted
            }

//step 3, get access tokens from twitter
 private void loginTwitter(string pin)
    {
        Service.GetAccessToken(Request, pin, processAccessToken);
    }


    public void processAccessToken(OAuthAccessToken access, TwitterResponse Response){
        if (Response.StatusCode == HttpStatusCode.OK)
        {
            if (access != null)
            {
                Access = access; // Store it for reuse
                Service.AuthenticateWith(access.Token, access.TokenSecret);
            }
        }
    }
Berni
  • 510
  • 4
  • 12