Slackにメッセージ・ファイル・エラーを送信（Python）

# はじめに
皆さん、実行時間が長いプログラムで通知が来るようにしたくありませんか？
AIを学習していると、数時間かかる実行は普通にあると思います。そのようなときに、今回紹介するプログラムは役立つと思います。
はじめて作成したのは1年くらい前なのですが、関数メインで作成されていて、あまりにも使いづらかったので、クラスを使ってより簡単に利用できるように修正しました。

**注意
jupyter notebook用に作成を行っているため、Pythonファイルでは作動しません。修正予定です。**

GitHubリンク
- https://github.com/morikazu1119/Original_library/tree/main

## 機能紹介
- send_msg(msg)
  - msgの文字列をslackに送信
- send_file(file_path)
  - fileをslackに送信
- その他
  - jupyter notebookのエラーを自動的に取得し、slackにエラー内容を通知

# プログラム全体と実行例
## コード
### Slack_send.py
```python
import requests
import os
import re
from IPython.core.ultratb import AutoFormattedTB
from IPython import get_ipython

chat_url = "https://slack.com/api/chat.postMessage"
file_url = "https://slack.com/api/files.upload"

class Slack:
    def __init__(self, token, channel):
        self.token = token
        self.channel = channel
        self.tb_handler = AutoFormattedTB(mode="Plain", color_scheme="Neutral", ostream=open(os.devnull, "w"))  # エラートレース取得用
        self.jupyter_preprocess()

    def send_msg(self, text):
        """Slackにメッセージを送信"""
        headers = {"Authorization": "Bearer " + self.token}
        data = {
            "channel": self.channel,
            "text": text
        }
        response = requests.post(chat_url, headers=headers, json=data)
        if not response.ok:
            print(f"Slack通知エラー: {response.status_code}, {response.text}")

    def send_file(self, file_path):
        """Slackにファイルを送信"""
        data = {
            "token": self.token,
            "channels": self.channel,
            "filename": os.path.basename(file_path),
            "title": os.path.basename(file_path)
        }
        with open(file_path, "rb") as f:
            files = {"file": f}
            response = requests.post(file_url, data=data, files=files)
            if not response.ok:
                print(f"Slack通知エラー: {response.status_code}, {response.text}")


    def jupyter_preprocess(self):
        """Jupyter Notebook の最初に実行する関数."""
        itb = AutoFormattedTB(mode='Plain', tb_offset=1)

        def custom_exc(shell, etype, evalue, tb, tb_offset=None):
            # 例外が発生した場合の処理
            shell.showtraceback((etype, evalue, tb), tb_offset=tb_offset)

            # トレースバックのフォーマット
            stb = itb.structured_traceback(etype, evalue, tb)
            sstb = itb.stb2text(stb)

            # ANSIカラーコードを正規表現で削除
            readable_traceback = re.sub(r'\x1b\[[0-9;]*m', '', ''.join(sstb))

            # エラー内容を整理してSlackに通知
            formatted_traceback = f"Exception: {etype}\nMessage: {evalue}\nTraceback:\n{readable_traceback}"

            # Slack通知
            self.send_msg(f"ERROR: 例外が発生しました。\n```\n{formatted_traceback}\n```")

            return sstb

        # カスタムエラーハンドラーを設定
        get_ipython().set_custom_exc((Exception,), custom_exc)

```

### _ init_.py
```python
from .Slack_send import Slack

__all__ = ["Slack"]
```

## 実行例
```python
import sys
sys.path.append("{your parent dir}")
from kython import Slack

token="{your token}"
channel="{channel name}"

slack = Slack(token=token, channel=channel)
slack.send_msg("Hello, world!")
```

# 終わりに
コードに関する解説は省略しています。

tokenの取得などは他の方の記事を参考にしてください。