1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

HerokuとRailsで自己リツイートを行うTwitterbot(Windows編)

Last updated at Posted at 2018-12-24

古い記事です。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というデータベースを使うように設定するといいらしい。詳しくは元記事参照。

変更前

Gemfile
gem 'sqlite3'

変更後

Gemfile
gem 'sqlite3', group: :development
# Use postgress in production mode
gem 'pg', group: :production

ちなみにワードパッドで編集した。vimとかEmacsとか使いこなせるようになりたいんだけどね… #の行はコメントだから自由に書けばいいんだけど、漢字とか仮名とかうまく読み込まれないから、英語かローマ字で分かるように書こう。ついでにTwitterのgemも追加しちゃおう、さっきのの下とか好きなところに以下の文言を追加。

Gemfile
# 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ファイルを次のように変更

変更前

_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>

変更後

_form.html.erb
  <div class="field">
    <%= form.label :content %>
    <%= form.text_area :content, cols: 40, rows: 5 ,maxlength: 140 %>
  </div>

ルーティング設定

アクセスしたときに掲示板がトップページになるようにする。\configにあるroutes.rbを以下のように書き換える。rbファイルはそのまま開いたのでは編集ができないので「プログラムから開く」で好きなテキストエディタを開こう。

routes.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ファイルを以下のように編集する。
まずはしょっぱなの部分をこう

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メソッドにも同様に付け加えてほしい。現状僕の環境でうまくツイートの削除ができてないから人に教えられない状況なんだけれど

tweets_controller.rb
  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アカウントの垢名に変えてね。

tweets_controller.rb
  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の下に記述

tweets_controller.rb
  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を書き換えてルーティングの設定をする

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ファイルに次の記述を追加

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ファイルを以下のように編集する。

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とはこのようなものです。

sendGet.gs
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 %>の直下に以下を追記した。
application.html.erb
<meta name="viewport" content="width=device-width, initial-scale=1">
  • HTMLにUnicodeを直書きすることで日本語が一部書けるようになった。
    • ↓みたいな感じで。ボタンやリンクに書く言葉を日本語化する方法はまだ分かっていない。
</p>&#x3082;&#x3057;&#x304b;&#x3057;&#x305f;&#x3089;&#x3053;&#x3046;&#x3057;&#x305f;&#x3089;&#x6587;&#x5b57;&#x304c;&#x8aad;&#x3081;&#x308b;&#x3088;&#x3046;&#x306b;&#x306a;&#x3093;&#x3058;&#x3083;&#x306a;&#x3044;&#x306e;&#x3063;&#x3066;&#x3044;&#x3046;&#x50d5;&#x306e;&#x4e88;&#x6e2c;&#x3088;&#x3069;&#x3046;&#x304b;&#x5f53;&#x305f;&#x308c;</p>
  • Heroku の無料枠が終了すると発表されてしまった……どうしよう…
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?