Goを使って、気圧低下をお知らせするLINE botを作ってみました。
1時間に1回、気圧の状態をチェックして、注意・警戒の場合は状態の場合は通知するようになっています。
(トド丸くんというのは我が家でいろいろお知らせ通知をしてくれる子です
最初はtodoリストを通知するのが目的だった子なので、トド(todo)丸です)
※今回はグループにLINE botを招待し、そこで通知する仕組みにしているのですこし特殊です
今回実装したアプリのソースコードは以下にて公開しています
LINE developersの設定
-
上記のLINE developers の公式ドキュメント「Messaging APIを始めよう」に則ってチャンネル作成をします
-
チャンネルを開き、「チャンネル基本設定」を開きます(デフォルトで開かれます)
-
基本情報内のチャネルシークレットをメモしておきます
-
一番下までいくと、「チャンネルアクセストークン」という項目があるので、そこの「発行」ボタンを押下します
-
チャンネルアクセストークンが表示されるのでメモしておきましょう
GitHubリポジトリの作成
GitHubリポジトリを作成します
"Add .gitignore" にチェックを入れ、"Go"を選択し、リポジトリを作成します
アプリの実装
ここからとにかく実装します
全体のコードは冒頭で紹介したGitHubのリポジトリにあげてあるのでそちらをみていただけたらと思います
(レイヤードアーキテクチャで実装しているので、少し読みにくい部分があるかもしれません。ご了承ください。。。)
ここでは、LINE botでのメッセージ配信部分と、気圧情報取得部分のみご紹介します
LINE botでメッセージを配信する
メッセージ配信部分のメソッドはこちらになります。
※今回はグループにLINE botを招待し、そこで通知する仕組みにしているのでルームIDが必要になります
ルームIDの取得方法はこちらを参考にしました
参考:トークルームの roomId を調べる方法 - Qiita
func (s *LineStore) Post(message string) error {
_, err := s.bot.PushMessage(s.roomID, linebot.NewTextMessage(message)).Do()
if err != nil {
s.logger.Error(err.Error())
return err
}
return nil
}
参考:Messaging APIリファレンス | LINE Developers
気圧情報を「頭痛ーる」から取得する
今回は、株式会社ポッケさんの頭痛ーるを利用させていただきます
そして、こちらのリンクを大いに参考にさせていただきました
ありがとうございます
参考:低気圧で頭痛がひどいのでslackで頭痛ーるを表示するappをlambdaで作った
試しに東京都新宿区の気圧情報を取得してみます
$ curl https://zutool.jp/api/getweatherstatus/13104 | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 8261 0 8261 0 0 41722 0 --:--:-- --:--:-- --:--:-- 41512
{
"place_name": "東京都新宿区",
"place_id": "104",
"prefectures_id": "13",
"dateTime": "2021-09-24 13",
"yesterday": [
{
"time": "0",
"weather": "200",
"temp": "25.9",
"pressure": "1009.8",
"pressure_level": "2"
},
{
"time": "1",
"weather": "300",
"temp": "25.4",
"pressure": "1009.6",
"pressure_level": "2"
},
...
{
"time": "22",
"weather": "100",
"temp": "18",
"pressure": "1021.9",
"pressure_level": "2"
},
{
"time": "23",
"weather": "100",
"temp": "17.5",
"pressure": "1021.5",
"pressure_level": "2"
}
]
}
URLの数字部分が、地域を特定するIDになっています
地域IDは こちら で確認することができます
レスポンスは、指定した地域に対して、昨日・今日・明日の0~23時の気圧情報となっています
今回は、今日の現在時刻・翌時間・翌々時間の 気圧レベル を使用していきます
気圧レベルはマジックナンバーで定められているので、 こちら の対応表を参考にしました
気圧情報が取得できたら、気圧レベルが通知対象になるかチェックします
通知対象になっていた場合はメッセージを生成します
package model
import (
"github.com/kyokomi/emoji"
)
const (
PressureLevelIntOK0 = iota
PressureLevelIntOK1
PressureLevelIntSomewhatWarning
PressureLevelIntWarning
PressureLevelIntBomb
)
const (
PressureLevelStrOK = "通常"
PressureLevelStrSomewhatWarning = "やや注意"
PressureLevelStrWarning = "注意"
PressureLevelStrBomb = "警戒"
)
var PressureLevelMap = map[int]string {
PressureLevelIntOK0: PressureLevelStrOK,
PressureLevelIntOK1: PressureLevelStrOK,
PressureLevelIntSomewhatWarning: emoji.Sprint(":arrow_heading_down:") + PressureLevelStrSomewhatWarning,
PressureLevelIntWarning: emoji.Sprint(":warning:") + PressureLevelStrWarning,
PressureLevelIntBomb: emoji.Sprint(":bomb:") + PressureLevelStrBomb,
}
type BarometricPressure struct {
NowLevel int
After1HourLevel int
After2HourLevel int
}
type BarometricPressuresByZutool struct {
PlaceName string `json:"place_name"`
PlaceID string `json:"place_id"`
PrefecturesID string `json:"prefecture_id"`
DateTime string `json:"dateTime"`
Yesterday []*BarometricPressureByZutool `json:"yesterday"`
Today []*BarometricPressureByZutool `json:"today"`
Tomorrow []*BarometricPressureByZutool `json:"tomorrow"`
DayAfterTomorrow []*BarometricPressureByZutool `json:"dayaftertomorrow"`
}
type BarometricPressureByZutool struct {
Time string `json:"time"`
Weather string `json:"weather"`
Temp string `json:"temp"`
Pressure string `json:"pressure"`
PressureLevel string `json:"pressure_level"`
}
func (u *Usecase) Exec() *UsecaseResult {
result := &UsecaseResult{}
now := time.Now()
defer func() {
result.ProcessingTime = time.Since(now).Seconds()
}()
// 気圧取得
barometricPressure, err := u.repository.GetBarometricPressure(now.Hour())
if err != nil {
result.Err = err
return result
}
// 警戒レベルがあるかチェック
if barometricPressure.NowLevel > model.PressureLevelIntSomewhatWarning || barometricPressure.After1HourLevel > model.PressureLevelIntSomewhatWarning || barometricPressure.After2HourLevel > model.PressureLevelIntSomewhatWarning {
// メッセージ作成
message := createMessage(barometricPressure)
// LINEBotで送信
if err := u.repository.PostMessage(message); err != nil {
result.Err = err
return result
}
}
return result
}
func createMessage(barometricPressure *model.BarometricPressure) string {
levelStr := convertPressureLevel(barometricPressure)
messageFormat := "気圧が下がってきてるまる…!\n薬の準備をして、無理せず休むまるよ〜。。。\n\n"
messageFormat = messageFormat + "現在:%s\n1時間後:%s\n2時間後:%s"
message := fmt.Sprintf(
messageFormat,
levelStr[0],
levelStr[1],
levelStr[2],
)
return message
}
func convertPressureLevel(barometricPressure *model.BarometricPressure) []string {
var levelStr []string
levelStr = append(levelStr, model.PressureLevelMap[barometricPressure.NowLevel])
levelStr = append(levelStr, model.PressureLevelMap[barometricPressure.After1HourLevel])
levelStr = append(levelStr, model.PressureLevelMap[barometricPressure.After2HourLevel])
return levelStr
}
Herokuにデプロイ
Heroku CLIを利用するので準備しておきましょう
デプロイ
Herokuアプリケーションの作成
以下コマンドでHerokuアプリケーションを作成します
$ create heroku linebot-barometric-pressure
参考:CLI からのアプリの作成 | Heroku Dev Center
環境変数の設定
LINE MessagingAPIのシークレット、アクセスキー、ルームIDと、頭痛ーるの場所IDを設定します
$ heroku config:set LINE_ACCESS_TOKEN <チャンネルトークン>
$ heroku config:set LINE_SECRET <チャンネルシークレット>
$ heroku config:set LINE_ROOM_ID <ルームID>
$ heroku config:set PLACE_ID <頭痛ーる 場所ID>
参考:Heroku CLI コマンド | Heroku Dev Center
go.modにコメントを追加
go.mod
にHerokuデプロイ用コメントを追加します
module github.com/chasegawa1209/linebot-notify-barometric-pressure
// 以下はHerokuデプロイ用コメント
// +heroku goVersion go1.16
go 1.16
require (
github.com/kyokomi/emoji v2.2.4+incompatible
github.com/line/line-bot-sdk-go v7.8.0+incompatible
go.uber.org/zap v1.17.0
)
デプロイ
herokuにリモートリポジトリを登録します
$ heroku git:remote -a linebot-barometric-pressure
$ git remote -v
heroku https://git.heroku.com/linebot-barometric-pressure.git (fetch)
heroku https://git.heroku.com/linebot-barometric-pressure.git (push)
origin git@github.com:chasegawa1209/linebot-notify-barometric-pressure.git (fetch)
origin git@github.com:chasegawa1209/linebot-notify-barometric-pressure.git (push)
gitへのpushと、Herokuへのpushを行います
$ git push origin main
$ git push heroku main
動作確認
アプリが正常に動くか動作確認をしてみます
$ heroku run ./bin/linebot-notify-barometric-pressure
› Warning: heroku update available from 7.54.0 to 7.59.0.
Running ./bin/linebot-notify-barometric-pressure on ⬢ linebot-barometric-pressure... up, run.2996 (Free)
{"level":"\u001b[34minfo\u001b[0m","time":"2021-09-24T04:01:55.413Z","caller":"build_dd2f39ba/app.go:29","msg":"ProcessingTime: 0.770953[s]"}
{"level":"\u001b[34minfo\u001b[0m","time":"2021-09-24T04:01:55.415Z","caller":"build_dd2f39ba/app.go:33","msg":"success to NotifyBarometricPressureBatch"}
正常に動きました🎉
定期実行
最後に、定期的に気圧情報をチェックするように定期実行の設定をします
無料のスケジューラーアドオンがあるのでCLIから設定します
$ heroku addons:create scheduler
スケジューラーの設定画面がブラウザで開きます
右上の "Add Job" を押下すると "Job Editor" が開くのでスケジュールを設定します
今回は
Schedule: Every hour at ... :00
Run Command: ./bin/linebot-notify-barometric-pressure
に設定します
(Run Commandは ./bin/<アプリ名>
になります)
これで1時間に1回、気圧情報をチェックし、注意以上の場合はLINEに通知されるようになります
おわりに
今後は、自宅付近に雨雲が近づいたら通知してくれる機能を追加していこうと思います
少しでも役に立った、いいね👍、と感じましたら "LGTM" していただけるととてもうれしいです