C#でtwitterizerをつかってみた2 Twitterizerを使ったMyTwitterToolsクラス[.NET][C#][twitterizer][twitterAPI]

前回の記事では、ソースコードを一部しか貼りませんでしたが、
せっかくなので、MyTwitterToolsクラスの全文を貼っときます。
(結構、書きかけの草案や間違ってるところも多いので、期待通り通り動かなかったらすみません。。)

using System;
using System.Collections.Generic;
using System.Text;

// Twitterizerライブラリを使っている
using Twitterizer;
// Process.Start()メソッドのため
using System.Diagnostics; 

// MyToolsクラスを使っている
using everyonecancreate.Game;

// Windows.Forms依存にしたくない時はコメントアウト+修正
using System.Windows.Forms;
using System.Drawing;
using System.Net;
using System.IO; 

namespace everyoneCanCreate.Twitter
{
    /// <summary>
    /// Twitter関連処理を(日本語付きメソッドなどで)簡単に扱えるようにしたstaticメソッドを集めたクラスです。
    /// 私のTwitterクラス、みたいな感じで、自分流に改良してってください。
    /// 
    /// ※推奨事項。TwitterAPIや関連ライブラリがバージョンアップなどで変更になった場合、
    /// いちいちたくさんのクラスを書き変えるのは面倒です。
    /// TwitterAPIを使う処理はこのクラスだけにして、いざというときはここだけ変更すればいいようにしておきましょう。
    /// </summary>
    public class MyTwitterTools
    {

        /// <summary>
        /// Twitter関連処理を行うプログラムのトークン作成に必要なキーです。
        /// 
        /// 普通は、Twitte開発者向けページr https://dev.twitter.com/ で作成したConsumer keyなどをここに代入して使ってください。
        /// 
        /// (トークンとは、例えばbotを作る場合、定期的につぶやくロボット君を作成するために必要な部品(キーパーツ)のことと思えばわかりやすい?)
        /// </summary>
        private static string p_Consumer_key = "自分で取得したのを入れてね";      // 必ず必要。
        private static string p_Consumer_secret = "自分で取得したのを入れてね";   // 必ず必要。
        private static string p_Access_token = "自分で取得したのを入れてね";      // twitterクライアントなどの場合は、ユーザにPINコードなどを入力させてから作成するから、空白でもよい。botの場合は必要。
        private static string p_Access_secret = "自分で取得したのを入れてね";     // twitterクライアントなどの場合は、ユーザにPINコードなどを入力させてから作成するから、空白でもよい。botの場合は必要。

        /// <summary>
        /// OAuthで識別したトークンです。つぶやき投稿など、いろんな時に使います。
        /// 
        /// (トークンとは、例えばbotを作る場合、定期的につぶやくロボット君を作成するために必要な部品(キーパーツ)のことと思えばわかりやすい?)
        /// 
        /// ※値は、基本的には、static変数であるp_Consumer_keyなどに自分のTwitterアプリの値を代入していれば、
        /// 勝手に_initメソッドが呼びだされて、トークンが作成されています。
        /// ただし、取得できなかった場合は、nullが入っているかもしれないので、一応nullじゃないかは確認した方がいいかも。
        /// </summary>
        private static OAuthTokens p_token = init・初期化(p_Consumer_key, p_Consumer_secret, p_Access_token, p_Access_secret);

        public static bool p_isUseDictionary・TwitterAPI実行数削減のために辞書を使うか = true;
        /// <summary>
        /// 今までTwitterUser.Show(@からはじまるtwitterID)したTwitterUserクラスのインスタンスを格納している辞書です。
        /// 
        /// TwitterAPI実行数削減のために、同じtwitterIDのユーザのデータを取得するときに使用します。
        /// </summary>
        private static Dictionary<string, TwitterUser> p_showedTwitterUserList・今まで検索したユーザの辞書 = new Dictionary<string, TwitterUser>();

        /// <summary>
        /// コンストラクタです。このクラスは、基本的にはstaticメソッドとして使うので、あまり使いません。
        /// 詳しくはHELP・このクラスの使い方のヘルプ()メソッドなどをみてください。
        /// </summary>
        public MyTwitterTools()
        {

        }
        /// <summary>
        /// 自分のタイムラインを引数で指定した数だけ、取得します。
        /// 返り値_timelineはTwitterStatusCollectionクラスです。
        /// 配列やリストと同じように、_timeline[配列].***で指定した配列のツイートを参照できます。
        /// </summary>
        /// <param name="_timeLineCount・取得するツイート数"></param>
        /// <returns></returns>
        public static TwitterStatusCollection getTimeLine・タイムラインを取得(int _timeLineCount・取得するツイート数)
        {
            TwitterStatusCollection _timeline = null;
            TimelineOptions options = new TimelineOptions()
            {
                //ホームタイムラインの取得する行を5行に設定する
                Count = _timeLineCount・取得するツイート数
            };

            //ホームタイムライン(p_tokenを持つアカウントの、自分のタイムライン)を取得する
            TwitterResponse<TwitterStatusCollection> _res = TwitterTimeline.HomeTimeline(p_token, options);
            if (_res.Result == RequestResult.Success)
            {
                _timeline = _res.ResponseObject;
            }
            else
            {
                checkError・エラー処理("タイムライン取得時のエラーです。", _res.ErrorMessage);
            }
            return _timeline;
        }
        /// <summary>
        /// ユーザのサムネイル画像を取得します。
        /// 
        /// ※まだ動くか確認してません。
        /// </summary>
        /// <param name="_twitterID_アットマークで始まるやつ"></param>
        /// <returns></returns>
        public static Image getUserImage・ユーザのサムネイル画像を取得(string _twitterID_アットマークで始まるやつ)
        {
            Image _image = null;
            TwitterResponse<TwitterUser> _res = TwitterUser.Show(_twitterID_アットマークで始まるやつ);
            if (_res.Result == RequestResult.Success)
            {
                TwitterUser _user = _res.ResponseObject;
                string _uri = _user.ProfileImageLocation;
                WebRequest _request = WebRequest.Create(_uri);
                Stream _fileStream = _request.GetRequestStream();
                _image = Image.FromStream(_fileStream);
            }
            return _image;
        }

        #region ツイート検索  検索メソッドは何を返すべきかか迷うので、まだちゃんと実装していない
        //public static bool serchTweet・ツイート検索(string _serchingText・検索文字列)
        //{
        //    TwitterResponse<TwitterSearchResultCollection> res = TwitterSearch.Search(_serchingText・検索文字列);
        //    if (res.Result == RequestResult.Success)
        //    {
        //        TwitterSearchResultCollection results = res.ResponseObject;

        //        for (int i = 0; i < results.Count; i++)
        //        {
        //            string msg = results[i].Text;
        //            msg += "\r\n";
        //            msg += "UserID : " + results[i].FromUserId + "\r\n";
        //            msg += "&#8212;&#8211;\r\n";
        //            MyTools.showMessage_ConsoleLine("とりあえず検索結果はリスト毎:"+msg);
        //        }
        //        return true;
        //    }
        //    else
        //    {
        //        checkError・エラー処理("「"+_serchingText・検索文字列+"」検索中のエラーです。", res.ErrorMessage);
        //        return false;
        //    }
        //}
        #endregion

        /// <summary>
        /// tweetの代わりにメッセージボックスで内容を表示します。テストなのにtwitterAPIに迷惑かけちゃ…心が痛むからね。本番ではちゃんとfalseにするのを忘れないでね。
        /// </summary>
        private static bool p_isTest・テスト用にツイッターで投稿する代わりにメッセージボックスに表示するか = true;
        /// <summary>
        /// 引数の文字列を新しくつぶやきます。エラーが起こるとfalseを返します。
        /// 
        ///  ・・・やり方は、ここなどを参考。特に非同期のつぶやき投稿方法。感謝
        ///  http://www.satsukifactory.net/twitter/twitter-client/twitterizer-asyncmemo/
        /// </summary>
        /// <param name="_newTweetText・つぶやくツイート内容_140文字以内じゃないと切れちゃうよ"></param>
        /// <returns></returns>
        public static bool tweet・つぶやく(string _newTweetText・つぶやくツイート内容_140文字以内じゃないと切れちゃうよ)
        {
            bool _isSuccess = false;
            string _tweet = _newTweetText・つぶやくツイート内容_140文字以内じゃないと切れちゃうよ;

            //ステータスラベルにポスト中の旨を表示
            //toolStripStatusLabel1.Text = "Posting...";

            //ポストする際のオプション指定。ここではSSLを使用しないように設定。
            StatusUpdateOptions _option = new StatusUpdateOptions();
            _option.UseSSL = false;

            // 以下、同期処理
            if (p_isTest・テスト用にツイッターで投稿する代わりにメッセージボックスに表示するか == false)
            {
                TwitterResponse<TwitterStatus> _result = TwitterStatus.Update(p_token, _tweet, _option);
                if (_result.Result == RequestResult.Success)
                {
                    MessageBox.Show("つぶやき投稿に成功したよ\n内容:"+_tweet, "確認", MessageBoxButtons.OK, MessageBoxIcon.None); //ダイアログを表示
                    _isSuccess = true;
                }
                else
                {
                    checkError・エラー処理("つぶやき投稿に失敗したよ。", _result.ErrorMessage);
                    _isSuccess = false;
                    
                }
            }
            else
            {
                MessageBox.Show("つぶやき投稿をテストでここに表示してるよ。\n内容:" + _tweet + "\n\n(twitterAPIに負荷与えないように配慮するなんて、君は偉いね。尊敬するよ。)", "確認", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }

            #region 非同期処理の草案( TwitterStatusAsyncが認識しない。新しいバージョンのtwitterizerでは認識しなくなった?)
            //IAsyncResult aresult = TwitterStatusAsync.Update(tokens, _tweet, option,new TimeSpan(0, 1, 0), res =>
            //{
            //    if (res.Result == RequestResult.Success)
            //    {
            //       BeginInvoke(new Action(() =>
            //       {
            //          toolStripStatusLabel1.Text = "PostingSuccess!"; //ラベルの表示を変更
            //         MessageBox.Show("投稿成功!", "確認", MessageBoxButtons.OK, MessageBoxIcon.None); //ダイアログを表示
            //        }));
            //     }
            //     else
            //     {
            //        BeginInvoke(new Action(() =>
            //        {
            //          toolStripStatusLabel1.Text = "Error!";
            //          MessageBox.Show("失敗したよ", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
            //         }));
            //      }
            //});
            #endregion

            return _isSuccess;
        }
        /// <summary>
        /// TwitterResponse.Result != Success だったとき、一貫してこのメソッドを呼び出してください。
        /// そうすると、エラー処理の個所をひとつにまとめられます。
        /// </summary>
        /// <param name="_ShownMessage・表示したいメッセージ"></param>
        /// <param name="_details・詳細エラーメッセージ_TwitterResponse_ErrorMessage"></param>
        /// <returns></returns>
        public static bool checkError・エラー処理(string _ShownMessage・表示したいメッセージ, string _details・詳細エラーメッセージ_TwitterResponse_ErrorMessage)
        {
            MessageBox.Show("【エラー】"+_ShownMessage・表示したいメッセージ+"\n\n詳細:" + _details・詳細エラーメッセージ_TwitterResponse_ErrorMessage, "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
            
            // 以下、エラーの内容によって、よくはまる事例をまとめてくれているサイト。感謝。 http://oresta.blog66.fc2.com/blog-entry-22.html
            
            // よくある、"Status is a duplicate."エラーは重複。Twitterでは同じ発言を繰り返し投稿できません。少なくとも10ツイートはあける必要があります。 http://www26.atwiki.jp/easybotter_wiki/pages/21.html 

            return true;
        }


        public static int getFollowerID・フォロワーのIDを取得(int _twitterID, int _folowerNo・何番目のフォロワーか)
        {
            int _followerID = 0;
            return _followerID;
        }
        /// <summary>
        ///  フォロワー(フォローされている人)のtwitterID(@ではじまるやつ)リストを取得します。
        ///  
        /// ※現時点では、不安定です。
        /// </summary>
        /// <param name="_twitterID_アットマークで始まる英数字や記号のやつ_TwitterUser_Name"></param>
        /// <returns></returns>
        public static List<Decimal> getFollowerTwitterUserIDs・フォロワーの識別数値IDを全て取得_高速版(string _twitterID_アットマークで始まる英数字や記号のやつ_TwitterUser_Name)
        {
            string _twitterId = _twitterID_アットマークで始まる英数字や記号のやつ_TwitterUser_Name;
            List<Decimal> _followers_TwitterUserIDs = new List<Decimal>();

            // この処理だと、一回に5000フォロワーしか呼びだせない
            //TwitterResponse<UserIdCollection> _userResponce = TwitterFriendship.FollowersIds(p_token);
            //UserIdCollection _users = _userResponce.ResponseObject;

            // 参考: http://ameblo.jp/funlife-v-v/entry-11388989280.html
            //TwitterFriendship.FollowersIdsは一度に5000件しか取得できません。
            //5000件以上フォロワーがいる場合は困ってしまいます。
            // 
            //そこでUserIdsOptionsを利用してやります。
            // 
            //UserIdsOptions.Cursorに、UserIdCollection.NextCursorを指定して
            //再度TwitterFriendship.FollowersIdsを実行します。
            // 
            //こんな感じです。	
            Decimal _userId = getUserID_ByTwitterID_UserName・twitterIDからユーザIDを取得(_twitterId);
            UsersIdsOptions _options = new UsersIdsOptions()
            {
                UserId = _userId
            };
            // 取れなくなるまで調べる
            while (true)
            {
                // とりあず5000個まで呼びだす
                // TwitterResponse<UserIdCollection> _users =TwitterFriendship.FollowersIds(p_token, _options);
                // var _users =TwitterFriendship.FollowersIds(p_token, _options);
                // TwitterResponse<UserIdCollection>とvarは表記が違うだけで、内部的にはいっしょ?
                // これ(TwitterFriendship.Followers)だと100人ずつしか呼びだせないみたい。しかもかなり時間がかかる。
                TwitterResponse<UserIdCollection> _res = TwitterFriendship.FollowersIds(p_token, _options);
                // リストに追加
                if (_res.Result == RequestResult.Success)
                {
                    int _idsCount = _res.ResponseObject.Count;
                    for (int i = 0; i < _idsCount; i++)
                    {
                        _followers_TwitterUserIDs.Add(_res.ResponseObject[i]);
                    }
                    // まだあるか調べる
                    UserIdCollection obj = _res.ResponseObject;
                    // 先頭に戻るとCursorが0となる
                    if ((_options.Cursor = obj.NextCursor) == 0)
                    {
                        // おわった〜
                        break;
                    }
                    // まだあるから、もっかい実行
                }
                else
                {
                    // もうないか、失敗したかやから、おわり
                    break;
                }
            }


            return _followers_TwitterUserIDs;

        }
        /// <summary>
        ///  フォロワー(フォローされている人)のtwitterID(@ではじまるやつ)リストを取得します。
        ///  
        /// </summary>
        /// <param name="_twitterID_アットマークで始まる英数字や記号のやつ_TwitterUser_Name"></param>
        /// <returns></returns>
        public static List<string> getFollowerID・フォロワーのIDを全て取得(string _twitterID_アットマークで始まる英数字や記号のやつ_TwitterUser_Name)
        {
            string _twitterId = _twitterID_アットマークで始まる英数字や記号のやつ_TwitterUser_Name;
            List<string> _followerTwitterIDs = new List<string>();

            // 現状では、数値IDをリストで取得した後、一個一個を数値ID→文字列twitterIDに変換してる
            List<Decimal> _userIds = getFollowerTwitterUserIDs・フォロワーの識別数値IDを全て取得_高速版(_twitterId);
            foreach (Decimal _id in _userIds)
            {
                _twitterId = getTwitterID_ByUserID・ユーザIDからTwitterIDを取得(_id);
                _followerTwitterIDs.Add(_twitterId);
            }

            return _followerTwitterIDs;

            #region 草案メモ。TwitterFriendship.FollowersIdsはループを回しても正常に動かない。
            //Decimal _userId = getUserID_ByTwitterID_UserName・twitterIDからユーザIDを取得(_twitterId);
            //FollowersOptions _options = new FollowersOptions()
            //{
            //    UserId = _userId
            //};
            //// 取れなくなるまで調べる(ものすごく不安定)
            //while(true){
            //    // とりあず5000個まで呼びだす
            //    // TwitterResponse<UserIdCollection> _users =TwitterFriendship.FollowersIds(p_token, _options);
            //    // var _users =TwitterFriendship.FollowersIds(p_token, _options);
            //    // TwitterResponse<UserIdCollection>とvarは表記が違うだけで、内部的にはいっしょ?
            //    // これ(TwitterFriendship.Followers)だと100人ずつしか呼びだせないみたい。しかもかなり時間がかかる。
            //    TwitterResponse<TwitterUserCollection> _res = TwitterFriendship.Followers(p_token, _options);
            //    // リストに追加
            //    if (_res.Result == RequestResult.Success)
            //    {
            //        int _idsCount = _res.ResponseObject.Count;
            //        for(int i=0; i<_idsCount; i++){
            //            _followerIDs.Add(_res.ResponseObject[i].Name);
            //        }
            //            // まだあるか調べる
            //            TwitterUserCollection obj = _res.ResponseObject;
            //            // 先頭に戻るとCursorが0となる
            //            if ((_options.Cursor = obj.NextCursor) == 0)
            //            {
            //                // おわった〜
            //                break;
            //            }
            //            // まだあるから、もっかい実行
            //    }else{
            //        // もうないか、失敗したかやから、おわり
            //        break;
            //    }
            //}
            //return _folloerIDs; 
            #endregion
        }

        public static bool isProtectedUser・ロックされているユーザIDか(string _twitterID_アットマークで始まる英数字のやつ_TwitterUser_Name)
        {
            TwitterResponse<TwitterUser> _userResponce = TwitterUser.Show(_twitterID_アットマークで始まる英数字のやつ_TwitterUser_Name);
            TwitterUser _user = _userResponce.ResponseObject;
            return _user.IsProtected;
        }
        /// <summary>
        /// TwitterID(User.Name:@で始まる英数字記号のユニークな文字列)からニックネーム(表示名:ScreenName)を取ってきます。
        /// </summary>
        /// <param name="_twitterUserScreenName"></param>
        /// <returns></returns>
        public static string getNickName・ニックネームを取得(string _twitterID_アットマークで始まる英数字のやつ_TwitterUser_Name)
        {
            string _userNickName = "";
            // ユーザID・名を取得するために必要な処理
            // TwitterResponseはジェネリック対応クラス。List<string>などのように各型に変換して使う。賢い!
            TwitterResponse<TwitterUser> _userResponce = TwitterUser.Show(_twitterID_アットマークで始まる英数字のやつ_TwitterUser_Name);
            if (_userResponce.Result == RequestResult.Success)
            {
                TwitterUser _user = _userResponce.ResponseObject;
                _userNickName = _user.ScreenName;
            }
            else
            {
                checkError・エラー処理("twitterID(@***、TwitterUser.Name)からニックネーム(TwitterUser.ScreenName)取得時のエラーです。", _userResponce.ErrorMessage);
            }
            return _userNickName;
        }
        /// <summary>
        /// ニックネーム(表示名:ScreenName)からTwitterID(User.Name:@で始まる英数字記号のユニークな文字列)を取ってきます。
        /// </summary>
        /// <param name="_twitterUserScreenName"></param>
        /// <returns></returns>
        public static string getTwitterID_ByScreenName・ニックネームからTwitterIDを取得(string _twitterUserScreenName)
        {
            TwitterResponse<TwitterUser> _userResponce = TwitterUser.Show(_twitterUserScreenName);
            TwitterUser _user = _userResponce.ResponseObject;
            return _user.Name; // これがTwitterID
            // return Decimal.ToInt32(_user.Id); // これはDecimal型(数値)のid。内部ではよく使うがユーザに意識させても頭がこんがらがると思うから使わない。キャストもややこしいし。
        }
        /// <summary>
        /// ※内部メソッドです。このクラスではよく使われます。
        /// 名前がややこしいので、他のクラスからは使わないことをおススメします。
        /// 
        /// 「@twitterID」のtwitterID(TwitterUser.Name)から、twitterAPIでユーザを識別するのに使われるDecimal型のTwitterUser.Idを取得します。
        /// 見つからなかったら0を返します。
        /// </summary>
        /// <param name="_twitterID・"></param>
        /// <returns></returns>
        private static Decimal getUserID_ByTwitterID_UserName・twitterIDからユーザIDを取得(string _twitterID_アットマークで始まる英数字のやつ_TwitterUser_Name)
        {
            Decimal _userId = 0; // 見つからなかったら0
            TwitterResponse<TwitterUser> _res = TwitterUser.Show(_twitterID_アットマークで始まる英数字のやつ_TwitterUser_Name);
            if (_res == null) return _userId;
            if (_res.Result == RequestResult.Unknown) return _userId;
            if (_res.Result == RequestResult.Success)
            {
                TwitterUser _user = _res.ResponseObject;
                _userId = _user.Id;
            }
            else
            {
                checkError・エラー処理("twitterIDからユーザID(TwitterUser.Id)取得中のエラーです。", _res.ErrorMessage);
            }
            return _userId;
        }
        /// <summary>
        /// ※内部メソッドです。このクラスではよく使われます。
        /// 名前がややこしいので、他のクラスからは使わないことをおススメします。
        /// 
        /// twitterAPIでユーザを識別するのに使われるDecimal型のTwitterUser.Idから、「@twitterID」のtwitterID(TwitterUser.Name)を取得します。
        /// 見つからなかったら""を返します。
        /// </summary>
        /// <param name="_twitterID・"></param>
        /// <returns></returns>
        private static string getTwitterID_ByUserID・ユーザIDからTwitterIDを取得(decimal _userId_Decimal型の数値ユーザID_TwitterUser_Id)
        {
            string _twitterId = "";
            TwitterResponse<TwitterUser> _res = TwitterUser.Show(_userId_Decimal型の数値ユーザID_TwitterUser_Id);
            if (_res == null) return _twitterId;
            if (_res.Result == RequestResult.Unknown) return _twitterId;
            if (_res.Result == RequestResult.Success)
            {
                TwitterUser _user = _res.ResponseObject;
                _twitterId = _user.Name;
            }
            else
            {
                checkError・エラー処理("ユーザID(TwitterUser.Id)からTwitterID(TwitterUser.Name)取得時のエラーです、", _res.ErrorMessage);
            }
            return _twitterId;
        }




        /// <summary>
        /// 初期化処理をしたか
        /// </summary>
        private static bool p_isInitialed = false;
        /// <summary>
        /// 初期化処理です。p_token取得のため、このクラスが使われる前に自動的に呼びだされるようにしています。
        /// 
        /// OAuth用トークンp_tokenを更新します。
        /// 
        /// 引数3・4のAccess token、Access secretのどちらかが""の場合は、別途ブラウザを開き、ユーザにPINコードを入力させて取得します。
        /// </summary>
        /// <param name="_Consumer_key">Twitte開発者向けページr https://dev.twitter.com/ で作成したConsumer key</param>
        /// <param name="_Consumer_secret">Twitte開発者向けページr https://dev.twitter.com/ で作成したConsumer secret</param>
        /// <param name="_Access_token">Acces token。ツイッターにアクセスした対象を識別するIDみたいなもの。botなどなら同じくTwitter開発者向けページで作成したものを使う。ユーザがつぶやくなら""にして、乱数などで新しく作成して作ってもいい</param>
        /// <param name="Access_secret">おなじく、Acces secret。Acces tokenと意味は同じ。</param>
        private static OAuthTokens init・初期化(string _Consumer_key, string _Consumer_secret, string _Access_token, string _Access_secret)
        {
            if (p_Consumer_key == "" || p_Consumer_secret == "")
            {
                MessageBox.Show("プログラム上で、Consumer keyか、Consumer secretが入力されていません。\nMyTwitterTools.p_Consumer keyと、p_Consumer secretに、\nTwitte開発者向けページ https://dev.twitter.com/ で作成したConsumer keyとConsumer secretを入力しているか、確認してください。\n終了します。\nご迷惑をおかけして、申し訳ありません。");
                Application.Exit();
                return null;
            }
            else if (_Consumer_key == "" || _Consumer_secret == "")
            {
                MessageBox.Show("プログラム上で、Consumer keyか、Consumer secretに\"\"を代入しようとしています。MyTwitterTools.init・初期化(...)メソッドの引数を確認してください。終了します。\nご迷惑をおかけして、申し訳ありません。");
                Application.Exit();
                return null;
            }
            if (_Access_token == "" || _Access_secret == "")
            {

                // アクセストークンを取得するために、ブラウザを立ち上げて認証ページを表示させる。
                OAuthTokenResponse req =
                        OAuthUtility.GetRequestToken(_Consumer_key, _Consumer_secret, "oob");
                // これをすると、ツイッターの認証画面が出て、トークン「(英数字数ケタ)」が表示される。
                System.Diagnostics.Process.Start(OAuthUtility.BuildAuthorizationUri(req.Token).ToString());

                // ユーザにキーを入力させる。
                string _pincode = MyTools.showInputBox("ブラウザに表示されている、PINコードを入力してください", "", "");
                OAuthTokenResponse res = null;
                // [Q]PINコードが間違ってた時の処理はかかなくてええのん?
                try
                {
                    // トークンを取ってくる
                    res = OAuthUtility.GetAccessToken(_Consumer_key, _Consumer_secret, req.Token, _pincode);
                }
                catch (Exception e)
                {
                    MessageBox.Show("PINコードが間違っているか、サーバにエラーが起きました。終了します。\nご迷惑をおかけして、申し訳ありません。");
                    Application.Exit();
                    return null;
                }
                if (res == null)
                {
                    MessageBox.Show("PINコードが間違っているか、サーバにエラーが起きました。終了します。\nご迷惑をおかけして、申し訳ありません。");
                    Application.Exit();
                    return null;
                }
                else
                {
                    // 認証情報を OAuthTokens に格納する。
                    _Access_token = res.Token;
                    _Access_secret = res.TokenSecret;
                }
            }
            // トークンを作成する情報が整った。

            // トークン情報を更新
            p_Consumer_key = _Consumer_key;
            p_Consumer_secret = _Consumer_secret;
            p_Access_token = _Access_token;
            p_Access_secret = _Access_secret;
            //HTTP_OAuth_Consumer_Request
            // OAuthのトークンを新しく作成
            OAuthTokens _token = new OAuthTokens
            {
                ConsumerKey = p_Consumer_key,
                ConsumerSecret = p_Consumer_secret,
                AccessToken = p_Access_token,
                AccessTokenSecret = p_Access_secret
            };

            p_isInitialed = true;

            return _token;
        }

        /// <summary>
        /// PINコードをユーザに入力させてツイッター認証し、トークンp_tokenを更新します。
        /// ほぼ http://www.satsukifactory.net/twitter/twitter-client/twitterizer-gettoken/ のコピペです。感謝。
        /// </summary>
        /// <returns></returns>
        public static bool makeUserDoTwitterRecognization・PINコードをユーザに入力させてツイッター認証()
        {
            //コンシューマーキー・コンシューマーシークレットの設定
            //const string consumerkey = "Your Consumerkey";
            //const string consumersecret = "Your Consumersecret";

            //リクエストトークンの取得
            OAuthTokenResponse oatr = OAuthUtility.GetRequestToken(p_Consumer_key, p_Consumer_secret, "oob"); //第三引数はよくわかんないけど、oobらしい

            //認証画面へ誘導(ブラウザを開く)
            Uri uri = Twitterizer.OAuthUtility.BuildAuthorizationUri(oatr.Token);
            Process.Start(uri.ToString());

            //PINコード入力画面を表示
            //inputPin pin = new inputPin();
            //pin.ShowDialog();
            //PINコードで認証
            //string pincode = pin.textBox1.Text;
            
            // ↑はいちいちフォームを作成するのが面倒だから、VisualBasicのInputBoxをつかっちゃおう
            string pincode = MyTools.showInputBox("ブラウザに表示されている、PINコードを入力してください", "認証", "");

            OAuthTokenResponse res;
            // [Q]PINコードが間違ってた時の処理はかかなくてええのん?
            try
            {
                res = OAuthUtility.GetAccessToken(p_Consumer_key, p_Consumer_secret, oatr.Token, pincode);
            }
            catch(Exception e)
            {
                MessageBox.Show("PINコードが間違っているか、サーバにエラーが起きました。終了します。\nご迷惑をおかけして、申し訳ありません。");
                return false;
            }
            if (res == null)
            {
                MessageBox.Show("PINコードが間違っているか、サーバにエラーが起きました。終了します。\nご迷惑をおかけして、申し訳ありません。");
                return false;
            }else{
                // static変数へ格納
                p_Access_token = res.Token;
                p_Access_secret = res.TokenSecret;

                // OAuthのトークンを新しく作成
                OAuthTokens _token = new OAuthTokens();
                _token.ConsumerKey = p_Consumer_key;
                _token.ConsumerSecret = p_Consumer_secret;
                _token.AccessToken = p_Access_token;
                _token.AccessTokenSecret = p_Access_secret;
                p_token = _token;

                //認証が完了した旨を知らせる
                System.Windows.Forms.MessageBox.Show("認証完了!", "確認", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Information);

            }

            return true;
        }


        #region ヘルプメソッド



        /// <summary>
        /// このクラスのヘルプです。
        /// 
        /// 
        /// ■Twitterizerの使い方 (きゃのさんの日記 http://cannotdebug.blog.fc2.com/blog-entry-8.html より抜粋)
        ///  ・・・3.基本構造
        /// Twitterizerにおけるほとんどの操作は、次のような形で行われるようだ。
        ///
        /// TwitterResponse hoge = [Some Class].[Some Method](OAuthToken o,[Values...]);
        /// var Data = hoge.ResponseObject;
        ///
        /// こうすることで、Dataに[Some Class]型のインスタンスか、[Some Class]型のコレクションが代入される。
        ///
        /// この方法で操作するクラスは、
        ///
        /// ・TwitterUser ...ユーザー操作
        /// ・TwitterStatus ...ツイート操作
        /// ・TwitterDirectMessage ...DM操作
        /// ・TwitterList ...リスト操作
        /// ・TwitterSearch ...検索操作
        /// ・TwitterFriendship ...フォロー・アンフォロー操作
        /// ・TwitterFavorite ...お気に入り操作
        /// ・TwitterTimeline ...タイムライン操作
        ///
        /// の8つである。
        ///
        /// 先頭の4つは、ほとんどの静的なメソッドの戻り値として自分自身の型のインスタンス(ツイートするメソッドならツイートしたツイートの情報が入ったインスタンス)、またはそのコレクションを返す。
        ///
        /// 後半の4つは、ほとんどの静的なメソッドの戻り値として(種類によって)先頭の2つのうちどちらかの型のインスタンス(TwitterFriendship型ならTwitterUser型のインスタンス)、またはそのコレクションを返す。
        ///
        /// 具体的には、
        ///
        /// ・タイムラインの取得
        ///
        /// TwitterResponse twitterResponse = TwitterTimeline.HomeTimeline(oau); //取得処理
        /// var TimeLine = twitterResponse.ResponseObject; //TwitterStatusCollection型のインスタンスTimeLineを生成
        /// foreach(TwitterStatus t in TimeLine) //TimeLineからTwitterStatus型のインスタンスtを抽出
        /// {
        /// Console.WriteLine(t.User.ScreenName + ": " + t.Text); //タイムラインのツイートを表示
        /// // t.UserはTwitterUser型のインスタンス
        /// }
        ///
        /// ・フォロワーの取得
        ///
        /// TwitterResponse twitterResponse = TwitterUser.Followers(oau); //取得処理
        /// var Followers = twitterResponse.ResponseObject; //TwitterUserCollection型のインスタンスFollowersを生成
        /// foreach(TwitterUser u in Followers) //FollowersからTwitterUser型のインスタンスuを抽出
        /// {
        /// Console.WriteLine(u.ScreenName); //フォロワーのScreenName(アカウント名)を表示
        /// }
        ///
        /// ・ユーザー表示
        ///
        /// TwitterResponse twitterResponse = TwitterUser.Show(oau,"Alice_Canno"); //取得処理 第二引数は取得したいユーザーのScreenName(アカウント名)
        /// var User = twitterResponse.ResponseObject; //TwitterUser型のインスタンスUserを生成
        /// Console.WriteLine(User.Name); //Alice_Cannoの名前を表示
        ///
        ///という感じである。
        ///
        ///また、第二以降の引数にOptionalPropertiesから派生したクラス(たいてい[hoge]Optionsという名前の型)のインスタンスを渡すものもある。
        ///これは、インスタンスのプロパティにプロパティ名から察して適当な値を入れて渡してやればよいし
        /// 、一部または全部の値を空のままにしてもよい。
        /// メソッドによってはnullを渡しても大丈夫なようだ。
        /// </summary>
        public static void HELP・このクラスの使い方のヘルプ()
        {
            // もし可能なら、簡単な使用例を描く。

            // initはクラス生成時に自動的に呼びだされるから、呼びだす必要はない。

            // twitterクライアントなどで、トークンを取らせたかったら一度やってみて。botなら基本要らない。
            //MyTwitterTools.makeUserDoTwitterRecognization・PINコードをユーザに入力させてツイッター認証();

            // Twitterに実際につぶやかせたいときはfalse。テスト用につぶやかせたくないときはtrue
            MyTwitterTools.p_isTest・テスト用にツイッターで投稿する代わりにメッセージボックスに表示するか = true;
            // TwitterAPIは基本1時間に150アクセスしかできないから、下手にやらないようがいいみたい…。



            tweet・つぶやく("#Test マイクテスト中…ツイートテスト中3。これはC#のTwitterAPIを使って、つぶやいています。。フォロワーのみなさん、うるさかったらごめんね。そろそろテストアカウントに移動しますね…");
            string _twitterID = "merusaia";
            string _screenName = MyTwitterTools.getNickName・ニックネームを取得(_twitterID);
            Stopwatch _stopwatch1 = new Stopwatch();
            _stopwatch1.Start();
            int _followerCount = MyTwitterTools.getFollowerTwitterUserIDs・フォロワーの識別数値IDを全て取得_高速版(_twitterID).Count;
            _stopwatch1.Stop();
            MyTools.showMessage_ConsoleLine(_stopwatch1.ElapsedMilliseconds + "ミリ秒かかってる <= MyTwitterTools.getFollowerTwitterUserIDs・フォロワーの識別数値IDを全て取得_高速版(_twitterID)");
            _message = "#Test " + _twitterID + " のフォロワーは、twitterizerによると " + _followerCount + " 人いるようです。…合ってます? 間違ってたらごめんね。\nこの処理に"+(_stopwatch1.ElapsedMilliseconds/1000.0)+"秒かかりました。…遅いね。";
            MyTwitterTools.tweet・つぶやく(_message);

            System.Windows.Forms.Application.Exit();

        }

        #endregion
    }
}

他の開発者の方の少しでも参考になれば幸いです。

パブリックドメイン著作権放棄します。ご自由にコピー・改変してお使いください。


ソース全文をダウンロードしたい方は以下からお気軽にどうぞ。
(※VisualStudio2010用なので、文字コードUTF-8です)。
■MyTwitterTools.cs
dropbox.com/home/Public/minRPG_みんつくプロジェクト 
https://www.dropbox.com/home/Public/minRPG_%E3%81%BF%E3%82%93%E3%81%A4%E3%81%8F%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88
(※VisualStudio2010用なので、文字コードUTF-8です)。
上記URL → ソースコード → 最新日付 → 「***.zip」をダウンロード&解凍
→ その中の「minRPG/_NET4_0Program_Twitterアプリ/NET4_0_Toolsプログラミングツール系」
   というフォルダの中に、「MyTwitterTools.cs」が入っています。(.NET Framework4.0が必要)
   なお、動かしたい場合は「MyTools.cs」というファイルも必要です。(このファイルのメソッドを使っているため)



ついでに、ここに「皆で創るRPG」て試作ゲームも、著作権フリーです。ご自由にお使いください。

その他、転載するなとか連絡してよとかとか固いことはなんにも言いませんので、じゃんじゃんお使いください。


余談ですが、他のサイトを調べてて、TwitterStreamクラスやTwitterStatusAsyncクラスなどと書かれてあるのが、私の環境ではなぜか見当たらない。。
最新版のtwitterizerにはなくなったんでしょうか…?


PS:プログラムソースコードが色分けされて、更に自動改行されないだけで、これだけ見やすさ変わるんですね。
やっぱりはてなブログより、はてなダイアリーの方が使いやすい…。