알라딘MGG와이드바


C# 으로 만드는 간단한 Twitter 클라이언트 개발 이야기

[http]WPF 4.5 Unleashed 13장 Data Binding 에 있는 The Pure-XAML Twitter Client 를 만드는 예제가 있는데 Twitter API 가 1.0 에서 1.1 로 넘어가는 바람에 작동하지 않아 만든 토이 프로그램.(책에 있는 샘플코드는 [http]여기 에서 얻을 수 있다.)
oAuth 인증코드는 [http]여기를 참고했다.
oAuth 에 대해서는 [http]H3 2012 OAuth2 - API 인증을위한 만능 도구상자 - 박민우 를 참고한다.
트위터 API 는 [https]Application-only authentication 를 지원한다.
TwitterKey.ConsumerKey 와 TwitterKey.ConsumerSecret 는 https://dev.twitter.com/ 에 로그인한 뒤에 [https]여기 에서 App 을 하나 만들면 얻을 수 있다.
Json 파서는 [http]Newtonsoft.Json 를 사용했다. References 에 Newtonsoft.Json.dll 을 추가해야 한다.
user_timeline API 사용법은 [https]여기를 참고한다.

C# 코드

using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Windows;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
 
namespace TwitterViewer
{
    // Xaml 의 screenName 입력창과의 DataBinding
    public class ScreenName
    {
        public string Name { get; set; }
    }
 
    // Json 포멧의 response 로부터 bearer token 를 얻기 위한 클래스
    public class TwitAuthenticateResponse
    {
        public string token_type { get; set; }
        public string access_token { get; set; }
    }
 
    // Xaml 의 ListBox item 용 DataBinding
    public class TwitItem
    {
        public string created_at { get; set; }
        public string text { get; set; }
        public string user { get; set; }
        public string profile_image_url { get; set; }
    }
 
    public class TwitItems : ObservableCollection<TwitItem>
    {
    }
 
    public partial class MainWindow : Window
    {
        TwitItems _twitItems = new TwitItems();
 
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = _twitItems;  // ListBox 와의 DataBinding
            ConnectTwitter(twitScreenName.Text);
        }
 
        public void ConnectTwitter(string screenName)
        {
            _twitItems.Clear();
 
            // oAuth 인증코드는 아래 URL 을 참고
            // http://stackoverflow.com/questions/17067996/authenticate-and-request-a-users-timeline-with-twitter-api-1-1-oauth
 
            // Step 1: Encode consumer key and secret
            // Do the Authenticate. You need to set your own keys and screen name
            // Application-only authentication 방식이라 개인 인증하지 않아도 된다.
            // https://dev.twitter.com/docs/auth/application-only-auth 참고
            var authHeader = string.Format("Basic {0}",
                Convert.ToBase64String(
                    Encoding.UTF8.GetBytes(
                        Uri.EscapeDataString(TwitterKey.ConsumerKey)
                        + ":"
                        + Uri.EscapeDataString((TwitterKey.ConsumerSecret))
                    )
                )
            );
 
            // Step 2: Obtain a bearer token
            HttpWebRequest authRequest = (HttpWebRequest)WebRequest.Create("https://api.twitter.com/oauth2/token");
            authRequest.Headers.Add("Authorization", authHeader);
            authRequest.Method = "POST";
            authRequest.ContentType = "application/x-www-form-urlencoded;charset=UTF-8";
            authRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
            using (Stream stream = authRequest.GetRequestStream())
            {
                var postBody = "grant_type=client_credentials";
                byte[] content = ASCIIEncoding.ASCII.GetBytes(postBody);
                stream.Write(content, 0, content.Length);
            }
 
            authRequest.Headers.Add("Accept-Encoding", "gzip");
 
            // deserialize into an object
            TwitAuthenticateResponse twitAuthResponse;
            using (WebResponse authResponse = authRequest.GetResponse())
            {
                using (var reader = new StreamReader(authResponse.GetResponseStream()))
                {
                    var objectText = reader.ReadToEnd();
                    twitAuthResponse = JsonConvert.DeserializeObject<TwitAuthenticateResponse>(objectText);
                }
            }
 
            // Step 3: Authenticate API requests with the bearer token and Do the timeline
            var timelineFormat = "https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name={0}&include_rts=1&exclude_replies=1&count=50";
            var timelineUrl = string.Format(timelineFormat, screenName);
            HttpWebRequest timeLineRequest = (HttpWebRequest)WebRequest.Create(timelineUrl);
            timeLineRequest.Headers.Add("Authorization", string.Format("{0} {1}", twitAuthResponse.token_type, twitAuthResponse.access_token));
            timeLineRequest.Method = "Get";
            JArray twitterLines;
            using (WebResponse timeLineResponse = timeLineRequest.GetResponse())
            {
                using (var reader = new StreamReader(timeLineResponse.GetResponseStream()))
                {
                    twitterLines = JArray.Parse(reader.ReadToEnd());
                }
            }
 
            // Json 은 http://james.newtonking.com/json 를 참고
            // Newtonsoft.Json.dll 을 References 에 추가해야 한다.
            IList<TwitItem> twitList = twitterLines.Select(p => new TwitItem
            {
                created_at = (string)p["created_at"],
                text = (string)p["text"],
                user = (string)p["user"]["name"],
                profile_image_url = (string)p["user"]["profile_image_url"]
            }).ToList();
            twitList.ToList().ForEach(_twitItems.Add);
        }
 
        private void OnButtonCrawling(object sender, RoutedEventArgs e)
        {
            ConnectTwitter(twitScreenName.Text);
        }
    }
}


Xaml 코드



<Window x:Class="TwitterViewer.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:my="clr-namespace:TwitterViewer"
        Title="TwitterViewer" Height="350" Width="525">
    <Grid>
        <Grid.Resources>
            <my:ScreenName x:Key="screenName" Name="rigmania"/>
        </Grid.Resources>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <ListBox Grid.Row="0" x:Name="twitList"
                 ItemsSource="{Binding}"
                 ScrollViewer.HorizontalScrollBarVisibility="Disabled">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <DockPanel>
                        <Image DockPanel.Dock="Left"
                               Source="{Binding Path=profile_image_url}" Height="50"/>
                        <DockPanel DockPanel.Dock="Top" >
                            <TextBlock DockPanel.Dock="Left" Text="{Binding Path=user}"/>
                            <TextBlock DockPanel.Dock="Left" Text="{Binding Path=created_at}"/>
                        </DockPanel>
                        <TextBlock DockPanel.Dock="Top"
                                   TextWrapping="Wrap"
                                   Text="{Binding Path=text}"/>
                    </DockPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <DockPanel Grid.Row="1">
            <TextBlock>Input TwitterUserName : </TextBlock>
            <TextBox x:Name="twitScreenName"
                     Text="{Binding Name, Source={StaticResource screenName}, Mode=TwoWay}"
                     DockPanel.Dock="Left" Width="200"/>
            <Button DockPanel.Dock="Left" Click="OnButtonCrawling">Crawling</Button>
        </DockPanel>
    </Grid>
</Window>


결과물


TwitterView


덧글

댓글 입력 영역


Yes24위대한게임의탄생3

위대한 게임의 탄생 3
예스24 | 애드온2