line-bot〜messageAPI-push機能の実装(Rails)〜

# line-bot〜push機能の実装方法(Rails)について〜

## 概要
調べてもあまり出てこなかったので、自分用のメモとして投稿します。
line-bot message APIのpush機能の実装方法です。（Railsで実装。）

push機能とは、LINEからのリクエスト無し（入力メッセージ無し）で、こちらからメッセージを送る機能のことです。

例：下記の「テストです〜」以下のメッセージがpush機能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425897/0f0d049e-1bd7-8e70-c373-894d96bc0264.png)

## 動作環境
-ruby 2.5.1
-Rails 5.2.3

## 手順リスト
1. taskファイルを「lib/task/」以下に作成し、タスク（処理）を記載する。（この中にpush機能のコードを書きます。）
2. gem 'whenever'を導入し、schedule.rbにさきほどのタスクをいつ処理させるか記載する。

今回は「whenever」というgemを用いて実装します。
wheneverについては下記の記事を参考ください。

　[初学者]whenever を使って定期的にバッチ処理を行う(公開設定編)
　https://qiita.com/shi-ma-da/items/e281331e34a43c0b05d4

###1.taskファイルを「lib/task/」以下に作成し、タスク（処理）を記載する。（この中にpush機能のコードを書きます。）

```lib/tasks/push.rake
namespace :push_line do 
  desc "push_line"
  task push_line_message_morning: :environment do # 以下にpush機能のタスクを書く。
    message = {
      type: 'text',
      text: '朝になりました。本日も頑張りましょう。食べた食べ物を「ひらがな」で入力すると、食品のカロリーと本日のトータルカロリーが表示されます。入力ミスの場合、「みす」と入力すると最新の入力を消去できます。カロリー計算に使ってください。'
    }
    client = Line::Bot::Client.new { |config|
      config.channel_secret = ENV["LINE_CHANNEL_SECRET"]
      config.channel_token = ENV["LINE_CHANNEL_TOKEN"]
    }
    response = client.push_message(ENV["LINE_CHANNEL_USER_ID"], message)
    p response
  end
end
```
**処理が走るか確認する。**

```:タスク一覧を表示
rails -T
```
**表示された一覧の中に以下のタスクがOKです。**

```:タスク一覧
...
...
rails push_line:push_line_message_morning  
...
```

これでタスクの設定は完了です。続いて、スケジュールを設定していきます。

###2. gem 'whenever'を導入し、schedule.rbにさきほどのタスクをいつ処理させるか記載する。

```ruby:Gemfile
gem 'whenever', require: false  # gem 'whenever'を追加する。
```

```:schedule.rbファイルを生成する。
$ bundle exec wheneverize . 

>[add] writing `./config/schedule.rb'
>[done] wheneverized!
```

```ruby:config/schedule.rb
require File.expand_path(File.dirname(__FILE__) + "/environment")

rails_env = ENV['RAILS_ENV'] || :development

set :environment, rails_env
set :output, "#{Rails.root}/log/cron.log"

every 1.day, at: ['7:00 am'] do # タスクを処理するペースを記載する。（例は毎朝7時に実行）
  rake 'push_line:push_line_message_morning'
end

#最初は「every 10.minutes do」（10分ごと）とかにして動作するか確かめました。
```

```:エラーがないか確認
$ bundle exec whenever

# 以下のような表示が出ればOK.
0,10,20,30,40,50 * * * * /bin/bash -l -c 'cd /Users/ユーザー名/projects/ディレクトリ名 && RAILS_ENV=development bundle exec rake push_line:push_line_message_morning --silent >> /Users/ユーザー名/projects/ディレクトリ名/log/cron.log 2>&1'

## [message] Above is your schedule file converted to cron syntax; your crontab file was not updated.
## [message] Run `whenever --help' for more options.
```

```:現在のcronの設定確認(おそらく何も設定されてないと思います。人によります。)
$ crontab -l
```
```:wheneverの設定更新（schedule.rbの内容でcronに登録。）
$ RAILS_ENV=development bundle exec whenever --update-crontab

> [write] crontab file updated
```
```:(crontabの設定を削除する場合)(実行する必要ない。)
& RAILS_ENV=development bundle exec whenever --clear-crontab
```

以上で設定完了です。
設定時間後にLINEへメッセージが自動で送信されれば問題ありません！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425897/0f0d049e-1bd7-8e70-c373-894d96bc0264.png)


ちなみに２個以上のタスクを実行したい場合は以下のようにすればいいです。

```ruby:lib/tasks/push.rake
namespace :push_line do 
  desc "push_line" # このタスクの説明を書く
  task push_line_message_morning: :environment do
    message = {
      type: 'text',
      text: '朝になりました。本日も頑張りましょう。食べた食べ物を「ひらがな」で入力すると、食品のカロリーと本日のトータルカロリーが表示されます。入力ミスの場合、「みす」と入力すると最新の入力を消去できます。カロリー計算に使ってください。'
    }
    client = Line::Bot::Client.new { |config|
      config.channel_secret = ENV["LINE_CHANNEL_SECRET"]
      config.channel_token = ENV["LINE_CHANNEL_TOKEN"]
    }
    response = client.push_message(ENV["LINE_CHANNEL_USER_ID"], message)
    p response
  end
# 以下のタスクを追加。
  task push_line_message_night: :environment do
    message = {
      type: 'text',
      text: '夜10時になりました。本日もお疲れ様でした。'
    }
    client = Line::Bot::Client.new { |config|
      config.channel_secret = ENV["LINE_CHANNEL_SECRET"]
      config.channel_token = ENV["LINE_CHANNEL_TOKEN"]
    }
    response = client.push_message(ENV["LINE_CHANNEL_USER_ID"], message)
    p response
  end
end
```
```ruby:config/schedule.rb
require File.expand_path(File.dirname(__FILE__) + "/environment")

rails_env = ENV['RAILS_ENV'] || :development

set :environment, rails_env
set :output, "#{Rails.root}/log/cron.log"

every 1.day, at: ['7:00 am'] do
  rake 'push_line:push_line_message_morning'
end
# 以下のスケジュールを追加。
every 1.day, at: ['10:00 pm'] do
  rake 'push_line:push_line_message_night'
end
```

最後に、何か間違いや指摘等あれば頂けると幸いです。

## 参考

[初学者]whenever を使って定期的にバッチ処理を行う(公開設定編)
https://qiita.com/shi-ma-da/items/e281331e34a43c0b05d4

LINE Messaging APIを使ってランダムな写真を送信する
https://qiita.com/ogibayashi/items/6a65f2073bbc1ab0e6b3

ローカルで始めるLINE bot @Ruby 
https://qiita.com/4geru/items/aa076fa57d1913312307