見出し画像

Pythonで住民税額の通知とファイル添付をSlack Bot経由でDMに通知する方法

Pythonを使って、住民税額の通知をDM(個別メッセージ)に送付するBOTを作成し、業務効率化を実現しました。

Python苦手だなぁ〜と思って、今まであまり触ることなく逃げてきたのですが、Chat GPTと壁打ちしながら、スクリプトを作成できました!!

実行環境

  • Windows 11

  • Visual Studio Code

スクリプト実行前の準備

  • pipでslack_sdkのインストール

  • SlackのOauth(権限回り)の設定

  • Slack Bot OAuth Tokenの環境変数への登録

  • GASを利用してファイルのリネーム

ファイルのリネームには、GASを使用

Google Colabを使ってもできるんじゃないかなーと思うのですが、今回は、GASを使用し、リネームをしました。
CSVファイルの名前が、ファイル名に含まれるようにすることで、ローカルのフォルダに保存されている従業員ごとのファイルを探せるようにしました。

Pythonを使わざるを得なくなった理由

世に出回っているGASのコードだと、ファイルのアップロードが出来なかったため、今回Pythonをチョイスしました。

CSVファイルの構成

  1. 従業員名

  2. Slackのメンションに使用するメンバーID

  3. 特徴税通・解凍パスワード取得URL

配布に必要な3列のCSVを作成しました。この処理にもGASを使用
サンプルデータは、Geminiに出力してもらいました。

Pythonのコード

import os
import pandas as pd
from slack_sdk import WebClient
from slack_sdk.errors import SlackApiError

# member_idからchannel_idに変換する
def get_dm_channel_id(client: WebClient, user_id: str) -> str:
    try:
        # チャネルを取得するための会話をオープン
        response = client.conversations_open(users=user_id)
        return response["channel"]["id"]
    except SlackApiError as e:
        print(f"Error opening conversation: {e.response['error']}")
        return None


def generate_message(eltax_url):
    unzip_software_url = 'https://7-zip.opensource.jp/'

    message = "お疲れ様です!\n"
    message += "令和*年度の住民税決定通知書を配布します\n"
    message += "<https://********|コンフル>に詳細がございますので、ご確認ください\n"
    message += f"<{eltax_url}|eLTAX 特徴税通・解凍パスワード取得URL>\n\n"
    message += "`・添付ファイルが他の従業員のものだった`\n"
    message += "`・取得したパスワードでフォルダ解凍できなかった`\n\n"
    message += "上記事象が発生した場合、早急に<https://********|#労務問い合わせチャンネル>からご連絡をお願いいたします:bow::skin-tone-3:\n\n"

    return message


def find_employee_files(directory, employee_name):
    """
    指定したディレクトリ内のファイルを検索し、
    ファイル名に指定した従業員名が含まれているファイルを返す。

    Parameters:
    directory (str): 検索するディレクトリのパス
    employee_name (str): 検索する従業員の名前

    Returns:
    list: 従業員名が含まれているファイルのリスト
    """
    files_with_employee_name = []

    for root, _, files in os.walk(directory):
        for file in files:
            if employee_name in file:
                files_with_employee_name.append(os.path.join(root, file))
                print(f"{files_with_employee_name}")

    return files_with_employee_name


# 環境変数からSlackトークンを取得
slack_token = os.getenv("SLACK_API_TOKEN")
if not slack_token:
    raise ValueError("環境変数が適切に設定されていない可能性があります。")

client = WebClient(token=slack_token)

# CSVファイルからデータを読み込む
df = pd.read_csv(r"C:\Users\user\Desktop\************\members.csv")

# 特別徴収税額のファイル格納先
directory = r"C:\Users\user\Desktop\************\tax_amount_details"

# 各ユーザーに対してDMを送る
for index, row in df.iterrows():
    user_id = row['member_id']  # ユーザーIDを取得
    employee_name = row['employee_name'] # ユーザー名
    eltax_url = row['decode_url']  # ファイルパスを取得
    file_path = find_employee_files(directory, employee_name)[0]

    try:
        # チャネルを取得するための会話をオープン
        response = client.files_upload_v2(
            channel=get_dm_channel_id(client, user_id),
            file=f"{file_path}", # ローカルファイルにあるファイルのパス
            title=os.path.basename(file_path), # 添付ファイルの名前
            initial_comment=generate_message(eltax_url), # elTaxのURL
        )

        file_url = response['file']['url_private']

        # アップロードが成功した場合、ファイルのURLを表示
        print(f"File uploaded: {file_url}")

    except SlackApiError as e:
        print(f"{employee_name}さんのファイルアップロードに不具合が生じました")
        print(f"Error uploading file: {e.response['error']}")

この記事が気に入ったらサポートをしてみませんか?