Google Latest Twitter integration in windows phone 8 c# | SubramanyamRaju Xamarin & Windows App Dev Tutorials

Thursday, 28 November 2013

Latest Twitter integration in windows phone 8 c#

Introduction

I am trying to integrate the Twitter app in Windows Phone 8 app. I have downloaded the tweetsharp package from the Nuget but I am not able to get the Twitterservice method named GetRequestToken.Because of  recentlyTwitter API 1.0 was retired  and Twitter  API 1.1 is available now. So I tried many ways which I got in my search ,finnaly got boring and stop doing.Recently i had come with good solutions "Posting tweets using hammock" instead of using tweetsharp.


Building the Sample

This article will help you in posting your tweets/ updating your timeline status in Twitter using Hammock library...You may get this library from http://www.nuget.org/packages/Hammock.
To work with Twitter, we have to register our app at Twitter Developer Site. To do so, after we successfully logged in in Twitter, we've to go to My Applications | Create a New Application. Now we have to fill the details of our app.
After registering the app, we will be provided with some URLs that we will be using in making OAuth requests and Consumer key and Consumer Secret Key. Save the two keys somewhere as we will require them later in the project.

Description
  • The MainPage.xaml file has the following contents now.
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
 
            <phone:WebBrowser Grid.Row="0" Margin="-6,3,0,1" Name="loginBrowserControl" Visibility="Collapsed"
                              Navigated="loginBrowserControl_Navigated" Navigating="loginBrowserControl_Navigating" 
                              IsScriptEnabled="True"/>
 
            <Grid x:Name="TweetPanel" Grid.Row="0" Visibility="Collapsed">
                <Grid.RowDefinitions>
                    <RowDefinition Height=".15*"/>
                    <RowDefinition Height=".10*"/>
                    <RowDefinition Height=".60*"/>
                    <RowDefinition Height=".15*"/>
                </Grid.RowDefinitions>
 
                <TextBlock Grid.Row="0" x:Name="txtUserName" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="26" FontFamily="Segoe WP Bold" Foreground="Red"/>
                <TextBlock Grid.Row="1" Margin="10" VerticalAlignment="Center" HorizontalAlignment="Left" Text="Enter your Tweet" FontSize="24" FontFamily="Segoe WP Bold"/>
                <TextBox Grid.Row="2" x:Name="txtTweetContent" Margin="20,-10,20,100" TextWrapping="Wrap" Text="" FontSize="24" FontFamily="Segoe WP Bold" />
                <Button Grid.Row="3" x:Name="btnPostTweet" Content="Post Tweet" HorizontalAlignment="Center" Click="btnPostTweet_Click"/>
 
            </Grid>
        </Grid>
Note: it is important to use path like this  Path = "/1.1/statuses/update.json " , If you are using 1.0 version path it will never work at all because of Twitter API 1.0 was retired recently and API 1.1 available at present.
C#
using System; 
using System.Collections.Generic; 
using System.Linq; 
using Hammock.Web; 
using System.IO; 
using Hammock; 
using System.Text; 
using Hammock.Authentication.OAuth; 
using Microsoft.Phone.Controls; 
using System.Windows; 
using System.Net; 
 
namespace TwitterPost 
{ 
    public partial class MainPage : PhoneApplicationPage 
    { 
        //http://developer.nokia.com/Community/Wiki/Twitter:_OAuth_1.0_Authentication_using_Hammock 
        string OAuthTokenKey = string.Empty; 
        string tokenSecret = string.Empty; 
        string accessToken = string.Empty; 
        string accessTokenSecret = string.Empty; 
        string userID = string.Empty; 
        string userScreenName = string.Empty; 
        public MainPage() 
        { 
            InitializeComponent(); 
            if (isAlreadyLoggedIn()) 
            { 
                userLoggedIn(); 
            } 
            else 
            { 
                var requestTokenQuery = OAuthUtil.GetRequestTokenQuery(); 
                requestTokenQuery.RequestAsync(AppSettings.RequestTokenUri, null); 
                requestTokenQuery.QueryResponse += new EventHandler<WebQueryResponseEventArgs>(requestTokenQuery_QueryResponse); 
            } 
            
        } 
 
        private Boolean isAlreadyLoggedIn() 
        { 
            accessToken = MainUtil.GetKeyValue<string>("AccessToken"); 
            accessTokenSecret = MainUtil.GetKeyValue<string>("AccessTokenSecret"); 
            userScreenName = MainUtil.GetKeyValue<string>("ScreenName"); 
 
            if (string.IsNullOrEmpty(accessToken) || string.IsNullOrEmpty(accessTokenSecret)) 
                return false; 
            else 
                return true; 
        } 
 
        private void userLoggedIn() 
        { 
            Dispatcher.BeginInvoke(() => 
            { 
               // var SignInMenuItem = (Microsoft.Phone.Shell.ApplicationBarMenuItem)this.ApplicationBar.MenuItems[0]; 
               // SignInMenuItem.IsEnabled = false; 
 
               // var SignOutMenuItem = (Microsoft.Phone.Shell.ApplicationBarMenuItem)this.ApplicationBar.MenuItems[1]; 
                //SignOutMenuItem.IsEnabled = true; 
 
                TweetPanel.Visibility = System.Windows.Visibility.Visible; 
                txtUserName.Text = "Welcome " + userScreenName; 
            }); 
        } 
        private void MenuItemSignOut_Click(object sender, EventArgs e) 
        { 
            MainUtil.SetKeyValue<string>("AccessToken"string.Empty); 
            MainUtil.SetKeyValue<string>("AccessTokenSecret"string.Empty); 
            Dispatcher.BeginInvoke(() => 
            { 
               // var SignInMenuItem = (Microsoft.Phone.Shell.ApplicationBarMenuItem)this.ApplicationBar.MenuItems[0]; 
                //SignInMenuItem.IsEnabled = true; 
 
                //var SignOutMenuItem = (Microsoft.Phone.Shell.ApplicationBarMenuItem)this.ApplicationBar.MenuItems[1]; 
               // SignOutMenuItem.IsEnabled = false; 
 
                TweetPanel.Visibility = System.Windows.Visibility.Collapsed; 
 
                MessageBox.Show("You have been signed out successfully."); 
            }); 
        } 
        private void btnPostTweet_Click(object sender, RoutedEventArgs e) 
        { 
            var credentials = new OAuthCredentials 
            { 
                Type = OAuthType.ProtectedResource, 
                SignatureMethod = OAuthSignatureMethod.HmacSha1, 
                ParameterHandling = OAuthParameterHandling.HttpAuthorizationHeader, 
                ConsumerKey = AppSettings.consumerKey, 
                ConsumerSecret = AppSettings.consumerKeySecret, 
                Token = this.accessToken, 
                TokenSecret = this.accessTokenSecret, 
                Version = "1.0" 
            }; 
 
            var restClient = new RestClient 
            { 
                Authority = "https://api.twitter.com", 
                HasElevatedPermissions = true 
            }; 
 
            var restRequest = new RestRequest 
            { 
                Credentials = credentials, 
                Path = "/1.1/statuses/update.json", 
                Method = WebMethod.Post 
            }; 
 
            restRequest.AddParameter("status", txtTweetContent.Text); 
            restClient.BeginRequest(restRequest, new RestCallback(PostTweetRequestCallback)); 
        } 
        private void PostTweetRequestCallback(RestRequest request, RestResponse response, object obj) 
        { 
            Deployment.Current.Dispatcher.BeginInvoke(() => 
            { 
                if (response.StatusCode == HttpStatusCode.OK) 
                { 
                    MessageBox.Show("TWEET_POSTED_SUCCESSFULLY"); 
                } 
                else if (response.StatusCode == HttpStatusCode.Forbidden) 
                { 
                    MessageBox.Show("TWEET_POST_ERR_UPDATE_LIMIT"); 
                } 
                else 
                { 
                    MessageBox.Show("WEET_POST_ERR_FAILED"); 
                } 
                txtTweetContent.Text = ""; 
            }); 
            //var requestTokenQuery = OAuthUtil.GetRequestTokenQuery(); 
            //requestTokenQuery.RequestAsync(AppSettings.RequestTokenUri, null); 
            //requestTokenQuery.QueryResponse += new EventHandler<WebQueryResponseEventArgs>(requestTokenQuery_QueryResponse); 
        } 
 
        void requestTokenQuery_QueryResponse(object sender, WebQueryResponseEventArgs e) 
        { 
            try 
            { 
                StreamReader reader = new StreamReader(e.Response); 
                string strResponse = reader.ReadToEnd(); 
                var parameters = MainUtil.GetQueryParameters(strResponse); 
                OAuthTokenKey = parameters["oauth_token"]; 
                tokenSecret = parameters["oauth_token_secret"]; 
                var authorizeUrl = AppSettings.AuthorizeUri + "?oauth_token=" + OAuthTokenKey; 
 
                Dispatcher.BeginInvoke(() => 
                { 
                    this.loginBrowserControl.Navigate(new Uri(authorizeUrl, UriKind.RelativeOrAbsolute)); 
                }); 
            } 
            catch (Exception ex) 
            { 
                Dispatcher.BeginInvoke(() => 
                { 
                    MessageBox.Show(ex.Message); 
                }); 
            } 
        } 
  
 
        private void loginBrowserControl_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e) 
        { 
            this.loginBrowserControl.Visibility = Visibility.Visible; 
            this.loginBrowserControl.Navigated -= loginBrowserControl_Navigated; 
        } 
 
        private void loginBrowserControl_Navigating(object sender, NavigatingEventArgs e) 
        { 
            if (e.Uri.ToString().StartsWith(AppSettings.CallbackUri)) 
            { 
                var AuthorizeResult = MainUtil.GetQueryParameters(e.Uri.ToString()); 
                var VerifyPin = AuthorizeResult["oauth_verifier"]; 
                this.loginBrowserControl.Visibility = Visibility.Collapsed; 
                var AccessTokenQuery = OAuthUtil.GetAccessTokenQuery(OAuthTokenKey, tokenSecret, VerifyPin); 
 
                AccessTokenQuery.QueryResponse += new EventHandler<WebQueryResponseEventArgs>(AccessTokenQuery_QueryResponse); 
                AccessTokenQuery.RequestAsync(AppSettings.AccessTokenUri, null); 
            } 
        } 
 
        void AccessTokenQuery_QueryResponse(object sender, WebQueryResponseEventArgs e) 
        { 
            try 
            { 
                StreamReader reader = new StreamReader(e.Response); 
                string strResponse = reader.ReadToEnd(); 
                var parameters = MainUtil.GetQueryParameters(strResponse); 
                accessToken = parameters["oauth_token"]; 
                accessTokenSecret = parameters["oauth_token_secret"]; 
                userID = parameters["user_id"]; 
                userScreenName = parameters["screen_name"]; 
 
                MainUtil.SetKeyValue<string>("AccessToken", accessToken); 
                MainUtil.SetKeyValue<string>("AccessTokenSecret", accessTokenSecret); 
                MainUtil.SetKeyValue<string>("ScreenName", userScreenName); 
 
                userLoggedIn(); 
            } 
            catch (Exception ex) 
            { 
                Dispatcher.BeginInvoke(() => 
                { 
                    MessageBox.Show(ex.Message); 
                }); 
            } 
        } 
    } 
} 
 
***************************** 
Note:Before going to use above code you must be add following classes 
 
 
using Hammock.Authentication.OAuth; 
using Hammock.Web; 
using System; 
using System.Collections.Generic; 
using System.IO.IsolatedStorage; 
using System.Linq; 
using System.Text; 
 
namespace TwitterPost 
{ 
    public class AppSettings 
    { 
        // twitter 
        public static string RequestTokenUri = "https://api.twitter.com/oauth/request_token"; 
        public static string AuthorizeUri = "https://api.twitter.com/oauth/authorize"; 
        public static string AccessTokenUri = "https://api.twitter.com/oauth/access_token"; 
        public static string CallbackUri = "http://www.google.com";   // we've mentioned Google.com as our callback URL. 
 
//#error TODO REGISTER YOUR APP WITH TWITTER TO GET YOUR KEYS AND FILL THEM IN HERE 
        public static string consumerKey = ""; 
        public static string consumerKeySecret = ""; 
 
        public static string oAuthVersion = "1.0a"; 
    } 
    public class MainUtil 
    { 
        public static Dictionary<stringstring> GetQueryParameters(string response) 
        { 
            Dictionary<stringstring> nameValueCollection = new Dictionary<stringstring>(); 
            string[] items = response.Split('&'); 
 
            foreach (string item in items) 
            { 
                if (item.Contains("=")) 
                { 
                    string[] nameValue = item.Split('='); 
                    if (nameValue[0].Contains("?")) 
                        nameValue[0] = nameValue[0].Replace("?"""); 
                    nameValueCollection.Add(nameValue[0], System.Net.HttpUtility.UrlDecode(nameValue[1])); 
                } 
            } 
            return nameValueCollection; 
        } 
 
        internal static T GetKeyValue<T>(string key) 
        { 
            if (IsolatedStorageSettings.ApplicationSettings.Contains(key)) 
                return (T)IsolatedStorageSettings.ApplicationSettings[key]; 
            else 
                return default(T); 
        } 
 
        internal static void SetKeyValue<T>(string key, T value) 
        { 
            if (IsolatedStorageSettings.ApplicationSettings.Contains(key)) 
                IsolatedStorageSettings.ApplicationSettings[key] = value; 
            else 
                IsolatedStorageSettings.ApplicationSettings.Add(key, value); 
            IsolatedStorageSettings.ApplicationSettings.Save(); 
        } 
    } 
    public class OAuthUtil 
    { 
        internal static OAuthWebQuery GetRequestTokenQuery() 
        { 
            var oauth = new OAuthWorkflow 
            { 
                ConsumerKey = AppSettings.consumerKey, 
                ConsumerSecret = AppSettings.consumerKeySecret, 
                SignatureMethod = OAuthSignatureMethod.HmacSha1, 
                ParameterHandling = OAuthParameterHandling.HttpAuthorizationHeader, 
                RequestTokenUrl = AppSettings.RequestTokenUri, 
                Version = AppSettings.oAuthVersion, 
                CallbackUrl = AppSettings.CallbackUri 
            }; 
 
            var info = oauth.BuildRequestTokenInfo(WebMethod.Get); 
            var objOAuthWebQuery = new OAuthWebQuery(info, false); 
            objOAuthWebQuery.HasElevatedPermissions = true; 
            objOAuthWebQuery.SilverlightUserAgentHeader = "Hammock"; 
            return objOAuthWebQuery; 
        } 
 
        internal static OAuthWebQuery GetAccessTokenQuery(string requestToken, string RequestTokenSecret, string oAuthVerificationPin) 
        { 
            var oauth = new OAuthWorkflow 
            { 
                AccessTokenUrl = AppSettings.AccessTokenUri, 
                ConsumerKey = AppSettings.consumerKey, 
                ConsumerSecret = AppSettings.consumerKeySecret, 
                ParameterHandling = OAuthParameterHandling.HttpAuthorizationHeader, 
                SignatureMethod = OAuthSignatureMethod.HmacSha1, 
                Token = requestToken, 
                Verifier = oAuthVerificationPin, 
                Version = AppSettings.oAuthVersion 
            }; 
 
            var info = oauth.BuildAccessTokenInfo(WebMethod.Post); 
            var objOAuthWebQuery = new OAuthWebQuery(info, false); 
            objOAuthWebQuery.HasElevatedPermissions = true; 
            objOAuthWebQuery.SilverlightUserAgentHeader = "Hammock"; 
            return objOAuthWebQuery; 
        } 
    } 
 

Related Posts:

  1. WindowsPhone Facebook Integration:How to post message/image to FaceBook Fan Page(C#-XAML)
  2. Now Direct Facebook Login Support available With Windows Phone 8 C# 
Have a nice day by 

29 comments:

  1. Sorry sir, I would like to ask some questions about your app: Twitter Post. http://code.msdn.microsoft.com/wpapps/Latest-Twitter-integration-a42e8bb6.
    The problem here is when I run the app, it shows a msg: "the given key was not present in the dictionary".
    Can you explain it for me?
    Thank you.

    ReplyDelete
    Replies
    1. Make sure your device wifi/data pack network connection should not be block the twitter website.Check once on your windows phone device internet explorer browser whether twitter website is working or not.

      Delete
    2. I can not access to www.twitter.com. It is blocked from my emulator (I run it on emulator). But, I can still access the www.google.com.

      Delete
    3. Yeah,That's the problem so that ask your admin to unblock twitter social network from your emulator networks.Then it will be work fine

      Delete
    4. I run the app on my laptop. Can you show me how to unblock the twitter?

      Delete
    5. Yar,its not development part,and ask your office admin to unblock twitter website based on your Device Ip address.

      Delete
    6. I will try it on real device.
      Btw, can you give me briefly code explaination or some documents so that I can understand the code easier.
      Many thanks

      Delete
    7. Hey Subbu, i am fan of yours after implementing it, it made my life easy. @Sang i had same prob that is with yours but i tried on device, its working fine. Thanks

      Delete
  2. I'm getting the same error and I'm running the app on my phone, any ideas?

    ReplyDelete
  3. Make sure your device wifi/data pack network connection should not be block the twitter website.Check once on your windows phone device internet explorer browser whether twitter website is working or not.If twitter website is not working on your browser,you should unblock the twitter social network from your device network,then only you can able to post messages to twitter.

    ReplyDelete
  4. Thanks for your help so quickly, but believe me via Browser I'm able to see Twitter, any other idea?

    Regards.

    ReplyDelete
  5. Hi Subbu. Thank you for simple and clear method for twitter integration with WP8 . i try with your code . I received the alert on load page "The given key was not present in the dictionary" plz tel how to solve this

    ReplyDelete
    Replies
    1. Hi guys,

      I just rechecking the this post sample ,I am not found any errors in my side,and able to post successfully on twitter.And guys please check procedure once while creating twitter account for app.
      1)Make sure your wifi network connections should be block twitter social website,to check it run twitter.com website on your device browser
      2)Make sure check once you should give proper values in Class1.cs file
      public static string CallbackUri = "";
      public static string consumerKey = "";
      public static string consumerKeySecret = "";
      3)Make sure your twitter account app permissions should be all for write,read

      Delete
  6. I test your code in device i got this msg. [Arg_keyNotFound]Arguments:
    Debugging resource string are unavailable
    often the key and arguments provide sufficient information to diagnose the problem
    http://go.microsoft.com/fwlink/?linkid=106663&Version=4.0.50829.0&File=mscorlib.dll&Key=Arg_keyNotFound

    ReplyDelete
    Replies
    1. Try this sample link ,and just place your values in Class1.cs file
      public static string CallbackUri = "";
      public static string consumerKey = "";
      public static string consumerKeySecret = "";
      and finally run it
      Sample link:https://onedrive.live.com/?cid=5f04a15546a742bc&id=5F04A15546A742BC%218439#cid=5F04A15546A742BC

      Delete
    2. Thank You Subbu . I solve it using apply callback url in App settings.

      Delete
    3. share status on LinkedIn using windows phone 8

      Hi Subramanyam your windows phone 8 twitter share it's work fine for me . now i need to add same functionality for Linked In and Google + . so Plz guide me to complete the functionality.
      My Mail ID pixel.gurunathan.n@gmail.com.
      Thank You. Waiting For your Reply.....

      Delete
    4. Hi Pixel..I am also getting same error..: [Arg_keyNotFound]Arguments:
      Debugging resource string are unavailable
      often the key and arguments provide sufficient information to diagnose the problem
      http://go.microsoft.com/fwlink/?linkid=106663&Version=4.0.50829.0&File=mscorlib.dll&Key=Arg_keyNotFound
      How you solved it?Please help me

      Delete
  7. hi Subramanyam,
    I need to get the replies to the tweet I am posting using the above sample.
    Tweetinvi API has a method which gives direct replies to a tweet given its tweet id.
    How can I get the id ?

    ReplyDelete
    Replies
    1. Hi Ashutosh,

      After successfully post,we will get response in this method.Please debug at
      private void PostTweetRequestCallback(RestRequest request, RestResponse response, object obj)
      {
      }

      Example Response :
      {"created_at":"Mon Apr 07 07:09:42 +0000 2014","id":453067073850073088,"id_str":"453067073850073088","text":"My Sample App test"

      Delete
    2. Thanks for the reply.
      I am able to parse the id but somehow the Tweetinvi API doesn't seem to work. What I want to do is after tweeting , wait for sometime and get the replies to this tweet.

      Delete
  8. Sir how can i integrate facebook , google, and twitter login to a single app and manage the app session ?

    ReplyDelete
  9. Hi Subramanyam Raju,

    Is a valid CallbackUri a necessity? I don't have any websites and during app registration it is said to be optional. Isn't there any way to get back to the app after login into twitter without giving CallbackUri?

    I suppose that was possible in Twitter API 1.0. What if I supply username & password? Is there any API method that facilitates this in ver 1.1?

    - Shantimohan

    ReplyDelete
    Replies
    1. Give any call back url(Ex:http://www.google.com),otherwise you will not be redirect to your page.

      Delete
    2. When I set string CallbackUri = "www.google.com", the strResponse in requestTokenQuery_QueryResponse event handler is as below:



      Desktop applications only support the oauth_callback value 'oob'
      /oauth/request_token


      So I set string CallbackUri = "oob"; Now it goes to twitter login page. After logging in, it shows the PIN page. I noted the PIN and tap on 'Go to ' link and it goes to domain search page as the web site given in app registration at twitter.com is only a placeholder.

      In app list it is still under TwitterPost name. When I press the back button, the app is terminated. It never returns to the app.

      Any suggestions?

      Delete
    3. After I tap on the 'Go to my app' link, the e.Uri in loginBrowserControl_Navigating event is just the web site address that I have given in the app's registration settings without the PIN. So even if I force the 'if' to be true in the debugger, AuthorizeResult is set to empty string. Why the Twitter is not returning the PIN in the response?

      Delete
    4. This comment has been removed by the author.

      Delete
    5. I have same issue.How have you resolved this issue

      Delete
  10. This comment has been removed by the author.

    ReplyDelete

Search Engine Submission - AddMe