Telegram通知関数を作成しよう

2024/10/07に恐ろしい発表がありました


https://x.com/lycorptech_jp/status/1843154519976513559





















今まで鞘の検知やbot動作確認通知にLINEを使っていた人は多く居ると思います。一応Telegramでの通知上限を調べてみましたが、良く分かりませんでした。

chatgptによると


Telegram API自体には1日のメッセージ送信数に関する明確な上限はありませんが、短時間に大量のメッセージを送信しすぎるとスパムとして認識され、制限を受ける可能性があります。レート制限（1秒に1メッセージなど）を守りながら、できるだけ自然なメッセージ送信を心がけることで、長期間にわたって問題なく使用できるでしょう。

との事でした。



Telegramにメッセージを送信する為には
telegram_token
telegram_chat_id
上記２種が必要です


まず、Telegram の検索マークからBotFatherを開きます


![a32cbfc865c3-20230718.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3573208/a07f125d-63c6-57dd-6fed-a33eeb5efdf6.png)

BotFatherへのコマンドで
```
/newbot
```
通知botの名前を決めます。
誰かのbot同じと名前だとNGになるので注意
```

Done! Congratulations on your new bot. You will find it at t.me/chantabot. You can now add a description, about section and profile picture for your bot, see /help for a list of commands. By the way, when you've finished creating your cool bot, ping our Bot Support if you want a better username for it. Just make sure the bot is fully operational before you do this.

Use this token to access the HTTP API:
777777777774:AAAAAAAAAAAAAAAAAAAAAAAAAAAFc
Keep your token secure and store it safely, it can be used by anyone to control your bot.

For a description of the Bot API, see this page: https://core.telegram.org/bots/api

```




上記の様に出力されました。
777777777774:AAAAAAAAAAAAAAAAAAAAAAAAAAAFc
この部分がAPIです。
次にtelegram_chat_idを取得します
telegram_chat_idを出力する為のプログラムを使用します。

```
pip install aiogram
```
telegram_chat_idの取得方法に悩んで上記モジュールを使用しました。
telegram_chat_idを取得出来れば今後必要ないので、アンインストールしても良さげ

```telegram_chat_id取得.py

import asyncio
import logging
import sys
from aiogram import Bot, Dispatcher
from aiogram.filters import CommandStart
from aiogram.types import Message

＃自分が取得したTOKENに書き換える
TOKEN = "777777777774:AAAAAAAAAAAAAAAAAAAAAAAAAAAFc"

dp = Dispatcher()


@dp.message(CommandStart())
async def command_start_handler(message: Message) -> None:
    # chat_idをログ出力
    logging.info(f"Chat ID: {message.chat.id}")
    await message.answer(f"Your chat ID is: {message.chat.id}")


async def main() -> None:
    bot = Bot(token=TOKEN)

    await dp.start_polling(bot)


if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO, stream=sys.stdout)
    asyncio.run(main())


```
上記プログラムを実行中にテレグラムの対象チャット上で
/startを送ると、チャットIDがTelegramに出力されます。
```
Your chat ID is: 123456789
```

出力された番号がtelegram_chat_idになります


```Telegram通知関数.
import requests
import logging
from logging import getLogger, StreamHandler, FileHandler, Formatter, INFO
from pprint import pprint

# 設定項目
telegram_config  = "ON"          # Telegram通知をするかどうかの設定
log_config       = "ON"          # ログファイルを出力するかどうかの設定
log_file_path    = "bot_log.csv"  # ログを記録するファイル名と出力パス
telegram_token   = "777777777774:AAAAAAAAAAAAAAAAAAAAAAAAAAAFc"  # Telegram Bot APIトークン
telegram_chat_id = "123456789"  # 実際のチャットIDに置き換えてください

# ログ機能の設定
if log_config == "ON":
    logger = getLogger(__name__)
    handlerSh = StreamHandler()
    handlerFile = FileHandler(log_file_path)
    handlerSh.setLevel(INFO)
    handlerFile.setLevel(INFO)
    logger.setLevel(INFO)
    formatter = Formatter('[%(asctime)s] %(levelname)s %(message)s')
    handlerFile.setFormatter(formatter)  # ファイルハンドラにフォーマッターを設定
    logger.addHandler(handlerSh)
    logger.addHandler(handlerFile)

#====================〇ログファイルの出力やTelegram通知〇====================
def print_log(text):
    # Telegram通知する場合
    if telegram_config == "ON":
        url = f"https://api.telegram.org/bot{telegram_token}/sendMessage"
        payload = {
            "chat_id": telegram_chat_id,
            "text": str(text),
            "parse_mode": "HTML"
        }
        try:
            response = requests.post(url, data=payload)
            response.raise_for_status()  # エラーチェック
        except requests.exceptions.RequestException as e:
            if log_config == "ON":
                logger.info(f"Telegram notification failed: {str(e)}")
            else:
                pprint(f"Telegram notification failed: {str(e)}")

    # コマンドラインへの出力とファイル保存
    if log_config == "ON":
        logger.info(text)
    else:
        pprint(text)


print_log("This is a test message for Telegram notification and log.")

```
上記の使い方は現在のプログラムでprintを使っている所の代わりにprint_logを使うだけです


![スクリーンショット 2024-10-07 202624.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3573208/802dcabf-fae7-8c75-c717-b0932c6253be.png)

以上！！