#概要
せっかくのAdvent Calendarなので、クリスマスに関連するアプリを作りたいですね
ちなみに、TECH::CAMP Advent Calenderでは、二日目に以下のような記事がすでに投稿されております!
【Swift】Twitter APIを使ってサンタコス女子を探す
二日目の記事では、サンタコスを探すアプリだったので、今回はサンタコスの画像をTwitterに発信しようかと!
つまり
###Twitter bot
ですね!
ちなみに、検索してもらうとわかるのですが、Twitterのbotの作り方の記事ってたくさんあるのですね!もちろん、rubyを使ったものも多いです。。
そこで、この記事では、特に以下のような点を意識して書きます!
####1. Railアプリであること
まず、rubyで動かすbotの記事は多いですが、railsまで使う記事はあまりありませんでした。特に、データベースを活用したRailsアプリによるbotがあまりありませんでした。
そのため、この記事では、Railsを使用して、以下のようにツイートを画像URL付きで保存する機能をつけます。
そこから、二段階に分けて、最初は手動でのランダム投稿、その次に自動化するようにします!
そうすると、、、
この記事では、最初に、基本的な手続きを踏んで、railsアプリを作成するので、是非Railsの基礎だけ学んだような人にも見てもらいたいです
####2. wheneverを使用した自動投稿
最初は手動でツイートできるようにしますが、やはりbotなので自動で動かしたいですね!
そこで、wheneverを使用して、一定時間ごとにデータベースに保存したツイートをtwitterに自動投稿する機能を作ってみます。
####3. twitterのgemの最新版を使用
twitterのgemは、最新版で少し記述の仕方が変わったようです。そのため、古い記事通りに作るとうまくいかないこともあるようです。ですので、ここでは最新版の書き方に従って書きます。
####4. 画像付きツイートのbot
まあこれはそれ用のメソッド使えばできます笑
####5. サンタコスbot
季節限定感出します(サンタコス以外のbotでも作り方は全く一緒です! 実際、最初は飯テロアプリのつもりでした笑)
####6. おまけ(サンタコスツイートを検索してお気に入り登録(いいね)する)付き
個人的にはおまけの項が一番やりたかったことです笑
#環境
・Ruby 2.1.3
・Ruby on Rails 4.2.4
#目次
Ⅰ Railsアプリにツイートを保存する機能を作る
Ⅱ RailsアプリとTwitterを連動させる
Ⅲ wheneverを使用して自動投稿できるようにする
Ⅳ 完成コード
Ⅴ おまけ(サンタコスツイートを検索してお気に入り登録(いいね)する)
######それでは作っていきましょう(゚∀゚)
##Ⅰ Railsアプリにツイートを保存する機能を作る
この章では、Railsの基礎的な話なのでさくさくいきます!わかる人は飛ばしてください!
####1. アプリを作り始める(慣れているのでmysqlでいきます)
$ rails new santacosbot -d mysql
$ cd santacosbot
最新版(2015年12月6日現在)のmysqlがエラーするので、mysqlの記述を上書き
gem 'mysql2', '0.3.18'
それで
$ bundle install
$ rake db:create
これで最低限の準備は整いました。
####2.ツイートの投稿と保存まで
ルーティング
Rails.application.routes.draw do
root 'tweets#new'
resources :tweets, only: [:new, :create]
end
コントローラー
$ rails g controller tweets
できたコントローラーファイルを以下のように編集
class TweetsController < ApplicationController
def new
@tweet = Tweet.new
end
def create
Tweet.create(create_params)
redirect_to :root
end
private
def create_params
params.require(:tweet).permit(:text, :image)
end
end
ビューファイル(自分しか使わないから見栄えは気にしない方針で)
一応twitterなので140文字の制限だけつけておきます!(追記:画像付きツイートしか保存しない方針なら、116文字で大丈夫だそうです。画像へのリンクが付くことによって入力できる文字数が減るからです。)
<%= form_for @tweet do |f| %>
<%= f.text_area :text, cols: 40, rows: 5 ,maxlength: 140 %>
<%= f.text_field :image %>
<%= f.submit '保存' %>
<% end %>
テーブル・モデル
$ rails g model tweet
で、マイグレーションファイルを以下のように編集
class CreateTweets < ActiveRecord::Migration
def change
create_table :tweets do |t|
t.text :text
t.text :image
t.timestamps
end
end
end
そして、実行
$ rake db:migrate
これで、以下のようなフォームからツイートを保存をすることだけはできるようになったはずです!!
##Ⅱ RailsアプリとTwitterを連動させる
###1.Twitterアカウントを作る(電話番号も登録する)
・すでにあるアカウントを使用しない場合は以下から新規アカウントを作成。
Twitterをはじめましょう
*ちなみに電話番号の登録と認証をしておかないと、下のアプリ登録が出来ないので登録しておきましょう
*一つの電話番号を複数のアカウントに登録できるので、他のアカウントとの兼ね合いの心配は要りません
*電話番号の登録がうまくいかない人は下記を参照
Twitterで携帯電話番号の登録に失敗する
###2.Twitterのアカウントにアプリ登録をする
Twitter Applicant Management
「Create New App」ボタンを押して、設定をはじめましょう。
Name(アプリの名前)、Description(アプリの説明、10文字以上必要)、Website(自分のウェブサイト等)は必須なので入力しましょう。
このうち、Nameはアプリの名前なのでちゃんと書きたいのですが、他はあまり重要でないのでとりあえず埋めておきましょう。
WebsiteはもはやTwitterのURLでもいいです(笑)
###3.必要なキーを入手しよう
・Consumer Key(API key)
・Consumer Secret(API secret)
・Access token
・Access token secret
この4つが、アプリから連携する上で必要なのでこの4つのキーを取得して、記録しておきます。
登録済みアプリのページの「Keys and Access Tokens」のタブからすべて取得できます。
「Keys and Access Tokens」のタブの一番下の「Create my access token」を押します。
そうすると、下記のように必要なキーが取得できます。
ちなみに、access levelの設定が「Read and Write」以上であることを確認してください。違っていたら、「permission」タブから読み込みと書き込みができるように設定を変更しておいてください。
手続きに困ったら下記のサイトを参考にしてください。
RubyでTwitter Botをつくる
これでTwitter側の設定は完了となります!
###4. RailsアプリにTwitterと連携の設定をする
まず、以下のgemを追加
gem 'twitter'
$ bundle install
これでtwitterのgemが使用可能になりました!
基本的に下記の記述をどこかに書けば、twitterと連携することができます。(古いversionのtwitter gemと記述の仕方が異なります。)
client = Twitter::REST::Client.new do |config|
config.consumer_key = "自分のConsumer Key(API key)"
config.consumer_secret = "自分のConsumer Secret(API secret)"
config.access_token = "自分のAccess token"
config.access_token_secret = "自分のAccess token secret"
end
今回は下記のように、controller内に書いてbefore_actionで動かそうかと思います。
class TweetsController < ApplicationController
before_action :twitter_client, except: :new
def twitter_client
@client = Twitter::REST::Client.new do |config|
config.consumer_key = "自分のConsumer Key(API key)"
config.consumer_secret = "自分のConsumer Secret(API secret)"
config.access_token = "自分のAccess token"
config.access_token_secret = "自分のAccess token secret"
end
end
end
これで、@clientに対してツイートするメソッドを実行することで、実際に投稿できるようになります。
そして、投稿するメソッドも書いてルーティングを設定してあげましょう。
def post
tweet = Tweet.order('rand()').first
status = tweet.text
media = open(tweet.image)
@client.update_with_media(status, media)
redirect_to :root
end
Rails.application.routes.draw do
root 'tweets#new'
resources :tweets, only: [:new, :create] do
collection do
get 'post'
end
end
end
そして、とりあえず手動で動かしたいので、ツイートをデータベースに投稿する画面に「ツイート」ボタンを作りましょう。
<hr>
<button type="submit" style = "width: 70px; height: 25px;"><%= link_to 'ツイート', post_tweets_path %></button>
これで「ツイートボタンをおすことで、tweetsテーブルに保存されたツイートからランダムでtwitterに投稿されます。
##基本機能完成
これでとりあえず、ローカルで自分で叩けば動くようになりました(自分しか使わない前提なので見栄えは気にしないでください笑)。
上部に、ツイートしたい文章と、画像のURLを貼ります!
これで、ツイートが保存されます
そして、「ツイート」ボタンを押すと、保存されたツイートからランダムに一件ツイートされます!
そうすると、、、
###Twitterに投稿できました!!ワーイヽ(゚∀゚)メ(゚∀゚)メ(゚∀゚)ノワーイ
##Ⅲ wheneverを使用して自動投稿できるようにする
ここまでは手動でのツイートでしたが、せっかくのbotなので自動でもできるようにしたいですね。ですので、ここからはwheneverのgemを使用します。
まず、以下のgemを追加
gem 'whenever', require: false
$ bundle install
次に、wheneverで動かしやすいようにrakeタスクを作りましょう
$ rails g task twitter
そうすると、lib/tasks以下に'twitter.rake'という名前のファイルができるので編集していきます。
namespace :twitter do
desc "random_tweet"
task :tweet => :environment do
twitter_client
tweet = Tweet.order('rand()').first
status = tweet.text
media = open(tweet.image)
@client.update_with_media(status, media)
end
end
def twitter_client
@client = Twitter::REST::Client.new do |config|
config.consumer_key = "自分のConsumer Key(API key)"
config.consumer_secret = "自分のConsumer Secret(API secret)"
config.access_token = "自分のAccess token"
config.access_token_secret = "自分のAccess token secret"
end
end
基本的にはコントローラにのpostに書いた内容と同じです。これで
$ rake twitter:tweet
のコマンドでツイートができるか確認してみましょう
そして、wheneverでこれを自動化していきましょう
$ wheneverize .
のコマンドを入力して、configにschedule.rbのファイルを作ります。
それを以下のように編集
require File.expand_path(File.dirname(__FILE__) + "/environment")
set :output, 'log/crontab.log'
set :environment, :development
#2時間ごとに動かす
every 2.hours do
rake 'twitter:tweet'
end
とりあえず二時間ごとに設定するために以下のようにしましたが、時間の指定の仕方はいろいろあるので以下を参考にカスタマイズしてください
Wheneverは導入が超簡単なcrontab管理ライブラリGemです![Rails4.2]
これで、あとは、このファイルを起動させれば自動ツイートされます。
$ whenever --update-cron #起動
$ whenever #起動中に起動内容確認
$ whenever --clear-crontab #終了
ですので、一番上の起動のコマンドを打てば動きます!
以上です!!!
これで完成となりますワーイヽ(゚∀゚)メ(゚∀゚)メ(゚∀゚)ノワーイ
完全に全自動になるようにしたい方は、オンラインサーバーにもあげましょう(Herokuを使用する方は一番下の注意の項を読んでください)
#Ⅳ 完成コード
Rails.application.routes.draw do
root 'tweets#new'
resources :tweets, only: [:new, :create] do
collection do
get 'post'
end
end
end
class TweetsController < ApplicationController
before_action :twitter_client, except: :new
def new
@tweet = Tweet.new
end
def create
Tweet.create(create_params)
redirect_to :root
end
def post
tweet = Tweet.order('rand()').first
status = tweet.text
media = open(tweet.image)
@client.update_with_media(status, media)
redirect_to :root
end
def twitter_client
@client = Twitter::REST::Client.new do |config|
config.consumer_key = "自分のConsumer Key(API key)"
config.consumer_secret = "自分のConsumer Secret(API secret)"
config.access_token = "自分のAccess token"
config.access_token_secret = "自分のAccess token secret"
end
end
private
def create_params
params.require(:tweet).permit(:text, :image)
end
end
<%= form_for @tweet do |f| %>
<%= f.text_area :text, cols: 40, rows: 5 ,maxlength: 140 %>
<%= f.text_field :image %>
<%= f.submit '保存' %>
<% end %>
<hr>
<button type="submit" style = "width: 70px; height: 25px;"><%= link_to 'ツイート', post_tweets_path %></button>
gem 'mysql2', '0.3.18'
gem 'twitter'
gem 'whenever', require: false
class CreateTweets < ActiveRecord::Migration
def change
create_table :tweets do |t|
t.text :text
t.string :image
t.timestamps
end
end
end
namespace :twitter do
desc "random_tweet"
task :tweet => :environment do
twitter_client
tweet = Tweet.order('rand()').first
status = tweet.text
media = open(tweet.image)
@client.update_with_media(status, media)
end
end
def twitter_client
@client = Twitter::REST::Client.new do |config|
config.consumer_key = "自分のConsumer Key(API key)"
config.consumer_secret = "自分のConsumer Secret(API secret)"
config.access_token = "自分のAccess token"
config.access_token_secret = "自分のAccess token secret"
end
end
require File.expand_path(File.dirname(__FILE__) + "/environment")
set :output, 'log/crontab.log'
set :environment, :development
every 2.hours do
rake 'twitter:tweet'
end
##Ⅴ おまけ(サンタコスツイートを検索してお気に入り登録(いいね)する)
せっかくなので、railsで旬なサンタコスツイートを検索してお気に入り登録する方法も書いておきますね
個人的にはこれが一番やりたかった
rakeファイルなりコントローラーなりに以下の記述すればできます(ここではrakeファイルに書いた場合)
namespace :twitter_search do
desc "favorite_santa_tweet"
task :tweet_search => :environment do
twitter_client
query = "#サンタコス"
results = @client.search(query, count: 100, result_type: "recent", exclude: "retweets", filter: "images")
results.take(100).each do |tw|
@client.favorite(tw.id)
end
end
end
def twitter_client
@client = Twitter::REST::Client.new do |config|
config.consumer_key = "自分のConsumer Key(API key)"
config.consumer_secret = "自分のConsumer Secret(API secret)"
config.access_token = "自分のAccess token"
config.access_token_secret = "自分のAccess token secret"
end
end
基本的にコードみればわかると思いますが、searchメソッドで検索して、takeメソッドで件数の指定をした上でお気に入り登録していきます。
ちなみにお気づきの方もいるかと思いますが、このgemのメソッドを使用すれば、ツイートを検索して取得できます。
つまり、そこから画像を取得してデータベースに保存することも、、、いわゆるスクレイピングですね笑
そうすればそこからその画像を再利用してツイートすることもできちゃいますね笑
ただ、それを本当にやっていいのかわからないのと、同じadvent calenderの【Swift】Twitter APIを使ってサンタコス女子を探すとやってることがかなりかぶるのでここでは書きません笑
やりたい方は、上記のリンクを見てみてください(swiftわからなくてもわかります笑)
以上で終了となります。このように、Twitterのgemを使うと遊べることがたくさんありますね笑
(ネットストーカー御用達ですね)
とりあえず、今回はこれで終わりにしますが、またTwitter関連で記事を書こうかなと思います!
#注意
・アカウント凍結に注意しましょう。
Twitterでは、一定時間内に投稿できる件数が決まっております。また、一定時間内に同じツイートを連続投稿するのもまずいみたいです。うまく動かなくてツイートボタンを連打してたらアカウント凍結されてたみたいにならないようにしましょう笑
・このままHerokuなどのサーバーにアップする場合は、ビューのツイートボタンにパスワードの入力フォームを入れて、postアクションにパスワード認証をつける
これは上記のアカウント凍結を避けるためです。Herokuなどにあげると、もし第三者がアクセスできてしまった場合に、ツイートボタンを押されないようにするためです。
・Herokuでは、wheneverは機能しない
wheneverによる自動ツイートを残したままオンラインサーバーにあげたいときはさくらVPSあたりを使用しましょう
Herokuでやる場合は、アドオンのschedulerを使用しましょう。
heroku schedulerの使い方(Rails,sinatra)
#参考
[Rails4] wheneverを使ってcrontabを管理して、cronを回す
3分でスッキリ! Oauth 1.0図解とRuby Twitter bot開発
rubyでtwitterのbotを実装する(第5世代のやり方)
Wheneverは導入が超簡単なcrontab管理ライブラリGemです![Rails4.2]