みなさんこんにちは! @ometora_sateyan と申します。
本記事は 富士通クラウドテクノロジーズ Advent Calendar 2023 20 日目の記事です。
昨日は @sameshima_alt さんの、UbuntuでDAW環境を構築するためにN100ミニPCを買った話でした!
実際に機器を購入して、趣味の音楽のための環境構築、、、
憧れますし、1つのロマンですね。
今回構築された環境で作られる音楽作品もこれから楽しみですね!
さて本日はPythonを使ってSlack botとしてToDoリマインダーを作ってみたお話です。
経緯
個人的なお話で恐縮です。
現在社会人(エンジニア)歴5年目であり、情報工学を専攻していた大学時代を含めると初めてプログラミングに触れてから10年以上経っているのですが、今となってはかなりメジャーであるPythonについては実はほとんど触ったことがありませんでした。(学生時代に機械学習を扱う講義で少し触れたくらい)
そんな中、今年度からPythonを扱う業務にアサインされることになり、急遽習得が必要となりました。
そこで社内ツール等でPythonが多く使われていることを見つけ、せっかくなら勉強しながら何かモノを作ってみようと思うようになったのが、本記事のキッカケです。
今回やりたいこと
さて今回は ToDoリストのリマインダー を作ってみます。
以下の要件を設定します。
- ToDoタスクはGitLabのissueで管理
- 日常のあらゆるタスク(電球交換や家賃振込など)をissueとして作成
- 可能ならば期限も設定
- SlackのIncoming Webhook設定を使ったbotで毎日決まった時間に積み残しのToDoタスクを通知する
- 今回は毎朝10:00とする
- 使用言語はPython
用意するもの
- Slack
- GitLab
- 動作確認用の環境
- ちなみに今回私は
VirtualBoxのVM(CentOS) + Dockerコンテナ(Pythonイメージ)
を用いました
- ちなみに今回私は
作成
プロジェクト作成
さて、まずはGitLabのプロジェクトを作成します。
今回は以下の2つのプロジェクトを作成します。
- ToDoタスク管理用
- 今回は
todo
プロジェクトとします - こちらのプロジェクトの
Project ID
をメモしておきます- 2023年12月現在のGitLab仕様では、左メニューの
Settings
->General
で確認できます
- 2023年12月現在のGitLab仕様では、左メニューの
- 今回は
- リマインダー実装用
- 今回は
reminder
プロジェクトとします
- 今回は
GitLabのプロジェクト作成画面より作成します。
公開設定については Private
にすることをおすすめします。
Slackのbot設定
次にSlackのbot設定を行います。
後にPythonコードでSlackを呼び出す際に必要なパラメータをこちらで設定します。
また実際に通知するときに、どういうアカウント(どういう名前でどういうアイコン)が送っているのかの見え方の設定もこちらで行います。
まずSlackのWebhook設定のサイトにアクセスします。
未ログインならログインして、右上のワークスペース欄が今回botを追加したいワークスペースになっていることを確認します。
チャンネルへの投稿
の欄にて、今回追加したいチャンネル名を指定して、 Incoming Webhook インテグレーションの追加
を押下します。
(今回は #private-todo
というチャンネルに投稿するようにしてみます)
ボタンを押下すると 新しい機能が追加されました!
という表示とともに、Webhookインテグレーションについての各設定の画面に遷移します。
まず冒頭の Webhook URL
はメモしておきましょう。(後で使います)
また 名前をカスタマイズ
や アイコンをカスタマイズする
も好みに合わせて設定します。
そして 設定を保存する
を押下して設定を保存します。
Pythonで実装
さてGitLabやSlackの準備も整ったので、早速実装していきましょう。
まず根幹となる処理について、以下のようなPythonコードを作成します。
import gitlab
import requests
import json
import datetime
import sys
gl = gitlab.Gitlab(private_token=sys.argv[1]) # トークンで認証しながらGitLabクラスのインスタンスを作成
project = gl.projects.get(iterator=True, id={todoプロジェクトのProject ID}) # GitLabのプロジェクト情報を取得
issues = project.issues.list(state='opened', iterator=True) # 取得したプロジェクトにてopenされているissue情報を取得
today = datetime.date.today() # 今日の日付を取得
title = "" # 全issueリスト
title_out = "" # 期限切れissueリスト
title_top = "" # 締切7日以内issueリスト
title_nor = "" # 締切が近くないissueリスト
# issue.titleがissueのタイトル、issue.due_dateが締切日となっている
for issue in issues:
if issue.due_date is None:
date_sub = 999
else:
due_time = datetime.datetime.strptime(issue.due_date, '%Y-%m-%d')
date_sub = (datetime.date(due_time.year, due_time.month, due_time.day) - today).days
if date_sub < 0:
title_out = title_out + "【期限切れ :cry: 】 :skull_and_crossbones: :skull_and_crossbones: *" + due_time.strftime('%Y/%m/%d') + "マデ " + issue.title + "* :skull_and_crossbones: :skull_and_crossbones: \n"
elif date_sub < 7:
title_top = title_top + "【もうすぐ締切!!】 :fire: :fire: *" + due_time.strftime('%Y/%m/%d') + "マデ " + issue.title + "* :fire: :fire: \n"
else:
title_nor = title_nor + due_time.strftime('%Y/%m/%d') + "マデ " + issue.title + "\n"
title = title_out + title_top + title_nor
if title == "":
title = ":tada: :tada: No task!! :tada: :tada:" # もしタスクがないとき(openされているissueがないとき)
requests.post("{作成したSlack Webhook設定のWebhook URL}", data = json.dumps({"text": "*==== :sleepy: " + today.strftime('%Y年%m月%d日') + " 本日のタスク :sleepy: ====* \n\n" + title})) # ここでSlackに投稿される
print("reminder posted!!") # おわり
文言などは好みに合わせてアレンジしてみましょう!
参考までに今回用いたAPIのドキュメントは以下となります。
botの実行準備
冒頭で作成した reminder
プロジェクトにて、先ほどの executor.py
をプッシュします。
次にPythonコード内からGitlabを呼び出す際に必要なトークンの参照設定を行います。(もしトークン未作成の場合はあらかじめ作成しておきます)
わざわざ変数の参照設定をしなくてもpythonコード内に直に書くことで一応動きますが、トークンを誰でも見られるところに書くのはセキュリティ的にあまり良くないので、、、
- GitLabの
reminder
プロジェクトの左メニューにてSettings -> CI/CD
と入っていき、Variables
にてExpand
を押下 -
Add variable
を押下し、以下のパラメータを入力- Type:
Variable(default)
- Environments:
All(default)
- 以下の3つ全てにチェック
Protect variable
Mask variable
Expand variable reference
- Key:
GITLAB_TOKEN
- Value:
トークンの値
- Type:
- 画面下方の
Add variable
を押下
次に実行の設定を行います。
今回は自動実行を行いたいのですが、ここでGitLabのCIジョブを活用することにします。
reminder
プロジェクト配下に以下のファイルを作成します。
image: python:3.11.3
stages:
- execute
execute_script:
stage: execute
only:
- web
- schedule
script:
- pip install python-gitlab
- python executor.py $GITLAB_TOKEN
さて実行準備は整いました!
ちなみにもし別にブランチを作成している場合は、mainブランチにマージしておきましょう。
ToDoリスト作成
それでは todo
プロジェクト配下にissueとしてタスクを登録してみましょう。
今回は以下のようなタスクを用意します。
自動実行設定
最後に毎日決まった時間に自動実行されるよう設定したいと思います。
-
reminder
プロジェクトの左メニューにてBuild -> pipeline schedules
と移動 -
Create a new pipeline schedule
を押下 - 以下のパラメータを指定
- Description:
reminder
- Interval Pattern:
Custom
を選択して0 10 * * *
- Cron timezone:
[UTC+9] Tokyo
- Select target branch or tag:
main
- Variables: (特に指定しない)
-
Actived
にチェック
- Description:
-
Create pipeline schedule
を押下
リマインダー稼働
これで毎朝10時にリマインダーが届くようになりました!
スマホ版アプリでSlackにログインしていたら、10時になると通知が届くようになります。
そしてSlackの #private_todo チャンネルにもタスクが出るようになりました!
感想
今回は比較的シンプルなものを作りましたが、複数の既存プラットフォームや既存ライブラリを組み合わせながら、どうやって実現させるか考えるのが難しいながらも楽しかったです。
今まで業務でSlackやGitLabの便利機能に触れていき、いつか自分で設定してみてから普段の生活に役立つモノを作ってみたいと思っていたので、今回それを実現することができて良かったです。
今度はもっと応用させたもの(Slackワークフロー機能を使ってみたり、わざわざGitLab画面に行かずにタスク作成できるようにしたり)を考えてみようと思います。
最後まで読んでくださり、ありがとうございました!
明日は @ystkfujii さんによる traefikのplugin作ってみる という内容の記事が予定されております。
近年主流のクラウド環境やDocker/k8sなどのコンテナ環境で活用されており、ルーティングを行ってくれるというtraefik、これを使ってどのようなものが出来上がるのか楽しみですね!