ワーパパエンジニアの学び手帳

ワーパパエンジニアの業務外での学びとかガジェットネタとか

電車の遅延情報をSlackに定期的に通知する(heroku scheduler)

前もrubyで似たようなことやってますが、herokuスケジューラを使ってAPIを定期的に叩いて結果をSlackに通知するというやつ。
朝と帰りに電車の遅延情報を通知したいと思い、今回はpythonでバッチを作りました。

前のやつ↓
us-key-tech.hatenablog.com

コードは↓に置いています。
GitHub - us-key/pushTrainInfoSample

目次

やること

  1. herokuのスケジューラでpythonスクリプトを定期実行
  2. pythonスクリプトで電車の運行情報を取得し整形
  3. 整形した内容をslackで通知

動作環境

以下、pythonはインストール済みの前提で進めていきます。
コマンドはWindows環境のものです。maclinuxの場合は読み替えてください。

手順

プロジェクト作成

> mkdir pushTrainInfoSample
> cd pushTrainInfoSample  
> py -m venv env  
> env/Scripts/activate  

(コマンドプロンプトの場合は/ではなく\ )

コーディング

requestsのインストール

(env) > pip install requests

slackwebのインストール

(env) > pip install slackweb

コードの内容

今回は路線情報のAPIを叩いて運行情報を取る部分と、文字列をSlackに投稿する部分に分けて実装しています。

API叩くコード

# app/trainInfo.py  
import requests  
import json  
  
def request(nameArr):  
    url = 'https://rti-giken.jp/fhc/api/train_tetsudo/delay.json'  
    response = requests.get(  
        url,  
    ).json()  
    flg = False  
    print(response)  
    for name in nameArr:  
        for dic in response:  
            if dic['name'] == name:  
                msg = name + 'の遅延情報があります。'  
                flg = True  
    if not flg:  
        msg = '遅延情報はありません'  
    return msg  

slackに通知するコード

# app/postSlack.py
import slackweb  
import trainInfo  
import configparser  
  
# read ini  
inifile = configparser.ConfigParser()  
inifile.read('conf/config.ini', 'UTF-8')  
  
# webhook url  
url=inifile.get('settings','webhookurl')  
print(url)  
# 確認したい路線(list)  
train=inifile.get('train','lines').split(',')  
print(train)  
  
slack = slackweb.Slack(url=url)  
slack.notify(text=trainInfo.request(train))  

configparserについては後述します。

slackのwebhook URL取得

webhook URL取得については、以前書いた記事を参考に。

設定ファイルの利用

上記のslack通知するコードで登場したconfigparserですが、これを使うと設定ファイルから設定値を取得することができます。
使い方は↓の記事を参考にしました。
www.python-izm.com

今回の設定ファイルの内容はこんな感じ。

# conf/config.ini
[settings]
#slackのWebhook URL
webhookurl=https://hooks.slack.com/services/XXXXXXXX/XXXXXXXX/XXXXXXXXXXXXXXXXXXXXXX

#情報を取得したい路線をカンマ区切りで指定
[train]
lines=AAAA,BBBB,CCCC

webhookurl、linesを書き換えて使います。

ローカルで動作確認

(env) > py app/postSlack.py

slackに通知されればOK!

git管理化

(env) > git init  
(env) > git add .  
(env) > git commit -m "first commit"  

herokuにpush

(env) > heroku create pushtraininfo  
(env) > git push heroku master  

なんかエラー発生

(env) PS C:\Users\yomt0\pythonWorkSpace\pushTrainInfo> git push heroku master  
Counting objects: 1148, done.  
Delta compression using up to 4 threads.  
Compressing objects: 100% (1131/1131), done.  
Writing objects: 100% (1148/1148), 9.20 MiB | 296.00 KiB/s, done.  
Total 1148 (delta 235), reused 0 (delta 0)  
remote: Compressing source files... done.  
remote: Building source:  
remote:  
remote:  !     No default language could be detected for this app.  
remote:                         HINT: This occurs when Heroku cannot detect the buildpack to use for this application automatically.  
remote:                         See https://devcenter.heroku.com/articles/buildpacks  
remote:  
remote:  !     Push failed  
remote: Verifying deploy...  
remote:  
remote: !       Push rejected to pushtraininfo.  
remote:  
To https://git.heroku.com/pushtraininfo.git  
 ! [remote rejected] master -> master (pre-receive hook declined)  
error: failed to push some refs to 'https://git.heroku.com/pushtraininfo.git'  

herokuへの新規デプロイが久々で今回色々詰まってしまったのですが、ひとまずエラーメッセージにあるURLを参考に、buildpackの設定をします。
Buildpacks | Heroku Dev Center

buildpackの設定

(env) > heroku buildpacks:set heroku/python

再デプロイ

ローカルへのコミットをしたのち、herokuに再度pushします。が、またエラー発生。

(env) PS C:\Users\yomt0\pythonWorkSpace\pushTrainInfo> git push heroku master  
Counting objects: 1148, done.  
Delta compression using up to 4 threads.  
Compressing objects: 100% (1131/1131), done.  
Writing objects: 100% (1148/1148), 9.20 MiB | 316.00 KiB/s, done.  
Total 1148 (delta 235), reused 0 (delta 0)  
remote: Compressing source files... done.  
remote: Building source:  
remote:  
remote: -----> App not compatible with buildpack: https://buildpack-registry.s3.amazonaws.com/buildpacks/heroku/python.tgz  
remote:        More info: https://devcenter.heroku.com/articles/buildpacks#detection-failure  
remote:  
remote:  !     Push failed  
remote: Verifying deploy...  
remote:  
remote: !       Push rejected to pushtraininfo.  
remote:  
To https://git.heroku.com/pushtraininfo.git  
 ! [remote rejected] master -> master (pre-receive hook declined)  
error: failed to push some refs to 'https://git.heroku.com/pushtraininfo.git'  

requirements.txtを作ってなかったから?

buildpackがpythonに対応してないぜ、的なメッセージが出ているのですが、pythonのやつを設定したばっかだしなぁと思いつつ、調べると以下の記事が。 App not compatible with buildpack - Heroku - Stack Overflow
以下コマンドでrequirements.txtを生成。

(env) > pip freeze > requirements.txt

再度gitにコミットした後、デプロイ

ログを取り忘れましたが、無事デプロイできました。

まとめ

前回記事でも書いた通り、heroku schedulerは簡単に設定できるうえ、スケジューラのみの使用で無料の範囲を超えることは個人利用ならよほどハードな使い方をしない限りないんじゃないかなと思います。
今回書いたコードで私は朝7時と18時の2回slack通知させています。(1日毎のスケジュールを2件作成)
f:id:us_key:20181225232615p:plain スケジュールの組み方は業務で使うようなスケジューラと比べると制約がありますが、個人で使う分には十分じゃないかと。
気軽にスケジュールが組めるのでお試しください!