登山仲間と登山に行くときに天気をググってURLをLineグループで共有することがよくあるので、少しでも手順を簡略化するために山の天気を教えてくれるLinebotを作ることにしました。
※注意
この記事ではHerokuやLINE Developersを使っています。
HerokuやLINE Developersは次々に仕様が変わっていくので料金など重要な情報は公式情報を確認するようにしてください。
2022/08/26追記
この記事で使っていたHerokuの無料プランは2022年11月に廃止されることが決定しました。
仕様
Lineで「○○山 天気」とコメントすると、Linebotがその山の天気予報ページをコメントしてくれる。
botがコメントする天気ページは下記の「てんきとくらす」を使っています。山の天気がわかるので大変お世話になっているサイトです。
サイトポリシーに『・本サイトへのリンクは原則自由であり、事前連絡も必要ありません。』と書いてあるので堂々と使って大丈夫でしょう。
https://tenkura.n-kishou.co.jp/tk/policy.html
システム構成
インフラ
Lineメッセージを解析して該当の天気URLを返却するAPIサーバーは、1アプリを動かすだけであれば料金がかからないherokuのFreeプランを使うことにしました。
DBも10,000行までであれば無料で使えます。
(※2019年7月時点)
https://jp.heroku.com/pricing
Line Developers
Linebotを作るにはLine Developersに登録する必要があります。
https://developers.line.biz/
登録方法は下記記事と同じなのでこの記事では省略します。
GCPを使って日次のLine push通知を作ってみた
上記の他にWebhookの設定が必要ですが、それはherokuの環境構築ができた後に設定するので後述します。
開発環境
Ruby on Railsで開発しました。
DBはherokuにあわせてpostgres。
ソース管理はheroku内のgithubを使うこともできるが、自分のgithubで管理したかったので自分のgithub経由でherokuへデプロイするようにしました。
開発環境ではdockerを使っています。
開発
開発環境構築
Dockerを使って開発環境を構築します。
最初にDockerfile, docker-compose.yml, Gemfile, Gemfile.lockを作成します。
FROM ruby:2.6.3
RUN curl -sL https://deb.nodesource.com/setup_10.x | bash -
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
RUN apt-get update -qq && apt-get install -y build-essential nodejs yarn postgresql-client
RUN mkdir -p /app
WORKDIR /app
COPY Gemfile Gemfile.lock ./
RUN gem update bundler
RUN bundle install
COPY . .
CMD ["rails", "server", "-b", "0.0.0.0"]
version: '3'
services:
web:
build: .
command: bundle exec rails s -p 3000 -b '0.0.0.0'
environment:
DATABASE_HOST: db
DATABASE_PORT: 5432
DATABASE_USER: postgres
DATABASE_PASSWORD:
links:
- db
volumes:
- .:/app
ports:
- 3000:3000
tty: true
stdin_open: true
db:
image: postgres:11.3
ports:
- "5432"
volumes:
- db-volume:/var/lib/postgresvolumes
volumes:
db-volume:
Railsのバージョンはなんでもよかったので現時点で最新の6にしてみた。
source 'https://rubygems.org'
gem 'rails', '6.0.0.rc1'
Gemfile.lockは空
ファイルが準備できたらdocker上にrails環境を構築します。
まずは環境をビルドします。
# build
docker-compose build
続いてdocker上にrails環境を生成します。
# rails new
docker-compose run web bundle exec rails new . --database=postgresql --skip-test
データベースの設定を行います。
development, test環境のアカウントは適当にpostgres/passwordにしました。(環境変数で変更もできます)
productionはherokuで発行されるurlを環境変数DATABASE_URL
で指定できるようにしています。
default: &default
adapter: postgresql
encoding: unicode
development:
<<: *default
database: db_development
host: <%= ENV.fetch('DATABASE_HOST') { 'localhost' } %>
port: <%= ENV.fetch('DATABASE_PORT') { 5432 } %>
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: <%= ENV.fetch('DATABASE_USER') { 'postgres' } %>
password: <%= ENV.fetch('DATABASE_PASSWORD') { 'password' } %>
test:
<<: *default
database: db_test
host: <%= ENV.fetch('DATABASE_HOST') { 'localhost' } %>
port: <%= ENV.fetch('DATABASE_PORT') { 5432 } %>
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: <%= ENV.fetch('DATABASE_USER') { 'postgres' } %>
password: <%= ENV.fetch('DATABASE_PASSWORD') { 'password' } %>
production:
<<: *default
url: <%= ENV['DATABASE_URL'] %>
database: db_production
rails環境の準備ができたのでサーバーを起動します。
# サーバー起動(docker-composeのcommandをバックグランドで起動)
docker-compose up --build -d
http://localhost:3000/ で接続確認。
下記が表示されれば疎通OKです。
実装
line-botを実装します。
rubyで実装する場合、'line-bot-api'というgemを使うと良いです。
githubにLinebotのサンプルもあるので参考にして作りました。sinatraを使っているのでRailsで作る場合は少し読み替える必要はあります。
https://github.com/line/line-bot-sdk-ruby
私は下記のように実装しました。基本、サンプルと同じように作っています。
post '/callback' => 'linebot#callback'
#
# yamasテーブルに山の名称(name)、URLを作るためのcode、typeを保持しています。
#
class Yama < ApplicationRecord
self.inheritance_column = :_type_disabled
class << self
def find_by_message(message)
# あんまりイケてないけど全部の山の名称を1件ずつメッセージに含まれているか確認して
# 含まれていたらその山情報を返却する。
# 本当は全文検索とかした方が良いと思うけどデータ数少なくてこれでも困っていないのでとりあえずこれで;;
all.find_each do |yama|
return yama if message =~ /#{yama.name}/
end
end
end
def url
"https://tenkura.n-kishou.co.jp/tk/kanko/kad.html?code=#{code}&type=#{type}&ba=hk"
end
end
class LinebotController < ApplicationController
require 'line/bot'
protect_from_forgery except: [:callback]
def callback
body = request.body.read
signature = request.env['HTTP_X_LINE_SIGNATURE']
unless client.validate_signature(body, signature)
head :bad_request
return
end
events = client.parse_events_from(body)
events.each { |event|
case event
when Line::Bot::Event::Message
case event.type
when Line::Bot::Event::MessageType::Text
# メッセージに"天気"という文字が入っているか確認。入っていなければSKIP
next unless event.message['text'] =~ /天気/
if yama = Yama.find_by_message(event.message['text'])
# 山が見つかればメッセージを生成してreplyする
reply_text = "#{yama.name}の天気\n#{yama.url}"
message = {
type: 'text',
text: reply_text
}
client.reply_message(event['replyToken'], message)
end
end
end
}
head :ok
end
private
def client
@client ||= Line::Bot::Client.new do |config|
config.channel_secret = ENV["LINE_CHANNEL_SECRET"]
config.channel_token = ENV["LINE_CHANNEL_TOKEN"]
end
end
end
実装が終わったら自身のgithubへPushしましょう。
heroku
環境構築
app新規作成
herokuのdashboardを開き、"Create new app"を選択します。
Deployタブ
Deployment methodで"GitHub"を選択して、Connect to GitHubで先ほどpushしたリポジトリを選択します。
Resourcesタブ
Add-onesで"Heroku Postgres"を検索して選択します。
Hobby Dev-Freeを選択して、Provision
これでpostgresが利用できます。
念のため、同ページに記載されているEstimated Monthly Costが$0.00(費用がかかっていない)ことも確認しておきましょう。
Postgres
先ほど作成したHeroku PostgresがリンクになっているのでそこをクリックしてPostgresの情報を確認します。
リンク先のSettingsタブにDatabase Credentialsという項目があるのでView Credentials...をクリックします。
その中に表示される"URI"をDB接続で利用します。
Settingsタブ
SettingsタブのConfig Varsに必要な環境変数を足します。
DATABASE_URLはすでに設定されていると思いますが、もしなければ先ほど確認したpostgresのURIを設定します。
LINE_CHANNEL_SECRET、LINE_CHANNEL_TOKENはLineDevelopersで作成したチャンネルページに記載されているものを設定します。(LINE_CHANNEL_TOKENはLINE Developersのアクセストークンのことです)
あとはRailsで必要な諸々の環境変数を設定します。
同じタブに"Domains and certificates"にURLが記載されているので、それに"/callback"をつけたものがWebhookURLです。
Deploy
Deployタグの下部にある"Manual deploy"をクリックしてデプロイします。
データを入れる
Postgresを使っているので必要に応じてデータを入れてください。
Rails consoleが使えるのでHerokuのドキュメントを参考にしてください。
https://devcenter.heroku.com/articles/getting-started-with-rails5#run-the-rails-console
Webhookの設定
HerokuのSettingsタブで確認したWebhookURLをLINEDevelopersのWebhook URLに設定します。
個別で利用するだけならこれだけでOKですが、もしLINEグループにこのチャンネルを友達追加したい場合はすぐ下にある"Botのグループトーク参加"を利用するにする必要があります。
最後に
ここまできたらあとはLine上で話しかけるだけです。Let's talking!!
実際に作成した時とこの記事を書くまでに時差があり、手順が間違っていたり抜けていたりするかもしれないのでおかしな点があればご指摘いただけるとありがたいです。
herokuのログはheroku logs
で確認できるのでrailsがうまく動かない場合は参照してみてください。
https://devcenter.heroku.com/articles/getting-started-with-rails5#view-logs