Posting status as app user?

Oct 14, 2013 at 9:22 PM
Edited Oct 14, 2013 at 10:33 PM
Hi

I'm so close to having this cracked!! And this is probably a stupid question, but I'm stuck!

My WP8 app uses the following credentials
                    // set twitter credentials
                    Credentials = new SingleUserInMemoryCredentials()
                    {
                        ConsumerKey = "gQh2m49cX2dTZA1Q",
                        ConsumerSecret = "zaHjIEdZG3e9uLqRuSECRETCghOFDwjs",
                        TwitterAccessToken = "1174197488-SwRjFyjfR3D8h7n2JGZReESpgjvG",
                        TwitterAccessTokenSecret = "0cWtGcRrJdU2QxeaSECRETRTuEk3CUa4",
                        UserId = TwitterAccountUserID.Split(':')[1]
                    }
These come from my apps twitter oauth page settings.

Now when I post a status, it comes from geoLogUK account (the one above), but the app has been authorized by a different user, SocialSceneBeta, the id of this user is the result of TwitterAccountUserID.Split(':')[1].

I assumed that setting UserId would make the post come from SocialSceneBeta??

What am I setting wrong??

PS. TwitterAccountUserID.Split(':')[0] (Note index is 0) holds the access token given when the user authorizes the app, should I be using this anywhere??

Many thanks

Jason.
Coordinator
Oct 14, 2013 at 10:03 PM
The query identity is based on the tokens loaded into the Credentials of the IAuthorizer assigned to the TwitterContext that invokes a query. If you authorize, the capture the credentials after authorization completes and save them for that user and reuse those credentials whenever that user uses your app again. That way you only authorize one time and the query will be on behalf of that user.

Since you used the SocialSceneBeta's credentials, the query will be on behalf of SocialSceneBeta. Instead, use the credentials of the person who authorized your app.

BTW, you'll want to edit your post to remove your tokens/secrets. Anyone can now use your tokens and operate on your behalf. Further, you'll want to rekey your application just in case that has already happened.

@JoeMayo
Oct 14, 2013 at 10:26 PM
Hi

I put word SECRET in middle of text fields, that should be ok??

Oct 15, 2013 at 8:41 AM
Ok, the only thing is that I don't use your api to authorize the app.

I use windows azure mobile services, this takes the user to the twitter authorize page, the user signs in, and the return values are their twitter id (int) and an auth_token.

These I save and need to use when the user wants to tweet, so how do I setup the credentials using these values??

Thanks

Jason.
Oct 17, 2013 at 10:00 AM
!!! URGENT !!!

I'm going to be demoing my app at the Nokia World event in Abu Dhabia next Tuesday and I'm still desperately trying to get posting a status a the app user working.

Here is the auth/credential code :-
                // setup single user authorization
                var auth = new SingleUserAuthorizer()
                {
                    // set twitter credentials
                    Credentials = new SingleUserInMemoryCredentials()
                    {
                        ConsumerKey = "gQh21Q",
                        ConsumerSecret = "zaHjIEdZG3ermwPiDwjs",
                        TwitterAccessToken =  "117488-Sw2JGZReESpgjvG",
                        TwitterAccessTokenSecret = "0cWtGcRRTuEk3CURm70ZGjTa4",
                        UserId = TwitterAccountUserID.Split(':')[1],
                    }
                };
ConsumerKey = from oauth page on dev twitter page
ConsumerSecret = from oauth page on dev twitter page
TwitterAccessToken = from oauth page on dev twitter page
TwitterAccessTokenSecret = from oauth page on dev twitter page

The above are linked to @geoLogUK. UserId = the twitter user id of the app user @SocialSceneBeta, it's from this account that I want the tweet to be sent from.

But when logged into the app as @SocialSceneBeta or any other account for that matter, the tweet always comes from @geoLogUK. Whats wrong with my setup, please please help, I'll give you a mention at the show!!!
Coordinator
Oct 17, 2013 at 5:24 PM
I'm going to describe a different approach that might be simpler for demo purposes. The concept is that you want to use the credentials (TwitterAccessToken and TwitterAccessTokenSecret) that belong to @SocialSceneBeta. This wasn't happening because you were using the credentials that belong to @geoLogUK. The credentials are what determines who the authorized (logged in) user is. All Twitter commands operate on behalf of the authorized user, which is the user whose credentials you are using. Try this:
  1. Use a PinAuthorizer. Can use the Console demos in the downloadable source for this step.
            var auth = new PinAuthorizer
            {
                Credentials = new InMemoryCredentials
                {
                    ConsumerKey = "<your app consumer key>",
                    ConsumerSecret = "<your consumer secret>",
                    //OAuthToken = //this is null, don't add it yet
                    //AccessToken = //this is null, don't add it yet
                },
                AuthAccessType = AuthAccessType.NoChange,
                UseCompression = true,
                GoToTwitterAuthorization = pageLink => Process.Start(pageLink),
                GetPin = () =>
                {
                    // this executes after user authorizes, which begins with the call to auth.Authorize() below.
                    Console.WriteLine("\nAfter authorizing this application, Twitter will give you a 7-digit PIN Number.\n");
                    Console.Write("Enter the PIN number here: ");
                    return Console.ReadLine();
                }
            };

            // start the authorization process (launches Twitter authorization page).
            auth.Authorize(true);
  1. Set a breakpoint in your code after Authorize() returns.
  2. Run the code and let the @SocialSceneBeta user authorize your app. This is who you want to be the authorized user.
  3. After you set the pin, the program will hit the breakpoint.
  4. Extract the OAuthToken and AccessToken from the Credentials property of the authorizer instance. These are the credentials that belong to the authorized user, @SocialSceneBeta.
  5. You now have the OAuthToken and AccessToken for @SocialSceneBeta. Use these credentials in your authorizer from now on.
  6. In your code, add a PinAuthorizer that includes all 4 credentials.
            var auth = new PinAuthorizer
            {
                Credentials = new InMemoryCredentials
                {
                    ConsumerKey = "<your app consumer key>",
                    ConsumerSecret = "<your consumer secret>",
                    OAuthToken = "<the OAuthToken you read during step #5>",
                    AccessToken = "<the AccessToken you read during step #5>"
                },
                AuthAccessType = AuthAccessType.NoChange,
                UseCompression = true,
                GoToTwitterAuthorization = pageLink => Process.Start(pageLink),
                GetPin = () =>
                {
                    // this executes after user authorizes, which begins with the call to auth.Authorize() below.
                    Console.WriteLine("\nAfter authorizing this application, Twitter will give you a 7-digit PIN Number.\n");
                    Console.Write("Enter the PIN number here: ");
                    return Console.ReadLine();
                }
            };

            var ctx = new TwitterContext(auth);

           auth.UpdateStatus("Your tweet text");
Whenever you have populated all 4 credentials, PinAuthorizer won't make the user perform the authorization process anymore.

It seems like you'll be doing this on Windows Phone. If you want the status back, you can use an overload that accepts a callback:
            twitterCtx.UpdateStatus(status,
                response =>
                {
                    if (response.Status == TwitterErrorStatus.Success)
                    {
                        Status tweet = response.State;

                        Console.WriteLine(
                            "Status returned: " +
                            "(" + tweet.StatusID + ")" +
                            "[" + tweet.User.ID + "]" +
                            tweet.User.Name + ", " +
                            tweet.Text + ", " +
                            tweet.CreatedAt + "\n");
                    }
                    else
                    {
                        Console.WriteLine(response.Exception.ToString());
                    }
                });
BTW, you posted your secrets again.

@JoeMayo
Oct 17, 2013 at 6:31 PM
I Joe,

I took loads of data out of the secrets fields, so they are not real.

This solution still involves using the .Authorize method.

This there no way to bypass this method with your api.

The user has already been authorized in the app using azure services (I get twitter id and access token from this process.). This is done when they login to my app using their twitter account.

After that, if they want to post a message I don't want them to be prompted again using a pin authorizer or anything.

The only field you have mentioned, that I am not given during the sign in process is the OAuthToken field.

I'm confused.com !!!
Coordinator
Oct 17, 2013 at 7:06 PM
LINQ to Twitter was designed and working long before Azure Mobile Services existed. I haven't used LINQ to Twitter with Azure mobile services, so I'm unable to reliably comment on that or guess on the advice you would need. It would require some research to figure out if it were possible. However, I can tell you how LINQ to Twitter works today, without Azure Mobile Services.

Read and follow all of the steps. I've also included reasons why you should take each step and how they contribute to solving the problem. The first 5 steps explain how to obtain the credentials for @SocialSceneBeta. Look at step #6 and the code that follows. It fills in all 4 credentials and does not require the user to authorize.

To use LINQ to Twitter, you must have all 4 credentials, which includes both OAuthToken and AccessToken. If you've filled in all 4 credentials, then the user will not have to authorize. Just write the code - do a sample app and experiment as needed with what I've described and you'll see what happens.

I also have some documentation, Securing your Applications, that might help you understand OAuth a bit more.

@JoeMayo
Oct 17, 2013 at 7:35 PM
Cheers Joe

I'll have to review my process and see how it pans out.