仕様
Twitterに記事を自動投稿する、いわゆるBOTツールを作成していきます。世間では多くのBOTツールが無料で配布されていますが、複数行のツイートを複数指定可能で、画像も一緒にツイート可能なことが、今回のツールの一つのアピールポイントです。
【概要】
入門編で作成したTweet記事作成ツールで作成したファイルを読み込み、一定間隔でファイルの内容をを画像付きでTweetする。
【入力】
ツイート保管ファイル内のBASEで指定された名前に4桁の連番を付加したファイル名を持つファイル
[例]
ツイート保管フォルダ:d:\worl\kiji\tweet
BASE:twwetarticle
の場合は、絶対パス名d:\worl\kiji\tweet\twwetarticle0001.rtf〜twwetarticle9999.rtfで示されるファイル
先頭行は、画像ファイルの絶対パス名もしくはファイル名で、最大4つまで指定。
【出力】
設定で指定したTwitterアカウントのタイムライン上に指定した時間間隔で画像付きのツイートを表示する。
ツイートした記事と画像をツールの記事表示画面に表示する
【設定】
1.ツイート保管フォルダのパス
2.ファイルのBASE名
3.画像保管フォルダのパス
4.記事1行目の扱い
絶対パス名による画像ファイル指定、ファイル名のみの指定、画像は設定していない(空行)
5.TwitterのAPIを使ってTwitterを操作するための情報
6.ツイート間隔
設定項目は、保存及び読み込みを可能とする。
画面デザイン
実行画面のイメージを下記に記載しておきます。
【ツイート表示画面】
【設定画面】
Twitterの利用について
TwitterのアカウントのTLにツイートを表示するには、どう行うかは別として、大きく2つの方法が考えられます。
1.人間の偽装
ID・パスワードを入力した様に偽装してTwitterにログインしてツイートします。
2.Twitter APIの利用
Twitterが提供するAPI(Application Programing Interface)というものを利用して、タイムラインにツイートします。
このうちTwitter社が認めているのは、2.の方法だけです。
規約では、Twitterのタイムラインを読み込んだり、フォロー・いいね・RTしたりする際にスクレイピングの様な手法を使うことは禁止されています。
過去に「APIを使わないので安全」と言ったアナウンスをしているTwitter用のツールがあったりしましたが、基本的にTwitterの規約に違反していることになるので、逆に注意してください。
APIを使わずに何か偽装したい「意図」が問題になるので、そういう利用方法がまずい訳です。
基本的にTwitterの規約に則り自動化ルールを守っている限りは、ツールを使ってもそれ自体は特に問題はありません。
ただ、どうしてもそれらの「使い方」を守っても、あなたのツールを観た方がツイート内容や頻度に拒否反応を示したり、場合によってはあなたのアカウントをBANしたいが為に、違反報告する場合があります。
しかし、仮にアカウントが一時的に制限された場合でも、SMSが利用可能な電話番号を指定することで、アカウントの制限が解除されます。
ただ注意しなければいけないのは、電話番号を同時に指定できるのは、1電話番号1アカウントだということです。
そして、電話番号指定をした後に、電話番号の指定を解除することが出来ますが、解除したとしても、仮に別のアカウントが制限されたりした場合に、すぐには電話番号を使いまわすことは出来ません。
なので、ルールに則って、利用するのしても、電話番号分以内のアカウント運用をおススメします。
Twitterは定期的にアカウントに制限を書ける場合があります。
その際の制限解除には上で書いた様に電話番号の入力が必須になるのですが、1つの電話番号で複数アカウントを運用していると、制限の解除が出来なくなります。
この場合に、Twitter社にアカウント解除の申請をした場合に、アカウント削除が初めてという場合は別として、制限が何回も行われていると、電話番号を入力して指示に従うように伝えられるだけの場合が多くなってきます。
そして、制限解除をしないでおくと、アカウントが削除されてしまいます。
こういう状況になると、Twitter社にアカウント削除の解除申請をしても全く受理されなくなります。
このアカウント制限に関するTwitter社の運用は以前に比べて、非常に厳しくなっています。したがって、くれぐれもTwitter社の規約に従わない運用は辞めましょう。
なお、2020年7月23日現在、新規にTwitterアカウントを作成する場合に、従来任意だった電話番号の入力が必須になっているように見えます。
Twitter APIを利用するために - OAuth2.0概論
Twitter APIを利用するアプリケーションを使うために必要な作業を簡単に書いておきます。
まず、大きな前提として
アプリケーション・アプリケーションのユーザー・Twitterの3者が登場人物として存在する
ことを常に認識してください。そしてユーザーはTwitterのユーザーアでもあります。アプリケーションがそのユーザーに代わって、Twitterの機能を利用する訳です。
そこでアプリケーションとしてはユーザーがTwitterにログインして行うことと同様なことが出来る必要があります。しかし、ログインのための情報をアプリケーションに記憶させることはセキュリティ上のリスクが発生します。
そこで、OAuth2.0という仕組みを使って、ユーザーがログインしている場合と同様な権限を使わせてもらうのです。(ログインによるユーザー-認証とは違うので、認可という言葉を使っています。)
なお、ここで記載している事項は、基本的に自分で作ったアプリケーションを他人に使ってもらうことを前提にしています。もし、自分で作って自分で使う場合は少しだけ簡単にできます。
OAuth2.0の詳細の説明はしませんが、下記の様な形でユーザーの権限を使わせてもらいます。
1.アプリからTwitterにリクエストトークン取得を依頼する
Twitter APIを利用するアプリケーションの開発者は、TwitterアカウントでTwitter社に対して開発者申請を行い、開発者として認めてもらう必要があります。
開発者用のサイトは下記になります。また、申請は基本的に全て英語です。
https://developer.twitter.com/en
開発者の申請には、開発するプログラム名やプログラムの概要、そしてプログラムの詳細説明を英語で記述します。
Twitter社による審査を経て開発者として承認されると、アプリケーションに対してConsumer API keyとConsumer API secret keyが割り当てられます。
そこで、このConsumer API keyとConsumer API secret keyをアプリケーションからTwitterのシステムに渡します。
すると、アプリケーションユーザー向けにTwitterのシステムは、アプリケーションのログインを許可することを促すためにTwitterへのログイン画面を表示します。
そこで、ユーザーがログインを行うと、PINコードが表示されます。
2.アプリからTwitterにアクセストークンの取得を依頼する
PINをユーザーに控えてもらい、アプリケーションにセットしてもらいます。(スクレイピングしても良いがユーザーにセットして貰う方が簡単で速い)
そしてConsumer API keyとConsumer API secret key及びPINをアプリケーションからTwitterのシステムに渡して、Access token と Access token secretを発行してもらいます。
そして、発行されたAccess token と Access token secretをアプリケーションにセットしてもらいます。
ここまでがTwitter APIを使う前の準備で、アプリケーションを使い始める際に一度だけ実行すればOKです。
ただ、必ず、Consumer API keyとConsumer API secret key及びAccess token と Access token secretをアプリに記録しておく必要があります。
3.アプリがConsumer API keyとConsumer API secret key及びAccess token と Access token secretでTokenを取得する
アプリでTwitterの機能を使用するために、Consumer API keyとConsumer API secret key及びAccess token と Access token secretをTwitterのシステムに渡してトークンを取得し、機能に該当するAPIを利用します。
Twitterを使う流れを書きましたが、文字だけで書いているので、分かりにくいかもしれません。
最初に書いた様に、
アプリケーション・アプリケーションのユーザー・Twitterの3者が登場人物として存在する
ことを念頭に、アプリがユーザーと同様の権限を使える様にするために、アプリが途中でユーザーの助けも借りながらTwitterとやり取りしていると考えてください。
※アプリを作って自分だけで使う場合
Twitter社による審査を経て開発者として承認されると、アプリケーションに対してConsumer API keyとConsumer API secret keyが割り当てられと書きましたが、アプリを自分で使うだけであれば、同時にAccess token と Access token secretを設定できます。
そこで、上の1.2.の手続きを踏まずに、Consumer API keyとConsumer API secret key及びAccess token と Access token secretをTwitterのシステムに渡してトークンを取得し、機能に該当するAPIを利用することが可能になります。
なので、ユーザーに開発者登録を行ってもらい、Consumer API keyとConsumer API secret key及びAccess token と Access token secretを取得しアプリケーションに設定してもらえば、上記の1.2.を行う必要は無くなります。
プログラムの概要
設定値の保存と読み込み
設定値の保存や読み込みは、Setteings1.settingsを使って、行います。
保存しておきたい項目に名前を付けてSetteings1.settingsに登録します。
設定値の保存は、
Properties.Settings.Default..指定した項目名 = textBox?.Text;
と言った形で保存します。
ただ、最後に、
Properties.Settings.Default.Save();
を忘れずに記述してください。
これによって、設定値が保存されます。
textBox?.Text = Properties.Settings.Default..指定した項目名;
という形で、保存した設定値を読み込むことが出来ます。
【設問】
radioボタンをどう保存するかを考えなさい。
Tweet開始・停止の考え方
基本的に、Tweet開始ボタンがクリックされたら、Folderに格納されている記事がある限り一定時間おきにツイートし続けます。
仮に、repeat指定されたいたら、アプリケーションを終了するかPCがシャットダウンされない限りツイートし続けます。
一方で、Tweet停止ボタンをクリックされたら、ツイート記事があっても止まって欲しいのです。
では、この機能をどう実現すればよいでしょうか。
まず一定時間起きにという部分は、次の様に、
await Task.Delay(指定したミリ秒);
と指定することで、アプリから一定時間Windowsに制御が渡されます。
そこで、その段階でTweet停止が押されたら、処理を止めれば良いことが分かります。
なので、Tweet処理稼働中ならtrue、Tweet処理稼働中でなければfalseになるbool型の変数on_tweetを設けて、Tweet開始ボタンがクリックされたら、on_tweetをtrueにセット、Tweet停止ボタンがクリックされたらon_tweetをfalseにします。
そして、Tweet開始ボタンのクリック時は、on_tweetをtrueにすると同時に、on_treetがtrueの間中、記事保管フォルダから次にTweetする記事を読み込んでツイートしたら、一定期間Task.Delayするという処理を繰り返します。
【設問】
記事保管フォルダから次のTweet記事を読み込む処理のアルゴリズムを考えなさい。
【設問2】
記事をツイートしている処理を繰り返している時に、Tweet開始ボタンをクリックしたらどうなりますか?もし、問題が発生する様であれば、それを回避する方策を考えてください。
【設問】
上記を踏まえて、BOTアプリのプログラムを書きなさい。ただし、Tweet記事のパスをstring型のpathに設定されていれば、
tweetimage.load(path);
tweetimage.tweet();
でツイートできるtweetimageクラスが存在しているものとします。
処理の概要 - 記事のツイート
ここでは、記事を読み込んでツイートする処理を考えます。
この記事をツイートする事自体は、BOTであろうが何であろうがTwitterのアプリケーションでは共通に働くことが想像できます。
そこで、BOTとは独立したプログラムを書いて、BOTからは通常のメソッドを呼び出す様に利用することを考えます。
もちろん、BOTの共通メソッドとして作ることので構わないのですが、ここではDLLという概念を説明するために、この様な形とします。
DLLとは、メソッドをアプリケーションとは独立に記述したもので、アプリケーションからは、普通のメソッドと同じ様に利用できるものです。
ただ、独立していると書いたのは意味があって、DLLとして作ると、物理的に〜.dllというファイルが作られて、他のアプリケーションでもそのDLLを利用することが出来る様になります。
作り方は簡単で、Visual Studio 2019で普通にプロジェクトの操作をしている所で、メニューの「ファイル」⇒「追加」⇒「新しいプロジェクト」を選択し、今回ならクラスライブラリ(.Net Framework)を選択して、通常のプロジェクトを作成します。名前はtweetimageとしておきましょう。
すると、メインのプロジェクトの中に新しいプロジェクトが追加されます。
そして、tweetimage.csタブが出来て、ここにメソッドのひな型が作成されます。
今回だと、いくつかusingが並んだあと、
namespace tweetwimage
{
public class tweetimage
{
public tweetimage()
{
という感じになっています。
つまり、この中で一つのnamespaceを作り、さらにその中でクラスが作成されているのです。そして、そのクラスのコンストラクターが何もない状態で存在している感じです。
クラスのインスタンスとコンストラクター
今、コンストラクターと書きましたが、クラスを利用する際に、実体を設定する時に使うものです。
例えば、下記の様にrtbという名前を付けたRichTextBoxクラスの変数を宣言したとします。
RichTextBox rtb;
そして、テキストエリアにabcと表示しようとして
rtb.Text = "abc";
と書いたとします。すると、そう書いた時点で、Visual Studioは
未割当のローカル変数'rtb'が使用されました。
とエラーを表示します。
クラスは宣言しただけだと、実体が伴わない状態なのです。
そこで、実体を伴うようにするのがnewの働きです。
そこで、
RichTextBox rtb;
rtb = new RichTextBox();
rtb.Text = "abc";
と書くと、今度はエラーの表示はされません。
宣言した後に、RichTextBox型のエリアを新しく確保するのが、new RichTextBox()の意味です。
そして、RichTextBox型のエリアを確保するのがRichTextBoxの型名に()を付けてメソッドの呼び出しの様な形にしたもので、RichTextBox型の実体を用意するものです。
こうしてクラスを宣言した実体が用意されたものをインスタンスと呼んでいます。
これは、
RichTextBox rtb = new RichTextBox();
などとクラスの宣言と同時にインスタンスを割り当てる形に書くこともできます。
そこで、クラスを定義する場合には、クラス名と同じ名前でコンスタらクターを定義出来、それはクラスのインスタンスを設定します。
tweetimageクラスの設計
それでは、tweetimageクラスの内容を考えてみましょう。
Twitter APIを使って記事をツイートする際には、Consumer API keyとConsumer API secret key及びAccess token と Access token secretをアプリに記録しておく必要があることを伝えました。それらは、String型で保持出来ます。
当然、つぶやく記事が必要です。記事はローカルに保存したり、読み込んだりできると都合が良いでしょう。そのため、RichTextBox型のインスタンスに入れておくと扱いが便利そうです。
そして、最大4つの画像の情報が必要です。画像は、ローカルドライブの絶対パス名が分かれば、それをロードして表示できます。なので、String型で保存しておけば良いでしょう。
そうすると、クラスには下記の様な情報を持てば良いことが分かります。
string ar_apikey; // Consumer Api key
string ar_apikey_s; // Consumer Api secret key
string ar_token; // Access token
string ar_token_s; // Access token secret
RichTextBox ar_content; // Contents of Tweet article
string ar_imageurl1; // Full path for Image
string ar_imageurl2; // Full path for Image
string ar_imageurl3; // Full path for Image
string ar_imageurl4; // Full path for Image
これにクラスの外からどうアクセスするかですが、C#ではクラスのメンバー変数に直接アクセスするのではなく、プロパティと言う概念を設けて、プロパティを通してアクセスするということが普通です。
【クラスの内部での定義】
class tweetimage
{
private string ar_imageurl1;
public string Ar_imageurl1
{
get { return this.n; }
set { this.n = value }
}
}
【利用する場合】
tweetimage ti = new tweetimage();
パスを設定する場合
ti.Ar_imageurl1 = textBox1.Text + @"\" + textBox2.Text + "0001.rtf";
【パスを読み込む場合】
textBox4.Text = ti.Ar_imageurl1;
先ほど、クラスは変数を宣言しただけでは使えず、実体を持たせる必要があると書きました。逆に、同じ変数名でインスタンスを複数作成可能です。その中で、今作業をしているインスタンスを特定するのがthisというキーワードです。
クラスの定義の中では、あたかもメソッドの様に記述し、使う場合はクラスの持つ変数(メンバー変数)にアクセスする様に記述します。
これだけを見ても、だから何だという感じだと思います。
例えばですが、仮にクラスのプログラミングにバグがあって、修正したとしても、それはクラスの内部的な話で、利用する側からすると、プログラムを編くする必要が無い訳です。
クラスの変数を全てpublicにして手の内をすべて見せてしまうと、誰かが勝手にその中の変数をプログラムで直接使ってしまったとします。
後日クラスの修正をして、その変数を削除した場合にどうなるでしょうか。もともとそのクラスを使っていたプログラムは動かなくなってしまうでしょう。しかし、(普通はクラスの変数なんて勝手に使わないので)何で動かないのかが分からないという事態になりかねないのです。
さて、上記で記事をRichTextBoxで保持しました。ユーザーからすればパスを指定すれば、記事を読み込んでくれれば、記事の内容はどうでも良い訳です。
そして、またユーザーからすれば、(今回のBOTツールでは使いませんが)保管するパスを指定してあげれば、記事の内容は本来はどうでもよい訳です。
ただ、記事内容自体は画面に出力するでしょうから、記事自体は読めた方が良いでしょう。しかし、BOTで使う分には、パスを指定して記事を読み込んで、それを画面に表示した上で、TwitterでツイートすればOKです。
何を言いたいかというと、tweetimageクラスでは、記事がどこにあるか(つまり記事のパス)は自分で持つ必要はない事が分かります。
その代わりに、保存したり、読み込む機能をクラスに付け加えて、呼び出す際に引数としてパスを指定してもらえば良い訳です。
ただ、クラス内にパス名を保存して、そのパス名で保存・読み込みを行うようにしても可能です。
なので、前者の場合はtweetimage.load(string path),tweetimage。save(path);という感じで使えるloadとsaveメソッドが必要です。
後者の場合は、tweetimage.Ar_path = full_path;tweetimage.load();と言った感じになるでしょう。
ところで、pathで指定したファイルをloadしようとしたらファイルが存在しなかった場合や、pathで指定されたfolderが無くてsave出来なかった場合はどうすれば良いでしょう。一つはloadやsaveを上手く行ったかどうかをbool型で返す関数にすれば良いでしょう。
もしくは、上手くいったかどうかを保持するbool型のメンバー変数を持っていても良いでしょう。
最後にツイートする場合は、最初にConsumer API keyとConsumer API secret key及びAccess token と Access token secretを使ってtokenを取得しておいて、それを保管し、実際にツイートする際に、そのtokenを利用することでツイートすることが出来ます。
もしくは、ツイートするごとに、都度Consumer API keyとConsumer API secret key及びAccess token と Access token secretを使ってtokenを取得して、それでツイ^とすることもできます。
さて、では実際にツイートするためにはどうすれば良いでしょう。
Twitter APIを実際に発行する方法 - CoreTweet
ではどうやって、Twitterにツイートすればよいでしょうか。
実は、ここについては、既に先人の知恵によって、C#のライブラリが提供されています。
今回はCoreTweetというC#用に作成されているTwitter API用のライブラリを利用します。
Visual Studioの通常であれば右側の上にあるソリューションエクスプローラー画面で、tweetimageプロジェクトの「参照」を探して、そこで、マウスの右ボタンをクリックします。
「NuGetパッケージの管理」というメニューが表示されると思うので、それをマウスの左ボタンでクリックします。
「参照」のタブの画面の上に検索と有るのでCoreTweetと入れます。
一覧が出てくるので、CoreTweetを探して、左ボタンをクリックします。すると右側に情報が表示されて、「インストール」というボタンが現れるので、それをクリックします。
そしてCoreTweetをインストールします。何か聞かれたら、OKをクリックしていきます。
インストールが終了したら、tweetimageの先頭にusingに下記の一行を追加します。
using CoreTwitter;
tokenの取得
tokenの取得は、下記の様な感じになります。
private static CoreTweet.Tokens createTwitterToken(string APIKEY, string APIKEY_S,string TOKEN, string TOKEN_S)
{
/**************************/
// トークン作成
/**************************/
try
{
var tokens = CoreTweet.Tokens.Create(APIKEY
, APIKEY_S
, TOKEN
, TOKEN_S);
return tokens;
}
catch (Exception e)
{
throw new Exception("トークンの作成に失敗しました。", e);
}
}
image付きのツイート
tokenを取得して、4つの画像をツイートするのは、tokenを取得して、そのtokenで画像をアップロードします。
そして、記事と画像情報を引数にtokenのStatus.Uploadメソッドを呼び出します。
var token = createTwitterToken(ar_apikey, ar_apikey_s, ar_token, ar_token_s);
MediaUploadResult first = token.Media.Upload(media: new FileInfo(ar_imageurl1));
MediaUploadResult second = token.Media.Upload(media: new FileInfo(ar_imageurl2));
MediaUploadResult third = token.Media.Upload(media: new FileInfo(ar_imageurl3));
MediaUploadResult forth = token.Media.Upload(media: new FileInfo(ar_imageurl4));
Status s = token.Statuses.Update(status: ar_content.Text, media_ids: new long[] { first.MediaId, second.MediaId, third.MediaId, forth.MediaId });
画像が無いのに呼び出した場合は例外は特に発生せず、画像がないものとして取り扱われます。
なお、画像が一つもない場合は、下記の処理になります。
createTwitterToken(ar_apikey, ar_apikey_s, ar_token, ar_token_s).Statuses.Update(status => ar_content.Text);
【設問】
記事の1行目には最大4つの画像ファイルのパスが,(カンマ)で区別されて記載されているので、最大4つのパスを読み取り、設定された画像の数に応じて正しくツイートするアルゴリズムを考えてプログラムを作成しなさい。
【設問2】
loadメソッド、saveメソッドのアルゴリズムを考えて、プログラムを作成しなさい。
BOTプログラムの配布と稼働の実例
以上でTwitterのBOTプログラムが完成する。
実際に動いているBOTの実例は下記を参照して下さい。
おひさまみっちの日向坂画像BOT
https://twitter.com/ohisamamiche
そして、実際に稼働するBOTプログラムは下記で配布している。
【相互フォロー募集中】BOTツール配布準備BOT
https://twitter.com/giveoutbottool
ただし、上の「Twitter APIを利用するために - OAuth2.0概論」で伝えたように、Twitter APIを使うには、Consumer API keyとConsumer API secret key及びAccess token と Access token secretを取得する必要があります。
そこで、基本的に、Twitterの開発者登録を自力でやって頂く必要があります。
開発者登録をする際には、具体的なイメージがあった方が良いので、ここで記載したBOTの仕様を利用して頂いて結構です。
ただしアプリケーションの名前はご自身で考えた適当な名前で申請してください。