はじめに
今回の記事は GraphQL API を叩いて毎朝電気代が届くLine Botを開発する
の後編の記事となります。
今回は、rake
を使用して、定期実行用のタスクを作成していくのと
Render
のCron Job
を使用して定期実行を設定する方法について解説していきます!
前回の記事はこちらになります。
実装方針
1.Rails側からGraphQL叩いて電気代を取得出来るようにする
2.Line Messaging APIを利用して、取得した電気代情報をユーザーに送信する機能の実装
-- 今回はここから下 --
3.開発環境で定期実行用のタスクを作成する
4.本番環境で定期実行を行えるようにする
開発環境で定期実行用のタスクを作成する
今回定期実行用のタスクを作成するために、rake
タスクを使用していきます。
rakeタスクは lib/tasks
の配下に作成する必要があります。
$ rails g task file_name
また、上記コマンドでも作成することが出来ます!
今回は下記コマンドを実行して作成してみましょう。
$ rails g task line_notification
すると下記のようなファイルが作成されると思います。
namespace :line_notification do
end
さて、上記を以下のように変更します。
namespace :line_notification do
desc "Send billing notification" # タスクの説明 description(説明)
task send_billing_notification: :environment do # task名(`send_billing_notification`) 自由に命名可
# 実行したいロジック
# 有効なRubyコードなら何でも書ける
OctopusEnergyBillController.new.index
end
end
ただ今回のコード、タスクを叩けば実際にLINEの通知が送られて
動作的に問題がありませんが良くない部分があります。
以下引用
Action Controllerは、MVCアーキテクチャの「C」に相当します。リクエストを処理するコントローラがルーティング設定によって決定されると、コントローラはリクエストの意味を理解して適切な出力を行う役目を担います。
上記を見ての通り、今回の場合はリクエストを処理するわけではないので
適切ではありません(まあ動きはしますが)。
ですので今回はapp/controllers/octopus_energy_bill_controller.rb
の
実装を サービスクラスに移植します!
その前に軽く説明しておくと、サービスクラスとは
ビジネスロジックを実装するためのパターンの1つです。
コントローラーやモデルからビジネスロジックを分離する、役割を果たします。
詳しくは、下記の記事に詳しく解説してあります(自分も下記記事見て勉強した)
。
コードは以下のようになります。
class OctopusEnergyBill
GetBillQUERY = OctopusClient::Client.parse <<~'GRAPHQL'
query(
$accountNumber: String!
$fromDatetime: DateTime
$toDatetime: DateTime
) {
account(accountNumber: $accountNumber) {
properties {
electricitySupplyPoints {
agreements {
validFrom
}
halfHourlyReadings(
fromDatetime: $fromDatetime
toDatetime: $toDatetime
) {
startAt
endAt
value
costEstimate
consumptionStep
consumptionRateBand
}
}
}
}
}
GRAPHQL
def notify
result = OctopusClient::Client.query(GetBillQUERY, variables: {
accountNumber: ENV['OCTOPUS_ACCOUNT_NUMBER'],
fromDatetime: Date.yesterday.beginning_of_day.iso8601,
toDatetime: Date.yesterday.end_of_day.iso8601
})
properties = result.original_hash.dig("data", "account", "properties")
electricity_supply_points = properties.first["electricitySupplyPoints"]
half_hourly_readings = electricity_supply_points.first["halfHourlyReadings"]
@kwh = half_hourly_readings.pluck("value").map(&:to_f).sum
@cost = half_hourly_readings.pluck("costEstimate").map(&:to_f).sum
text = "#{Date.yesterday.strftime('%Y年%m月%d日')}は#{@kwh.round(2)}kWh消費して#{@cost}円かかったよ"
message = {
type: 'text',
text: text
}
LineBotClient.new.client.broadcast(message)
end
end
rake
タスクで実行するするインスタンスメソッドも下記のように変更します。
namespace :line_notification do
desc "Send billing notification"
task send_billing_notification: :environment do
# コントローラーだけはなく、サービスメソッドから呼び出すように変更
- OctopusEnergyBillController.new.index
+ OctopusEnergyBill.new.notify
end
end
さて、コマンドを実行してみましょう!
$ rake line_notification:send_billing_notification # rake namespace:task_name
すると...
予想通り、Lineに電気代の通知が届きます!
4.本番環境で定期実行を行えるようにする
今回は、Render の Cron Jobs使用して定期実行を行なっていきます!
そもそもRenderとは?
一言で言うと、WebアプリケーションをGithubと連携して簡単にデプロイできるPaasサービスです。
heroku
が有料サービスのみの提供になりましたが、render
に関しては
アプリケーションの実行時間は750時間・パイプラインの実行時間に関しては、500分まで無料です!
データベースに関しても、90日間まで無料ですので検証用や個人のポートフォリオであれば問題ないかなと思います。
今回はそのRenderの中の定期実行させるための機能、 Cron Jobs を使用していきます!
因みに料金は以下に乗っています。
基本的に 1ヶ月1ドルが最低料金となり、インスタンスタイプ毎に1分毎に従量課金が行われていきます。
また、主要な設定について説明いたします。
項目 | 説明 |
---|---|
Name | Cronのユニークな名前 |
Branch | Cronjobが実行されるブランチ、今回テスト用で作業ブランチ・テスト完了後にmainで設定した。 |
Runtime | どの言語・環境で実行するか選択する。(例:Ruby,Docke,Go) |
Build Command | 新しいバージョンのコードをデプロイ・ないしは設定を変更した際に実行するコマンド |
Schedule | cron式に設定(例:30(分) 23(時) *(日) *(月) *(曜日 0-6 0が日曜) |
Command | Scheduleに従って実行するコマンド(例:rake line_notification:send_billing_notification ) |
また、時刻が23時30分と定義されているのは、UTC(協定世界時)とJST(日本標準時)で9時間時差があるので、
実際に実行されるのは日本時間の08:30になります。
次に、設定が終わったらEnvironmentから .env
で設定した環境変数も
同様に定義しておいてください!
また、SECRET_KEY_BASE
に関してはデプロイ時にエラーが発生したため環境変数と
config/secrets.yml
に定義いたしました。
production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
少し補足しておくと、secrets.yml
は暗号化通信通信のための設定ファイルでsecret_key_base
を設定し通信を暗号化します。
さて、全ての設定が終了したら実際にcronが実行されるか確認します。
毎朝8時半に電気代の通知が来ることが確認できました!!
最後に
いかがでしたでしょうか。
以上で「GraphQL API を叩いて毎朝電気代が届くLine Botを開発」が完了です!!
また、オマケ版としてAWS Lambda
とCloudWatch Events
を使用して、
定期実行する記事もいずれ執筆しようと思います。
ソースコードの方は下に置いておきます。
最後まで読んでいただきありがとうございました!!
参考文献