0
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 3 years have passed since last update.

RubyでTwitterBotを作って天気予報をツイートする

Last updated at Posted at 2021-05-02

#はじめに
WebAPIとRubyの勉強を目的に、TwitterBotを作りました。

WebアプリとしてHerokuにデプロイし、HerokuSchedulerを用いて、毎日7:30に東京の天気を画像付きでツイートします。

image.png

#背景
女児向けアニメの『アイカツ!』という作品内で、主人公の大空あかりちゃんがお天気キャスターとして活躍するのですが、それを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']で呼び出しています。

tweet.rb
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の関数ファイル

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
WeatherInfo.rb
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を実行でツイートされます。

app.rb
require 'sinatra'
require_relative 'tweet.rb'

get '/' do
  'under constraction'
end

get '/send_tweet' do
  'Closed'
end

###config.ru
Sinatraということを認識させる記述を行っています。

config.ru
require_relative 'app.rb'
run Sinatra::Application

###imagesフォルダ
添付する画像フォルダ
image.png

#HerokuSchedulerで定期的に動かす
Herokuにデプロイし、Schedulerアドオンを使って毎日7:30に動くようにします。
コマンドの欄は、bundle exec ruby tweet.rb
参考記事

またHerokuにデプロイ後、Heroku側でも環境変数の設定が必要とのことで設定します。
参考記事

#さいごに
以上が、天気情報を毎日ツイートするTwitterBotの制作過程でした。
TwitterBotの制作記事はたくさんあるので、参考記事には困りませんでした。
WebAPIを使うのは初めてでしたが、特に問題もなく導入できたので良かったと思います。

#参考
・TwitterBot

・天気情報取得方法

・HTTPClient

・Heroku 環境変数

0
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
0
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?