HeyCHのブログ

慢性疲労のへいちゃんです

【C#】CoreTweetを使ってみよう その2

今回の記事は前回の記事の続きという事で書いていきます。
heych.hatenablog.com


今回は、Tokenの永続化と相互フォローツールについて書いてみようと思います。

まずはTokenの永続化

Tokenの永続化についてですが、昨日調べていたら「AccessToken」「AccessTokenSecret」を保存しておけば行けるような感じでした。
従って、認証用のウィンドウは必要なくなります。
そのため、サブウィンドウ化し、認証専用ウィンドウを作ります。

<Window x:Class="FollowerFollow.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:FollowerFollow"
        mc:Ignorable="d"
        Title="認証ウィンドウ" Height="162.333" Width="200">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="50"/>
            <RowDefinition Height="25"/>
            <RowDefinition Height="25"/>
            <RowDefinition Height="25"/>
        </Grid.RowDefinitions>
        <TextBox  Grid.Row="0" TextWrapping="WrapWithOverflow" IsReadOnly="True" Text="認証を押した後ブラウザで承認し、PINコードを設定してください。"/>
        <Button Grid.Row="1" Content="認証" Click="Button_Click"/>
        <TextBox Grid.Row="2" Text="{Binding PINCode,UpdateSourceTrigger=PropertyChanged}"/>
        <Button Grid.Row="3" Content="設定" Click="Button_Click_1"/>
    </Grid>
</Window>
  • OAuthWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using CoreTweet;
using static CoreTweet.OAuth;

namespace FollowerFollow {
    /// <summary>
    /// Window1.xaml の相互作用ロジック
    /// </summary>
    public partial class Window1 : Window {
        public ViewModel vm;
        public Window1() {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e) {
            vm.Session = OAuth.Authorize(Properties.Resources.ConsumerKey, Properties.Resources.ConsumerSecret);
            System.Diagnostics.Process.Start(vm.Session.AuthorizeUri.AbsoluteUri);
        }

        private void Button_Click_1(object sender, RoutedEventArgs e) {
            vm.Tokens = OAuth.GetTokens(vm.Session, vm.PINCode);
            Properties.Settings.Default.AccessToken = vm.Tokens.AccessToken;
            Properties.Settings.Default.AccessTokenSecret = vm.Tokens.AccessTokenSecret;
            Properties.Settings.Default.Save();
        }
    }
}
  • MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using CoreTweet;
using static CoreTweet.OAuth;

namespace FollowerFollow {
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window {
        ViewModel vm;
        public MainWindow() {
            InitializeComponent();
            vm = new ViewModel();
            this.DataContext = vm;
            try {
                if (!string.IsNullOrEmpty(Properties.Settings.Default.AccessToken)) {
                    vm.Tokens = Tokens.Create(Properties.Resources.ConsumerKey
                                            , Properties.Resources.ConsumerSecret
                                            , Properties.Settings.Default.AccessToken
                                            , Properties.Settings.Default.AccessTokenSecret);
                    Dictionary<string, object> ps = new Dictionary<string, object>();
                    ps.Add("screen_name", "twitter");
                    var users = vm.Tokens.Users.Lookup(ps);
                    if (users.Count == 0) throw new ApplicationException("Userが見つかりませんでした。");
                } else {
                    throw new ApplicationException("AccessTokenが設定されていません。");
                }
            } catch (Exception ex) {
                OAuthWindow ow = new OAuthWindow();
                ow.DataContext = vm;
                ow.vm = vm;
                ow.ShowDialog();
            }
        }
        private void Button_Click(object sender, RoutedEventArgs e) {
            vm.Tokens.Statuses.Update("test");
        }
    }
    public class ViewModel : INotifyPropertyChanged {
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string name) {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
        string _PINCode = "";
        public string PINCode {
            get { return _PINCode; }
            set {
                _PINCode = value;
                OnPropertyChanged("PINCode");
            }
        }
        public OAuthSession Session { get; set; }
        public Tokens Tokens { get; set; }
    }
}

フォローしてくれている人をフォローする

<Window x:Class="FollowerFollow.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:FollowerFollow"
        mc:Ignorable="d"
        Title="FollowerFollow" Height="300" Width="400">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="25"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Button Grid.Row="0" Content="フォローしてくれている人をフォローする" Click="Button_Click"/>
        <TextBox Grid.Row="1" x:Name="textBox1" AcceptsReturn="True" IsReadOnly="True"/>
    </Grid>
</Window>
  • MainWindow.xaml.cs

フォロワーを取得して、その中からフォローしていない人を探してフォローします。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using CoreTweet;
using static CoreTweet.OAuth;

namespace FollowerFollow {
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window {
        ViewModel vm;
        public MainWindow() {
            InitializeComponent();
            vm = new ViewModel();
            this.DataContext = vm;
            try {
                if (!string.IsNullOrEmpty(Properties.Settings.Default.AccessToken)) {
                    vm.Tokens = Tokens.Create(Properties.Resources.ConsumerKey
                                            , Properties.Resources.ConsumerSecret
                                            , Properties.Settings.Default.AccessToken
                                            , Properties.Settings.Default.AccessTokenSecret);
                    var res = vm.Tokens.Account.VerifyCredentials();
                    vm.Tokens.UserId = (long)res.Id;
                    Dictionary<string, object> ps = new Dictionary<string, object>();
                    ps.Add("screen_name", "twitter");
                    var users = vm.Tokens.Users.Lookup(ps);
                    if (users.Count == 0) throw new ApplicationException("Userが見つかりませんでした。");
                } else {
                    throw new ApplicationException("AccessTokenが設定されていません。");
                }
            } catch (Exception ex) {
                OAuthWindow ow = new OAuthWindow();
                ow.DataContext = vm;
                ow.vm = vm;
                ow.ShowDialog();
            }
        }
        private void Button_Click(object sender, RoutedEventArgs e) {
            var followers = vm.Tokens.Followers.EnumerateIds(EnumerateMode.Next, user_id => vm.Tokens.UserId);
            var users = vm.Tokens.Friendships.Lookup(followers);
            for (int i = 0; i < users.Count; i++) {
                var user = users[i];
                var c = user.Connections;
                if (c.Contains("followed_by") && !c.Contains("following")) {
                    vm.Tokens.Friendships.Create(user_id => user.Id);
                    textBox1.Text += user.Name+"さんをフォローしました。\r\n";
                }
            }
        }
    }
    public class ViewModel : INotifyPropertyChanged {
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string name) {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
        string _PINCode = "";
        public string PINCode {
            get { return _PINCode; }
            set {
                _PINCode = value;
                OnPropertyChanged("PINCode");
            }
        }
        public OAuthSession Session { get; set; }
        public Tokens Tokens { get; set; }
    }
}

GitHub - Hey-CH/FollowerFollow