11 min readPython
【Python】Cloud Functionsを利用して、ゴミ出しを通知する
家のゴミが溜まり、「明日こそ出す!」と意気込んでいたが忘れてしまう。何度も経験して苦い思いをしているのではないでしょうか?今回は、Cloud Functions機能を活用してPythonを実行し、ゴミ出し日のLine通知を実装致します。
執筆者 - おすすめの記事2選
用意するもの
- GCPのプロジェクトの作成が済んでいる。
- Lineを利用していること、Line利用開始時に設定した「Email address, Password」の設定を覚えていること
- 通知したいLineグループが存在する場合、Lineアプリからグループを作成しておくこと、またLine NotifyをLineグループ内に友達追加しておくこと
アーキテクチャ
実行手順
上記のアーキテクチャを見ただけではわからない部分も多々あるかと思います。以下の手順を踏まえて、実装してみましょう。
Line Notifyの設定を行う
以下の作業は、Line通知するために必要な「トークン」を発行するために必要な工程になります。トークンを発行する理由としては、「様々なグループ、ユーザー間に対して、通知が送られないように必要な鍵を発行している」のだと考えてください。
- こちらのページに訪問する。
- 右上に存在する「Log in」 テキストリンクをクリックする。
- ラインのログイン時に必要な「Email address, Password」を入力する。
- ログインしたら右上の自分の名前をクリックして、「My Page」のテキストリンクをクリックする。
- 下の方へ行くと、「Generate token」の文字が確認できるので、そのボタンをクリックする。
- 「Please enter a token name to be displayed before each notification.」の箇所に、通知の際にどのようなテキストを埋め込みたいのか設定します。(デモ内では、「ゴミ出しテスト」を通知するものですので、「ゴミ出しテスト」を設定しております。)
- 「Select a chat to send notifications to.」の箇所では、通知したいグループ名を選択します。
- 「Generate token」をクリックします。
- 最後にトークンが表示されるので、忘れないようにメモしておいてください。
Cloud Functions作成
以下の作業は、Pythonを実行する関数を実装するために必要な工程になります。
お好みのGCPプロジェクトへアクセスする。そして、上の検索覧へ「Cloud Functions」と入力する。すると、Cloud Functionsを操作する画面が表示される。続けて「関数を作成」をクリックする。
以下のように関数の詳細を設定していく。
- 関数名(実行する際の関数名称) : garbage_test
- リージョン(どの地域で関数を実行するのか?) : asia-northeast1
- トリガータイプ(何をきっかけとし、関数を実行するのか?) : Cloud Pub/Sub
- Cloud Pub/Sub トピックを選択してください(もう一度アーキテクチャを確認するとわかるのですが、Cloud Schedulerを始めとしてCloud Pub/Subの特定のトピックが呼び出されます。そしてトピックに紐づくCloud Functionsの関数が実行されます。そのために、ここでは独自のトピックを作成してCloud Schedulerで呼び出せるように設定している。) 「トピックを作成する」をクリック → トピックIDへいい感じの名前を設定。「トピックを作成」をクリックする。
- ランタイム、ビルド、接続の設定(関数を実行する際に変数の扱いや、接続先の利用用途を設定する。) : ランタイム環境変数へ名前をtoken, 値を先ほどLine Notifyで取得したトークンを格納する。
「次へ」ボタンをクリックする。
以下の作業で、私の方で作成したコードを、自身のパソコンへファイルを置く作業になります。
- こちらのページに訪問ください。
- 緑の「Code」と書かれているボタンをクリックして、 「Download ZIP」をクリックください。
- ダウンロードしたZipファイルをドラック&ドロップを使って、デスクトップへファイル移動して下さい。
- Zipファイルを展開するために、デスクトップに置いた先ほどのファイルをダブルクリックして下さい。
次に先ほど自身のパソコンへ入れたコードをコピーして、以下の文章、画像を確認しながら該当するファイルへ貼り付けてください。
- エントリポイントを「garbage_test」へ変更する。
- 自身のパソコンへ入れたファイルと同名の内容をコピーしてそれぞれ貼り付ける。
- 「デプロイ」ボタンをクリックする。
Cloud Scheduler作成
Cloud Pub/Sub のトピックを実行する、Cloud Schedulerを作成します。上の検索覧へ「Cloud Scheduler」と入力する。するとCloud Schedulerを操作する画面が表示される。続けて「ジョブを作成」をクリックする。
Cloud Schedulerの詳細設定を行います。
- 名前(タスクの名前) : garbage_test
- 説明(タスクを実行する説明文) : ゴミ出しテストです
- 頻度(タスクを実行する頻度。書き方の詳細はこちら) : 00 9 * * *
- タイムゾーン(どこの国を基準として実行するのか?) : 日本標準時(JST)
- ターゲットタイプ(どこのタスクを実行するのか?) : Pub/Sub
- トピック(どのPub/Sub内で生成されたトピックを選択するのか?) : 先ほど作成したトピック
- メッセージ本文(タスクを実行する際にデータを送りたい場合に利用する) : {}
「作成」ボタンをクリックする。
最後に「今すぐ実行」を選択して、Line通知されるか確認する。
完成動画
よくわかるコード解説
以下のコードでは、本日の日付を取得するコードを実装しています。注意する点としては、timezone(どこの日付を基準として値を扱うか)が大切になります。(日本は協定世界時から+9時間なので、datetime.timedelta(hours=9)と設定しています。)
1# 本日の日付を取得する。
2def getToday():
3 # timezoneを日本時間仕様に設定して、本日の日付を取得する。
4 today = datetime.datetime.now(datetime.timezone(datetime.timedelta(hours=9)))
5 # 一度本日の日付を整形して文字列型にし、再度date型へ変形する。
6 return datetime.datetime.strptime(today.strftime('%Y-%m-%d'), '%Y-%m-%d')
以下のコードでは、◯曜日を基準にした場合に、本日の日付が第何週目なのか算出する関数になります。
ポイントとしては、
- 月-日曜日を0-6の数字で表していること
- 本月の1日は何曜日の数字(0-6)になるのか、weekday()関数を用いて取得していること
- 1日の曜日(数字) - 基準の曜日(数字)をすることで差分を取得する。
- % 7することで、差分を絶対値のように扱う。
が考えられます。
1# 本日の日付が◯曜日を基準とした場合に、第何週目の曜日なのか算出する関数
2# https://note.nkmk.me/python-calendar-datetime-nth-dow/
3# dt : 本日の日付
4# firstWeekDay : 0~6, 0 : 月曜日, 1 : 火曜日, 2 : 水曜日, 3 : 木曜日, 4 : 金曜日, 5 : 土曜日, 6 : 日曜日, default : 月曜日
5# response : int
6def getNthWeek(dt, firstWeekDay=0):
7 # 日にちを1に置換して月初のオブジェクトを生成し、weekday()メソッドで曜日のidx値を取得する。
8 firstDow = dt.replace(day=1).weekday()
9 # firstDow - firstWeekDay : -6~6
10 # (割られる数) = (商) * (割る数) + (余り)
11 # 7で割る理由は、1週間は7日であるため。
12 # -6 = (-1) * 7 + 1
13 # -5 = (-1) * 7 + 2
14 # -4 = (-1) * 7 + 3
15 # -3 = (-1) * 7 + 4
16 # -2 = (-1) * 7 + 5
17 # -1 = (-1) * 7 + 6
18 # 0 = (0) * 7 + 0
19 # 1 = (0) * 7 + 1
20 # 2 = (0) * 7 + 2
21 # 3 = (0) * 7 + 3
22 # 4 = (0) * 7 + 4
23 # 5 = (0) * 7 + 5
24 # 6 = (0) * 7 + 6
25 # https://ja.stackoverflow.com/questions/66236/python-%E3%81%A7-%E8%B2%A0%E3%81%AE%E6%95%B0%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%9F%E5%89%B0%E4%BD%99%E7%AE%97%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6
26 offset = (firstDow - firstWeekDay) % 7
27 # // : 切り捨て除算
28 # idxの開始位置が0であるため、-1を行う。
29 # + 1を行うのは、第0週から始まるのを防ぐため。
30 return (dt.day + offset - 1) // 7 + 1
今日のまとめ
- Cloud Functionsを活用すると、ローカル環境なしにコードを動かすことができる。
- Cloud Schedulerを用いることで、定期実行したい処理を実装できる。
- Cloud Functionsでは、Python以外にも様々な言語でコードを書ける。(対応可能言語一覧)
こんなことにもチャレンジしてみよう
- その他の言語を利用して、Cloud Functionsを実行してみよう。
- Cloud Functionsへローカルからコードデプロイしてみよう。
参考文献
- Pub/Sub を使用して Cloud ファンクションをトリガーする
- cron ジョブ スケジュールの構成
- Cloud Functions対応可能言語一覧
- Cloud Functionsコードデプロイ
- ゴミ出し日の前日にLINEで通知してくれるアプリを作る(Node.js / AWS Lambda)
- Google Cloud Function + Cloud Scheduler + Python で定期的に Twitter 投稿する