はじめに
この記事では、新規に追加されたデータベースのレコードを監視し、特定の条件に一致した場合に Slack に通知を送る Python スクリプトの作成方法を紹介します。具体的には、MariaDB データベースのテーブルから新しいレコードを取得し、性別が ‘male’ である場合に Slack へ通知を送ります。また、通知の内容には、レコードの各カラムデータが含まれます。このスクリプトは cron を使って定期的に実行されることを想定しています。
必要なライブラリと環境変数の設定
このチュートリアルで作成する Python スクリプトを実行するためには、いくつかの外部ライブラリが必要です。また、スクリプト内で使用するデータベース接続情報や Slack API トークンなどの機密情報は、環境変数を通じて設定します。以下では、それぞれの手順を説明していきます。
ライブラリのインストール
このチュートリアルでは、以下のライブラリを使用します。
mysql-connector-python
: MariaDB データベースへ接続するためのライブラリrequests
: HTTP リクエストを送信するためのライブラリpython-dotenv
: .env ファイルから環境変数を読み込むためのライブラリ
これらのライブラリをインストールするには、以下のコマンドを実行します。
pip install mysql-connector-python requests python-dotenv
環境変数の設定
スクリプト内で使用する機密情報を環境変数として設定します。このチュートリアルでは、以下の環境変数が必要です。
DB_HOST
: データベースのホスト名DB_USER
: データベースのユーザー名DB_PASSWORD
: データベースのパスワードDB_NAME
: データベース名SLACK_API_TOKEN
: Slack API トークンSLACK_CHANNEL
: Slack 通知を送信するチャンネル名
これらの環境変数を設定するために、プロジェクトのルートディレクトリに .env
という名前のファイルを作成し、以下のように環境変数を記述します。
DB_HOST=your_database_host
DB_USER=your_database_user
DB_PASSWORD=your_database_password
DB_NAME=your_database_name
SLACK_API_TOKEN=your_slack_api_token
SLACK_CHANNEL=your_slack_channel
各変数の値は、実際のデータベース接続情報や Slack API トークンに置き換えてください。このファイルは機密情報を含むため、バージョン管理システムにはコミットしないように注意してください。
Slack Bot の作成と API トークンの取得
このセクションでは、Slack で Bot を作成し、API トークンを取得する手順について説明します。
Bot の作成
- Slack API のアプリケーション管理ページにアクセスします。
- 右上の「Create New App」ボタンをクリックします。
- 「App Name」に任意のアプリ名を入力し、「Development Slack Workspace」で対象となるワークスペースを選択して、「Create App」ボタンをクリックします。
- 左側のメニューで「OAuth & Permissions」を選択します。
- 「Scopes」の下の「Bot Token Scopes」の「Add an OAuth Scope」ボタンをクリックし、必要な権限を追加します。本例では、
chat:write
(メッセージの送信)を追加します。 - 左側のメニューで「App Home」を選択します。
- 「App Home」ページ内の「Your App’s Presence in Slack」の下にある「Edit」ボタンをクリックし、「Display Name」および「Default Username」に任意の名前を入力して保存します。
- 「OAuth & Permissions」ページに戻り、「Install to Workspace」をクリックし、アプリをインストールします。この時点で Bot Token が生成されます。
API トークンの取得
- 作成した Bot の設定ページにアクセスします。
- 「OAuth & Permissions」のページを開き、「Bot Token」欄に表示されている API トークンをコピーします。このトークンは、「xoxb-」で始まります。
- API トークンを環境変数の設定で使用するために、.env ファイルに以下の形式で追加します。
SLACK_API_TOKEN=your_bot_token_here
これで Slack 側で Bot が作成され、API トークンも取得できました。Python スクリプトで API トークンを使って通知を送ることができるようになります。
Python スクリプトの作成
このセクションでは、データベースから新しいレコードを取得し、特定の条件に一致した場合に Slack に通知を送る Python スクリプトの作成方法について説明します。
スクリプトの構造と主要な関数の説明
スクリプトは以下の主要な関数から構成されます。
read_last_processed_id(file_path)
: 最後に処理されたレコードの ID をファイルから読み込む関数write_last_processed_id(file_path, last_id)
: 最後に処理されたレコードの ID をファイルに書き込む関数send_slack_notification(record, username)
: Slack に通知を送る関数main()
: スクリプトのメイン関数。データベース接続、レコードの取得、通知の送信、最後に処理された ID の更新を行います。
スクリプトの全体サンプル
以下は、今回説明する Python スクリプトの全体サンプルです。このスクリプトはデータベースから新しいレコードを取得し、特定の条件に一致した場合に Slack に通知を送る機能を実現します。
# ----------------------------------------------------------------------------
# Author: tomo
# Creation Date: 2023-04-12
#
# This script is free to use and modify at your own discretion.
# No warranty is provided for the script's functionality.
# Use this script at your own risk.
# ----------------------------------------------------------------------------
# -*- coding: utf-8 -*-
import mysql.connector
import os
import requests
import json
from dotenv import load_dotenv
usernames = {
"saki": "aaa",
"akiya": "bbb",
}
def read_last_processed_id(file_path):
if not os.path.exists(file_path):
return 0
with open(file_path, "r") as f:
content = f.read().strip()
if content:
return int(content)
else:
return 0
def write_last_processed_id(file_path, last_id):
with open(file_path, "w") as f:
f.write(str(last_id))
def send_slack_notification(record, username):
slack_token = os.getenv("SLACK_API_TOKEN")
slack_channel = os.getenv("SLACK_CHANNEL")
text = f"@{username} cc: @channel\n新しいレコードが追加されました:\n" \
f"・Name: {record['name']}\n" \
f"・Age: {record['age']}\n" \
f"・Gender: {record['gender']}\n" \
f"・Job Type: {record['job_type']}"
response = requests.post(
"https://slack.com/api/chat.postMessage",
headers={
"Authorization": f"Bearer {slack_token}",
"Content-Type": "application/json; charset=utf-8"
},
data=json.dumps({
"channel": slack_channel,
"text": text,
"link_names": True,
"username": "MariaDB Notifier"
})
)
if not response.json().get("ok"):
print(f"Error: The request to the Slack API failed. (url: {response.url} )")
print(f"The server responded with: {response.json()}")
def main():
load_dotenv()
last_processed_id_file = "last_processed_id.txt"
last_processed_id = read_last_processed_id(last_processed_id_file)
conn = mysql.connector.connect(
host=os.getenv("DB_HOST"),
user=os.getenv("DB_USER"),
password=os.getenv("DB_PASSWORD"),
database=os.getenv("DB_NAME")
)
cursor = conn.cursor()
cursor.execute(f"SELECT * FROM sample_table WHERE id > {last_processed_id} A ND gender = 'male' ORDER BY id ASC")
records = cursor.fetchall()
cursor.close()
conn.close()
for record_tuple in records:
record = {
'id': record_tuple[0],
'name': record_tuple[1],
'age': record_tuple[2],
'gender': record_tuple[3],
'job_type': record_tuple[4]
}
username = usernames[record['name']]
send_slack_notification(record, username)
last_processed_id = record['id']
write_last_processed_id(last_processed_id_file, last_processed_id)
if __name__ == "__main__":
main()
データベース接続とレコードの取得
main
関数の中で、mysql.connector
を使ってMariaDB データベースに接続し、cursor.execute()
でSQL クエリを実行して新しいレコードを取得します。その際、gender = 'male'
の条件を追加し、対象のレコードが男性に限定されるようにします。また、最後に処理された ID よりも大きい ID を持つレコードのみを取得します
Slack への通知の送信
send_slack_notification
関数では、requests.post()
を使って Slack API に対して HTTP リクエストを送信し、通知を送ります。この際、Authorization
ヘッダーに Slack API トークンを含めることが重要です。また、通知の内容にはレコードの各カラムデータを含めるようにしています。
スクリプトの実行と最後に処理された ID の保存
main
関数の最後で、最後に処理された ID を更新し、それを last_processed_id.txt
ファイルに書き込みます。これにより、次回スクリプトが実行された際に、前回処理されたレコードよりも新しいレコードのみを取得できるようになります。
cron を使った定期実行の設定
cron を使った定期実行の設定
スクリプトが正常に動作することを確認したら、次に cron を使ってスクリプトを定期的に実行するように設定します。これにより、新しいレコードが追加されるたびに自動的に Slack 通知が送られるようになります。
crontab ファイルの編集
まず、ターミナルで以下のコマンドを実行して、crontab ファイルを開きます。
crontab -e
cron ジョブの追加
crontab ファイルが開いたら、以下のような行を追加して、スクリプトが1分ごとに実行されるように設定します。
* * * * * /usr/bin/python3 /path/to/your/script.py
ここで、/path/to/your/script.py
は実際のスクリプトのファイルパスに置き換えてください。また、/usr/bin/python3
は Python インタープリタのパスですが、環境によって異なる場合があります。適切なパスに変更してください。
cron ジョブの保存と実行
追加した cron ジョブを保存し、crontab ファイルを閉じます。これで、指定した間隔でスクリプトが自動的に実行され、新しいレコードが追加された際に Slack 通知が送信されるようになります。
まとめ
このチュートリアルでは、MariaDB データベースに新しいレコードが追加された際に Slack で通知を送る Python スクリプトの作成方法を説明しました。また、cron を使ってスクリプトを定期的に実行する方法も紹介しました。このスクリプトをカスタマイズして、独自の通知システムを構築することができます。
以上