#はじめに
WebAPIとRubyの勉強を目的に、TwitterBotを作りました。
WebアプリとしてHerokuにデプロイし、HerokuSchedulerを用いて、毎日7:30に東京の天気を画像付きでツイートします。
#背景
女児向けアニメの『アイカツ!』という作品内で、主人公の大空あかりちゃんがお天気キャスターとして活躍するのですが、それをBotとして作った次第です。
朝に東京の天気もわかるし、推しの画像も見られるので一石二鳥です。
#TwitterBotの導入
下記の記事を参考にしました。
・導入記事1
・導入記事2
#インストールしたGem
source 'https://rubygems.org'
ruby '2.5.1'
gem 'sinatra'
gem 'twitter' //TwitterAPI通信用
gem 'httpclient' //WebAPI通信用
gem 'dotenv' //環境変数設定用
#TwitterBotのコード
###ディレクトリの構成
(一部抜粋)
~twitter_bot
|- images // ツイートに添付する画像フォルダ
|- otenki0.jpg
|- ...
|- otenki22.jpg // 23枚ほど用意
|- src // 天気情報を取得するフォルダ
|- Weather.rb // API接続からデータ加工処理を行うファイル
|- WeatherInfo.rb // Weather.rbの関数ファイル
|- .env // TwitterAPIのコンシューマーキーやアクセストークンを格納
|- app.rb // Webアプリのメインファイル
|- config.ru // Webアプリの設定ファイル
|- Gemfile // 使用するgemを管理するファイル
|- tweet.rb // ツイート処理ファイル
###tweet.rb
ツイート処理ファイルです。
画像を添付してツイートするのに加えて、srcフォルダから天気情報を取得しています。
.envに書いたキーとトークンをENV['hoge_hoge']で呼び出しています。
require 'date'
require 'twitter'
require 'dotenv/load'
require "./src/Weather"
require "./src/WeatherInfo"
class Tweet
def initialize
# 投稿内容の初期化
@text = ""
# クライアントの生成
@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
# Tweetの投稿処理呼び出し
def send_tweet
create_text
update
end
# ツイート本文の生成
def create_text
# 天気情報取得
weatherobj = Weather.new
info = weatherobj.doProcess()
# ツイート部分
@text = "みなさんおはようございます!時刻は7時30分!\n"
@text += "今日のお空はどんな空~❓\n大空お天気の時間です✨\n"
@text += "今日の都心部は#{info.todayTelop()}、最高気温は#{info.todayTempMax()}℃です!\n"
@text += "それでは通勤・通学気をつけて、行ってらっしゃ~い!"
end
private
# Tweet投稿処理
def update
begin
# 画像添付部
images = []
range = 0..22
range.each{|i|
images << File.new("./images/otenki#{i}.jpg")
}
@client.update_with_media(@text,images.sample)
rescue => e
p e # エラー時はログを出力
end
end
end
# ツイートを実行
if __FILE__ == $0
Tweet.new.send_tweet
end
###srcフォルダ
天気予報APIから東京の天気をJSON形式で取得します。
HTTPClientライブラリを用いることで、外部へHTTPリクエストを送ることができます。
・Weather.rb: API接続からデータ加工処理を行うクラス
・WeatherInfo.rb: Weather.rbの関数ファイル
# API接続からデータ加工処理を行うクラス
require 'httpclient'
require 'resolv'
require 'json'
require './src/WeatherInfo'
class Weather
@@DESCRIPTION = "description"
@@TEXT = "text"
@@FORECASTS = "forecasts"
@@TELOP = "telop"
@@DATE = "date"
@@TEMPERATURE = "temperature"
@@CELSIUS = "celsius"
@@MIN = "min"
@@MAX = "max"
@@TODAY = 0
@@TMRW = 1
# コンストラクタ
def initialize()
end
# メイン処理メソッド
def doProcess()
# 拠点コード(東京)
keyWord = '130010'
# 天気API URL取得
url = 'https://weather.tsukumijima.net/api/forecast'
return analysisWeather(connectionAPI(keyWord, url))
end
# API接続部
# 戻り値:ハッシュ化されたレスポンス
def connectionAPI(keyWord, url)
# http接続クライアントの生成
client = HTTPClient.new
# 指定した拠点のコードをリクエストに設定する。
query = { 'city' => keyWord }
# APIリクエスト
res = client.get(url, query)
# ハッシュ化して返却
return JSON.parse(res.body)
end
# 天気情報をHashより解析する
def analysisWeather(hash)
info = WeatherInfo.new
# 概要の取得
info.description=(convertNil(hash.dig(@@DESCRIPTION, @@TEXT)))
# 今日の天気情報
info.todayTelop=(convertNil(hash.dig(@@FORECASTS, @@TODAY, @@TELOP)))
info.today=(convertNil(hash.dig(@@FORECASTS, @@TODAY, @@DATE)))
info.todayTempMin=(convertNil(hash.dig(@@FORECASTS, @@TODAY, @@TEMPERATURE, @@MIN, @@CELSIUS)))
info.todayTempMax=(convertNil(hash.dig(@@FORECASTS, @@TODAY, @@TEMPERATURE, @@MAX, @@CELSIUS)))
# 明日の天気情報
info.tmrwTelop=(convertNil(hash.dig(@@FORECASTS, @@TMRW, @@TELOP)))
info.tmrw=(convertNil(hash.dig(@@FORECASTS, @@TMRW, @@DATE)))
info.tmrwTempMin=(convertNil(hash.dig(@@FORECASTS, @@TMRW, @@TEMPERATURE, @@MIN, @@CELSIUS)))
info.tmrwTempMax=(convertNil(hash.dig(@@FORECASTS, @@TMRW, @@TEMPERATURE, @@MAX, @@CELSIUS)))
return info
end
# nil判定、nilの場合は「-」を返却
def convertNil(value)
return value == nil ? "-" : value
end
end
class WeatherInfo
attr_accessor :description,
:todayTelop,
:today,
:todayTempMin,
:todayTempMax,
:tmrwTelop,
:tmrw,
:tmrwTempMin,
:tmrwTempMax
:comment
# コンストラクタ
def initialize()
end
# 概要
def description()
@description
end
# 概要
def description=(value)
@description = value
end
# 本日テロップ
def todayTelop()
@todayTelop
end
# 本日テロップ
def todayTelop=(value)
@todayTelop = value
end
# 本日最低気温
def todayTempMin()
@todayTempMin
end
# 本日最低気温
def todayTempMin=(value)
@todayTempMin = value
end
# 本日最高気温
def todayTempMax()
@todayTempMax
end
# 本日最高気温
def todayTempMax=(value)
@todayTempMax = value
end
# 明日テロップ
def tmrwTelop()
@tmrwTelop
end
# 明日テロップ
def tmrwTelop=(value)
@tmrwTelop = value
end
# 明日最低気温
def tmrwTempMin()
@tmrwTempMin
end
# 明日最低気温
def tmrwTempMin=(value)
@tmrwTempMin = value
end
# 明日最高気温
def tmrwTempMax()
@tmrwTempMax
end
# 明日最高気温
def tmrwTempMax=(value)
@tmrwTempMax = value
end
# コメント
def comment()
@comment
end
# 明日最高気温
def comment=(value)
@comment = value
end
end
###app.rb
Webアプリのメインファイルです。
TwitterBotをHerokuで動かすためにSinatraでWebアプリにしています。
/send_tweetを実行でツイートされます。
require 'sinatra'
require_relative 'tweet.rb'
get '/' do
'under constraction'
end
get '/send_tweet' do
'Closed'
end
###config.ru
Sinatraということを認識させる記述を行っています。
require_relative 'app.rb'
run Sinatra::Application
#HerokuSchedulerで定期的に動かす
Herokuにデプロイし、Schedulerアドオンを使って毎日7:30に動くようにします。
コマンドの欄は、bundle exec ruby tweet.rb
参考記事
またHerokuにデプロイ後、Heroku側でも環境変数の設定が必要とのことで設定します。
参考記事
#さいごに
以上が、天気情報を毎日ツイートするTwitterBotの制作過程でした。
TwitterBotの制作記事はたくさんあるので、参考記事には困りませんでした。
WebAPIを使うのは初めてでしたが、特に問題もなく導入できたので良かったと思います。
#参考
・TwitterBot
・天気情報取得方法
・HTTPClient
・Heroku 環境変数