古い記事です。Herokuの無料枠が終了するため以下の方法で作るとお金が発生するようになります。この記事は残しておきますが、近々GAS等を使って改修しようと思います。
改修できました!今後は下の記事を参考にしてください。
ツイッターのbot作りたい。
でも検索かけたら自分のbotで検索欄埋め尽くしたくない。
過去にツイートしたものだったら自己リツイートによって再ツイートする仕様にしたい。
あとツイート内容を追加・削除・訂正出来るように管理したい。
既存のwebサービスではちょっと見当たらなかったから自作するかもっと探すかを考えている。
自作できたので以下に示す。
方法
コマンドプロンプトを使いやすい位置に置く
コマンドプロンプトについてはこのへんを読んでください。タスクバーにピン止めしたりとか。うちのパソコンのOSはWindows10です。
Rubyをダウンロード
こちらの記事を参照
僕の場合MSYS2というのがなかなかインストールできなくて6か月ほど投げ出した覚えがある。最終的にここからmsys2-base-x86_64-20181211.tar.xzというファイルを直接ダウンロードした気がするがよく覚えていない。
Rails on Rubyをダウンロード
先ほどと同じ記事を参照
途中、処理がバッティングしているというようなエラーが出たのでcatgets-1.1-2、libcatgets-1.1-2というフォルダとgencat.exeというファイルをデスクトップに移したら最後まで行けた。
Gitのインストール
ここからGitをダウンロード
twitterアカウントを創設
志怪小説bot@shikai_shosetsuを創設した。
Herokuのアカウントを作成
このページからアカウントを作成しよう。
Herokuのcommand類をインストール
よく覚えてない、ここからWindows用のをダウンロードしたんだっけか
Windowsにはbrewとかいう便利なコマンドはないのだ。
環境
- Ruby 2.4.3p205 (2017-12-14 revision 61247) [x64-mingw32]
- Ruby On Rails 5.2.1.1
- Git 2.19.2.windows.1
- Heroku 7.18.10 win32-x64 node-v11.1.0
環境の表記の仕方はこれで合っているのだろうか
Railsアプリを作成
こちらの記事を参考にしながらrailsアプリを作成していこう。まずはコマンドプロンプトに以下のように記述、エンター
$ rails new shikai-shosetsu-bot
shikai-shosetsu-botのところはお好きなアプリ名で。元記事では新しくディレクトリ作ってたけど特にこれといってないならわざわざ作らなくてもいいんじゃないかと思う。ディレクトリが入れ子になっちゃって大変だった。
Gemfileの設定
Ruby on RailsではデフォルトでSQLiteというデータベースを使用しているらしいんだけど、これがHerokuでは使えないらしいので、Heroku上ではPostgreSQLというデータベースを使うように設定するといいらしい。詳しくは元記事参照。
変更前
gem 'sqlite3'
変更後
gem 'sqlite3', group: :development
# Use postgress in production mode
gem 'pg', group: :production
ちなみにワードパッドで編集した。vimとかEmacsとか使いこなせるようになりたいんだけどね… #の行はコメントだから自由に書けばいいんだけど、漢字とか仮名とかうまく読み込まれないから、英語かローマ字で分かるように書こう。ついでにTwitterのgemも追加しちゃおう、さっきのの下とか好きなところに以下の文言を追加。
# Use Twitter api
gem 'twitter'
そしてコマンドプロンプトでバンドルインストール!
$ cd shikai-shosetsu-bot
$ bundle install
掲示板を作成
$ rails generate scaffold tweet content:text tweet_id:string rt_id:string
$ rails db:migrate
フォームをいじる
この記事を参考にして\app\views\tweetsにある_form.html.erbファイルを次のように変更
変更前
<div class="field">
<%= form.label :content %>
<%= form.text_area :content %>
</div>
<div class="field">
<%= form.label :tweet_id %>
<%= form.text_field :tweet_id %>
</div>
<div class="field">
<%= form.label :rt_id %>
<%= form.text_field :rt_id %>
</div>
変更後
<div class="field">
<%= form.label :content %>
<%= form.text_area :content, cols: 40, rows: 5 ,maxlength: 140 %>
</div>
ルーティング設定
アクセスしたときに掲示板がトップページになるようにする。\configにあるroutes.rbを以下のように書き換える。rbファイルはそのまま開いたのでは編集ができないので「プログラムから開く」で好きなテキストエディタを開こう。
Rails.application.routes.draw do
resources :tweets
root 'tweets#index'
end
ここらで一度動かしてみよう。以下のコマンドを入力
$ rails s
続いてお好きなブラウザのアドレス欄にlocalhost:3000と入力。エラーが起きなければ大成功、起きたらごめんなさい、コマンドプロンプトに残るログを読めばもしかしたら原因がわかるかも…
Tweet機能の追加
こちらの記事を参考にしていきます。Ryoya Sekino氏に圧倒的感謝
Twitterアプリケーション登録
こちらの記事を参考にしてConsumer Key、Consumer Secret、Access TokenとAccess Token Secretを入手する。サイトはとりあえずgithubに新しくレポジトリを作ってそれにした。
controllerを編集
\app\controllersにあるtweets_controller.rbファイルを以下のように編集する。
まずはしょっぱなの部分をこう
require "twitter"
class TweetsController < ApplicationController
before_action :set_tweet, only: [:show, :edit, :update, :destroy]
before_action :twitter_client, except: :new
def twitter_client
@client = Twitter::REST::Client.new do |config|
config.consumer_key = ENV['CONSUMER_KEY']
config.consumer_secret = ENV['CONSUMER_SECRET']
config.access_token = ENV['ACCESS_TOKEN']
config.access_token_secret = ENV['ACCESS_TOKEN_SECRET']
end
end
~
次にupdateメソッドにtweet_deleteメソッドを付け加える。tweet_deleteメソッドは後程作ります。destroyメソッドにも同様に付け加えてほしい。現状僕の環境でうまくツイートの削除ができてないから人に教えられない状況なんだけれど
def update
tweet_delete
respond_to do |format|
if @tweet.update(tweet_params)
format.html { redirect_to @tweet, notice: 'Tweet was successfully updated.' }
format.json { render :show, status: :ok, location: @tweet }
else
format.html { render :edit }
format.json { render json: @tweet.errors, status: :unprocessable_entity }
end
end
end
次にpostメソッドを追加。3箇所あるscreen_name: "shikai_shosetsu"のshikai_shosetsuの部分はご自身のTwitterアカウントの垢名に変えてね。
def post
tweet_options = Tweet.where(tweet_id: nil)
if tweet_options.size != 0
tweet = tweet_options.shuffle.first
status = tweet.content
@client.update(status)
tw = @client.user_timeline(screen_name: "shikai_shosetsu", count: 1)
tweet.tweet_id = tw[0].id.to_s
else
tweet = Tweet.where.not(tweet_id: nil).shuffle.first
if tweet.rt_id.present?
@client.unretweet(tweet.rt_id.to_i)
@client.retweet(tweet.tweet_id.to_i)
tw = @client.user_timeline(screen_name: "shikai_shosetsu", count: 1)
tweet.rt_id = tw[0].id.to_s
else
@client.retweet(tweet.tweet_id.to_i)
tw = @client.user_timeline(screen_name: "shikai_shosetsu", count: 1)
tweet.rt_id = tw[0].id.to_s
end
end
tweet.save
redirect_to :root
end
最後にtweet_deleteメソッドをprivateの下に記述
private
~
def tweet_delete
if @tweet.tweet_id.present?
@client.destroy_status(@tweet.tweet_id.to_i)
@tweet.tweet_id = nil
@tweet.rt_id = nil
@tweet.save
end
end
~
ルーティング設定
再び\configにあるroutes.rbを書き換えてルーティングの設定をする
Rails.application.routes.draw do
resources :tweets do
collection do
get 'post'
end
end
root 'tweets#index'
end
ツイート機能の確認のために、新しいツイートを追加するページにでもツイートボタンを設置してみよう。\app\views\tweetsにあるnew.html.erbファイルに次の記述を追加
<button type="submit" style = "width: 70px; height: 25px;"><%= link_to 'tweet', post_tweets_path %></button>
BASIC認証で簡易的にカギをかける
アプリをHerokuに公開する場合、urlがばれたら勝手に投稿とかされかねないので、この記事を参考にしながら簡易的な認証をかけよう。\app\controllersにあるapplication_controller.rbファイルを以下のように編集する。
class ApplicationController < ActionController::Base
http_basic_authenticate_with :name => ENV['BASIC_AUTH_USERNAME'], :password => ENV['BASIC_AUTH_PASSWORD'] if Rails.env == "production"
end
名前とパスワードは後で設定します。
Herokuでアプリケーション作成
再びこの記事を参照しながらHerokuにRailsアプリをデプロイしよう。
アプリケーション作成
$ heroku create shikai-shosetsu-bot
shikai-shosetsu-botのところには自分のアプリ名を。ちなみにアンダーバーが使えないらしいぜ。
アプリケーションのデプロイ
$ git push heroku master
マイグレーションの実行
$heroku run rails db:migrate
環境変数の設定
最後に環境変数を6つ新たにHerokuに登録する。ツイッタートークンとかパスワードとかファイルに直接書いたら誰かに見られてしまう危険のあるものはHeroku上で環境変数として設定すればいいらしい。Herokuのサイト上で登録する方法と、コマンドプロンプトでやる方法の2つあるけど、僕は前者を選んだ。
まずはHerokuのサイトにアクセスして、自分のアプリを選択、Settingsに移動してReveal Config Varsボタンをクリック。Config Varsの最終行から、次の6つをKEY、VALUEとして設定していく。
KEY | VALUE |
---|---|
CONSUMER_KEY | 先ほどTwitterアプリケーション登録でゲットしたconsumer_key |
CONSUMER_SECRET | 同じく先ほどゲットしたconsumer_secret |
ACCESS_TOKEN | 同じくゲットしたaccess_token |
ACCESS_TOKEN_SECRET | 同じくゲットしたaccess_token_secret |
BASIC_AUTH_USERNAME | BASIC認証で使う名前 |
BASIC_AUTH_PASSWORD | BASIC認証で使うパスワード。簡易的な認証だからバレても大丈夫なものにしておこう |
テスト
さてここらで一度動作確認をしてみよう。
http://(自分のHerokuアプリ名).herokuapp.comにアクセスして、New Tweetをクリック。フォームでbotに使うツイートを入力し、Create Tweetをクリックして保存。最後にTweetボタンを押して無事ツイートされたら成功!
Google Apps Scriptで自動投稿の設定
Heroku上で自動投稿とかの定期的な処理をするときはheroku Schedulerってアドオンを使うのが一般的らしいんだけど、クレジットカードも持ってないのでGoogle Apps Script(GAS)を使うことにした。GASとはこのようなものです。
function sendGet(){
/* POSTするためのOPTIONを設定 */
var options = {
"method": "get",
"Authorization" : " Basic " + Utilities.base64Encode(userid + ":" + password),
"muteHttpExceptions": true
};
var html = UrlFetchApp.fetch('http://(自分のHerokuアプリ名).herokuapp.com', options);
Utilities.sleep(60000);
var response = UrlFetchApp.fetch('http://(自分のHerokuアプリ名).herokuapp.com/tweets/post', options);
Logger.log(response.getContentText());
}
useridとpasswordのところには認証に使う名前とパスワードを入力してほしい。トリガーで6時間おきにツイートまたはリツイートするよう設定した。
これにて完成である!
課題
- 記事の削除ができない
- 記事が0個のときの処理を書いていない
- 日本語対応
- erbファイルとかに日本語が混じってるとうまく動かない。いくつか日本語対応できる記事とかみつけたのでおいおい対応することにする。
- 記事の取得の仕方に改善の余地あり
- 今のままじゃ記事数が増えたら重くなってしまう
-
画面がスマホ向けじゃないそもそもまだきちんと設計できていないから当たり前なんだけど
- なんか140字以上入力できてしまったみたいでツイッターへの投稿時にエラーになってそれで4日ぐらいツイートが止まった。
- ツイートできない→他全部ツイート済みだから次回時にまたそのツイートが選ばれる→またツイートできないの負のループ
- 編集しなおしたらまた無事動き出したけど他にもこんな類のエラーが起きたらまたツイートが止まりそう...
- ほかにももし同じことで困っている人がいた時のためにツイート済みのものはRTで済ますTwitter bot 作成アプリ作りたい
- Twitter認証難しそう
- 無料のherokuサーバでは耐えられなさそう
- 要望がもしあったらその時またいろいろ考えよう
追記
- 1度他の人にRTされたツイートが再びRTされないというバグが発生した。対処法を検討中。
- どうやら勘違いだったようだ。
- 画面のスマホ対応ができた。
- \app\views\layoutsのapplication.html.erbにある<%= csp_meta_tag %>の直下に以下を追記した。
<meta name="viewport" content="width=device-width, initial-scale=1">
- HTMLにUnicodeを直書きすることで日本語が一部書けるようになった。
- ↓みたいな感じで。ボタンやリンクに書く言葉を日本語化する方法はまだ分かっていない。
</p>もしかしたらこうしたら文字が読めるようになんじゃないのっていう僕の予測よどうか当たれ</p>
- Heroku の無料枠が終了すると発表されてしまった……どうしよう…