No artigo anterior (Posts e consultas no twitter pelo windows phone 7 part 1 de 2) no vimos como construir uma aplicação no windows phone 7 que faça consultas no twitter utilizando o api do twitter; Neste artigo vamos tentar construir nesta mesma aplicação algo que o usuário possa fazer o login no twitter, visualize seus posts e adicione novos.
No passo anterior no menu da aplicação nos deixamos um item chamado "login" que servira pra redirecionar para uma tela que o usuário possa efetuar o login no twiter;
Para que essa parte da aplicação funcione precisamos registrar nossa aplicação no twitter; Acesse dev.twitter.com.
A aplicação deve ser to tipo Browser e a Callback URL informada, essa é uma das exigências do twitter, como nos vamos utilizar a URL do google( http://www.google.com ).
Apos o registro da aplicação o twitter retorna as url's necessárias para as transações.
Agora vamos montar a classe de tratamento que utiliza as dll's Hammock.WindowsPhone e ICSharpCode.SharpZipLib.WindowsPhone que disponibilizei na primeira parte deste tutorial.
oAuthHelper.cs
A idéia é utilizar o componente browser do wp7 para acessar a pagina de login da nossa aplicação que o twitter nos retorna, assim que o usuário informar login, senha de clicar no botão "Allow", assim que autenticação for feita nos vamos ocultar o browser e exibir em um ListBox os post do usuário e também disponibilizar a visualização de um TextBox e um botão para novos posts que serão feitos, deixando a tela mais ou menos assim:
Vamos criar as seguintes variáveis publicas no nosso InTwitter.axml.cs
Abaixo do metodo InitializeComponent(); que fica no construtor da classe vamos resgatar as nossas chaves que o twitter nos forneceu e faremos um tratamento das mesmas se estiver tudo ok vamos registrar um evento no browser e no botão de posts:
No evento AccessTokenQuery_QueryResponse tentamos armazenar os parâmetros na variável parameters, capturar os valores traves destes parâmetros e habilitar o menu para o usuário fazer o logoff do twitter.
No evento btnPostTweet_Click precisamos pegar todas as credenciais que foram preenchidas durante o processo dos outros eventos acima e enviar para o twitter e já receber os posts atualizados do usuário.
Podemos também criar um botão no menu do WP7 que atualize os post enviados pelo usuário e neste botão no invocamos o evento TweetButton_Click.
No evento wcTwitterTimeline_DownloadStringCompleted nos atualizamos nosso listbox de acordo com com as informações retornadas da API do twiter, que retorna um XML com os posts do usuário que esta logado na nossa aplicação .
No menu da aplicação podemos invocar o vento MenuItemSignOut_Click que limpara os dados do usuário logado e efetuar o redirecionamento para a tela principal da aplicação.
Se precisar entender melhor esta aplicação o download da mesma pode ser feito aqui lembrando que estou deixando esta aplicação preparada para para integração de outras redes sociais.
No passo anterior no menu da aplicação nos deixamos um item chamado "login" que servira pra redirecionar para uma tela que o usuário possa efetuar o login no twiter;
Para que essa parte da aplicação funcione precisamos registrar nossa aplicação no twitter; Acesse dev.twitter.com.
A aplicação deve ser to tipo Browser e a Callback URL informada, essa é uma das exigências do twitter, como nos vamos utilizar a URL do google( http://www.google.com ).
Apos o registro da aplicação o twitter retorna as url's necessárias para as transações.
Para conseguirmos buscar e enviar informações no twitter vamos utilizar a api de autorizaçao oAuth .
Agora vamos construir nossas classes com estas informações.
TwitterSettings.cs
using System; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; namespace WindowsPhoneApplication1 { public class TwitterSettings { 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"; public static string StatusUpdateUrl { get { return "http://api.twitter.com"; } } //#error Adicione as respectivas cheves do Twitter aqui public static string consumerKey = "consumerKey"; public static string consumerKeySecret = "consumerKeySecret"; public static string oAuthVersion = "1.0a"; } }pedido Token e secreto pedido token são conjunto temporário de credenciais que lhe permitem adquirir tokens de acesso OAuth. O token de acesso e secreto token de acesso são necessários para acessar os tweets de um usuário.
Agora vamos montar a classe de tratamento que utiliza as dll's Hammock.WindowsPhone e ICSharpCode.SharpZipLib.WindowsPhone que disponibilizei na primeira parte deste tutorial.
oAuthHelper.cs
using System; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using Hammock.Authentication.OAuth; using Hammock.Web; namespace WindowsPhoneApplication1 { public class oAuthHelper { internal static OAuthWebQuery GetRequestTokenQuery() { var oauth = new OAuthWorkflow { ConsumerKey = TwitterSettings.consumerKey, ConsumerSecret = TwitterSettings.consumerKeySecret, SignatureMethod = OAuthSignatureMethod.HmacSha1, ParameterHandling = OAuthParameterHandling.HttpAuthorizationHeader, RequestTokenUrl = TwitterSettings.RequestTokenUri, Version = TwitterSettings.oAuthVersion, CallbackUrl = TwitterSettings.CallbackUri }; var info = oauth.BuildRequestTokenInfo(WebMethod.Get); var objOAuthWebQuery = new OAuthWebQuery(info); objOAuthWebQuery.HasElevatedPermissions = true; objOAuthWebQuery.SilverlightUserAgentHeader = "Hammock"; objOAuthWebQuery.SilverlightMethodHeader = "GET"; return objOAuthWebQuery; } internal static OAuthWebQuery GetAccessTokenQuery(string requestToken, string RequestTokenSecret, string oAuthVerificationPin) { var oauth = new OAuthWorkflow { AccessTokenUrl = TwitterSettings.AccessTokenUri, ConsumerKey = TwitterSettings.consumerKey, ConsumerSecret = TwitterSettings.consumerKeySecret, ParameterHandling = OAuthParameterHandling.HttpAuthorizationHeader, SignatureMethod = OAuthSignatureMethod.HmacSha1, Token = requestToken, Verifier = oAuthVerificationPin, Version = TwitterSettings.oAuthVersion }; var info = oauth.BuildAccessTokenInfo(WebMethod.Post); var objOAuthWebQuery = new OAuthWebQuery(info); objOAuthWebQuery.HasElevatedPermissions = true; objOAuthWebQuery.SilverlightUserAgentHeader = "Hammock"; objOAuthWebQuery.SilverlightMethodHeader = "GET"; return objOAuthWebQuery; } } }Ok, agora que temos nessas classes para trabalho vamos montar uma tela (InTwitter.axml);
A idéia é utilizar o componente browser do wp7 para acessar a pagina de login da nossa aplicação que o twitter nos retorna, assim que o usuário informar login, senha de clicar no botão "Allow", assim que autenticação for feita nos vamos ocultar o browser e exibir em um ListBox os post do usuário e também disponibilizar a visualização de um TextBox e um botão para novos posts que serão feitos, deixando a tela mais ou menos assim:
string OAuthTokenKey = string.Empty; string tokenSecret = string.Empty; string accessToken = string.Empty; string accessTokenSecret = string.Empty; string userID = string.Empty; string userScreenName = string.Empty;
Abaixo do metodo InitializeComponent(); que fica no construtor da classe vamos resgatar as nossas chaves que o twitter nos forneceu e faremos um tratamento das mesmas se estiver tudo ok vamos registrar um evento no browser e no botão de posts:
accessToken = HelperMethods.GetKeyValue<string>("AccessToken"); accessTokenSecret = HelperMethods.GetKeyValue<string>("AccessTokenSecret"); userScreenName = HelperMethods.GetKeyValue<string>("ScreenName"); if (string.IsNullOrEmpty(accessToken) || string.IsNullOrEmpty(accessTokenSecret)) { var requestTokenQuery = oAuthHelper.GetRequestTokenQuery(); requestTokenQuery.RequestAsync(TwitterSettings.RequestTokenUri, null); requestTokenQuery.QueryResponse += new EventHandler<WebQueryResponseEventArgs>(requestTokenQuery_QueryResponse); } else { GetUserTimeLine(userScreenName); Dispatcher.BeginInvoke(() => { var tweetButton = (Microsoft.Phone.Shell.ApplicationBarIconButton)this.ApplicationBar.Buttons[0]; tweetButton.IsEnabled = true; PageTitle.Visibility = Visibility.Visible; listboxMyTimeline.Visibility = Visibility.Visible; txtBoxNewTweet.Visibility = Visibility.Visible; btnPostTweet.Visibility = Visibility.Visible; }); } webBrowser1.Navigated += new EventHandler<System.Windows.Navigation.NavigationEventArgs>(webBrowser1_Navigated); webBrowser1.Navigating += new EventHandler<NavigatingEventArgs>(webBrowser1_Navigating); btnPostTweet.Click += new RoutedEventHandler(btnPostTweet_Click);Nos evento requestTokenQuery_QueryResponse vamos tentar capturar autorização utilizando nossa chave OAuthTokenKey e acionar nosso browser passando a url de autorização.
void requestTokenQuery_QueryResponse(object sender, WebQueryResponseEventArgs e) { try { var parameters = HelperMethods.GetQueryParameters(e.Response); OAuthTokenKey = parameters["oauth_token"]; tokenSecret = parameters["oauth_token_secret"]; var authorizeUrl = TwitterSettings.AuthorizeUri + "?oauth_token=" + OAuthTokenKey; Dispatcher.BeginInvoke(() => { this.webBrowser1.Navigate(new Uri(authorizeUrl)); }); } catch (Exception ex) { Dispatcher.BeginInvoke(() => { MessageBox.Show(ex.Message); }); } }No evento webBrowser1_Navigating recebemos o resultado da autorização, armazenamos nossa web query na variavel AccessTokenQuery, registramos um enveto AccessTokenQuery_QueryResponse e utilizamos uma requisisão assincrona, disando o evento assim:
void webBrowser1_Navigating(object sender, NavigatingEventArgs e) { if (e.Uri.ToString().StartsWith(TwitterSettings.CallbackUri)) { var AuthorizeResult = HelperMethods.GetQueryParameters(e.Uri.ToString()); var VerifyPin = AuthorizeResult["oauth_verifier"]; this.webBrowser1.Visibility = Visibility.Collapsed; var AccessTokenQuery = oAuthHelper.GetAccessTokenQuery( OAuthTokenKey, tokenSecret, VerifyPin ); AccessTokenQuery.QueryResponse += new EventHandler<WebQueryResponseEventArgs>(AccessTokenQuery_QueryResponse); AccessTokenQuery.RequestAsync(TwitterSettings.AccessTokenUri, null); } }No evento webBrowser1_Navigated alteramos a visualização do browser e removemos o evento para o usuário ver seus posts
void webBrowser1_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e) { this.webBrowser1.Visibility = Visibility.Visible; this.webBrowser1.Navigated -= webBrowser1_Navigated; }
No evento AccessTokenQuery_QueryResponse tentamos armazenar os parâmetros na variável parameters, capturar os valores traves destes parâmetros e habilitar o menu para o usuário fazer o logoff do twitter.
void AccessTokenQuery_QueryResponse(object sender, WebQueryResponseEventArgs e) { try { var parameters = HelperMethods.GetQueryParameters(e.Response); accessToken = parameters["oauth_token"]; accessTokenSecret = parameters["oauth_token_secret"]; userID = parameters["user_id"]; userScreenName = parameters["screen_name"]; HelperMethods.SetKeyValue<string>("AccessToken", accessToken); HelperMethods.SetKeyValue<string>("AccessTokenSecret", accessTokenSecret); HelperMethods.SetKeyValue<string>("ScreenName", userScreenName); Dispatcher.BeginInvoke(() => { var AtualizarMenuItem = (Microsoft.Phone.Shell.ApplicationBarMenuItem)this.ApplicationBar.MenuItems[1]; AtualizarMenuItem.IsEnabled = true; }); GetUserTimeLine(userScreenName); } catch (Exception ex) { Dispatcher.BeginInvoke(() => { MessageBox.Show(ex.Message); }); } }
No evento btnPostTweet_Click precisamos pegar todas as credenciais que foram preenchidas durante o processo dos outros eventos acima e enviar para o twitter e já receber os posts atualizados do usuário.
void btnPostTweet_Click(object sender, RoutedEventArgs e) { if (txtBoxNewTweet.Text.Trim().Length == 0) { return; } var credentials = new OAuthCredentials { Type = OAuthType.ProtectedResource, SignatureMethod = OAuthSignatureMethod.HmacSha1, ParameterHandling = OAuthParameterHandling.HttpAuthorizationHeader, ConsumerKey = TwitterSettings.consumerKey, ConsumerSecret = TwitterSettings.consumerKeySecret, Token = this.accessToken, TokenSecret = this.accessTokenSecret, Version = "1.0" }; var restClient = new RestClient { Authority = TwitterSettings.StatusUpdateUrl, HasElevatedPermissions = true, Credentials = credentials, Method = WebMethod.Post }; restClient.AddHeader("Content-Type", "application/x-www-form-urlencoded"); var restRequest = new RestRequest { Path = "1/statuses/update.xml?status=" + txtBoxNewTweet.Text }; var ByteData = Encoding.UTF8.GetBytes(txtBoxNewTweet.Text); restRequest.AddPostContent(ByteData); restClient.BeginRequest(restRequest, new RestCallback(PostTweetRequestCallback)); }No evento PostTweetRequestCallback atualizamos o post do usuário utilizando o método GetUserTimeLine(usuário_logado).
private void PostTweetRequestCallback(RestRequest request, Hammock.RestResponse response, object obj) { GetUserTimeLine(userScreenName); }
Podemos também criar um botão no menu do WP7 que atualize os post enviados pelo usuário e neste botão no invocamos o evento TweetButton_Click.
private void TweetButton_Click(object sender, EventArgs e) { GetUserTimeLine(userScreenName); }No metodo GetUserTimeLine(usuario_logado) nos temos que registrar o evento wcTwitterTimeline_DownloadStringCompleted.
private void GetUserTimeLine(string userName) { WebClient wcTwitterTimeline = new WebClient(); wcTwitterTimeline.DownloadStringCompleted += new DownloadStringCompletedEventHandler(wcTwitterTimeline_DownloadStringCompleted); wcTwitterTimeline.DownloadStringAsync(new System.Uri("http://api.twitter.com/1/statuses/user_timeline.xml?screen_name=" + userName)); }
No evento wcTwitterTimeline_DownloadStringCompleted nos atualizamos nosso listbox de acordo com com as informações retornadas da API do twiter, que retorna um XML com os posts do usuário que esta logado na nossa aplicação .
void wcTwitterTimeline_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) { if (e.Error != null) { return; } XElement Tweets = XElement.Parse(e.Result); listboxMyTimeline.ItemsSource = from tweet in Tweets.Descendants("status") select new TwitterItem { UserName = tweet.Element("user").Element("screen_name").Value, Tweet = tweet.Element("text").Value, ImageSource = tweet.Element("user").Element("profile_image_url").Value }; Dispatcher.BeginInvoke(() => { listboxMyTimeline.Visibility = Visibility.Visible; txtBoxNewTweet.Visibility = Visibility.Visible; btnPostTweet.Visibility = Visibility.Visible; }); }
No menu da aplicação podemos invocar o vento MenuItemSignOut_Click que limpara os dados do usuário logado e efetuar o redirecionamento para a tela principal da aplicação.
private void MenuItemSignOut_Click(object sender, EventArgs e) { HelperMethods.SetKeyValue<string>("AccessToken", string.Empty); HelperMethods.SetKeyValue<string>("AccessTokenSecret", string.Empty); NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative)); }
Se precisar entender melhor esta aplicação o download da mesma pode ser feito aqui lembrando que estou deixando esta aplicação preparada para para integração de outras redes sociais.
Comments
Thank you!