はじめに
以前、LINE Notifyの代替として、Discord Botを使ってメッセージや画像を通知する方法を紹介しました。
前回の記事はこちらです。

前回はDiscord Developer PortalでBotを作成し、BotトークンとチャンネルIDを取得して、PythonからDiscordへ通知しました。この方法でも問題なく通知できます。しかし、実際に使い続けてみると、単純にメッセージや画像を送りたいだけなら、Discord BotよりもWebhookのほうがはるかに簡単であることに気付きました。
Discord公式ドキュメントでも、Incoming WebhookはBotユーザーや通常の認証を用意せず、生成されたURLを使ってチャンネルへメッセージを投稿できる仕組みとして説明されています。この記事では、次の内容を電子工作・Python初学者向けに解説します。
- Discord Webhookの仕組み
- Webhook URLの作成方法
- Pythonから文字を送信する方法
- Pythonから画像を送信する方法
- Webhookを部品化して別のプログラムから呼び出す方法
- Discord BotとWebhookの違い
- Botにしかできないこと
- Discord Botを使ってメッセージに応答する方法
- Webhook URLやBotトークンを安全に管理する方法
Raspberry Piのセンサー監視、カメラ撮影、バス時刻通知、サーバー監視などにも、そのまま応用できます。
Discord Webhookとは
Webhookは、指定されたURLへHTTPリクエストを送信することで、外部サービスを動かす仕組みです。Discordの場合は、Discord側で専用のWebhook URLを作成し、そのURLにデータを送ると、指定したチャンネルへメッセージが投稿されます。
イメージとしては、次のようになります。
Raspberry Piやパソコン
│
│ HTTP POST
▼
Discord Webhook URL
│
▼
指定したDiscordチャンネルPythonプログラムから見ると、Webhook URLはDiscordへ通知を届けるための専用住所です。郵便に例えると、次のような関係です。
Webhook URL = 通知先の住所
POSTデータ = 送る荷物
Discord = 荷物を受け取って表示する場所Webhook URLへ次のようなJSONデータを送るだけで、Discordへ文字を投稿できます。
{
"content": "Raspberry Piからの通知です"
}これがDiscord Webhookの基本原理です。
WebhookとAPIの関係
WebhookとAPIは似ていますが、まったく同じものではありません。一般的なAPIでは、プログラム側からサービスへ要求を送ります。
プログラム
│
│ データをください
▼
サービスのAPI一方、一般的なWebhookは、何らかのイベントが発生したときに、あらかじめ登録されたURLへ情報を送るために使われます。
サービスでイベント発生
│
│ 自動通知
▼
登録されたWebhook URLただし、DiscordのIncoming Webhookは少し用途が異なります。こちらからDiscordのWebhook URLへPOSTリクエストを送ることで、Discordチャンネルにメッセージを投稿します。そのため、次のように覚えておけば十分です。
Discord Webhookは専用URLへデータを送るだけでDiscordに投稿できる簡易的な通知用インターフェース
Discord BotとWebhookの大きな違い
先に結論を示すと、次のように使い分けます。
| やりたいこと | 適した方法 |
|---|---|
| 一方的に文字を通知する | Webhook |
| 一方的に画像を送る | Webhook |
| センサー異常を通知する | Webhook |
| 定期実行結果を通知する | Webhook |
| ユーザーの発言に返信する | Bot |
| コマンドを受け付ける | Bot |
| リアクションや参加イベントを検知する | Bot |
| DiscordからRaspberry Piを操作する | Bot |
つまり、
通知だけならWebhook、Discordからの入力も処理するならBot
と考えると分かりやすいです。
Discord Webhookを作成する
ここから実際にWebhookを作成します。Discord Botを作成するときはDiscord Developer Portalを使いましたが、WebhookはDiscordのサーバー設定から作成できます。Developer Portalでアプリケーションを作る必要はありません。
前提条件
Webhookを作成するには、次のものが必要です。
- Discordアカウント
- 自分が管理できるDiscordサーバー
- 通知先となるテキストチャンネル
- Webhookを管理できる権限
個人用の通知であれば、自分だけが参加するDiscordサーバーで十分です。
PCでの作業になりますので、ご注意ください
Webhookを設定したいDiscordサーバーを開きます。サーバー名を右クリックし、次の項目を選択します。
サーバ設定サーバー設定の中から、次の項目を開きます。
連携サービス
「ウェブフック」または「Webhooks」を選択し、新しいWebhookを作成します。
画面の表示に従って、次の内容を設定します。
- Webhookの名前
- Webhookのアイコン
- 通知を投稿するチャンネル
Webhookの名前は、何から送られてきた通知なのか分かる名前がおすすめです。

Webhookの設定画面にある、Webhook URLをコピーします。URLは、おおむね次のような形式になっています。“discordapp”となっている場合があります。使用する時”app”を削除するとうまくいきます。
https://discord.com/api/webhooks/数字/長い文字列
このURLがあれば、Pythonなどの外部プログラムからDiscordへ投稿できます。ただし、非常に重要な注意点があります。
Webhook URLはパスワードと同じです!
Webhook URLを知っている人は、そのWebhookを使ってチャンネルへ投稿できてしまいます。ブログ、GitHub、SNS、スクリーンショットなどに、実際のURLを掲載してはいけません。
PythonからWebhookで文字を送信する
LINE Notifyと同じことを実現してみます。LINEより若干複雑になっていますが、使い方はシンプルです。
取得したトークン、チャンネルIDを入力し、discord_send_message.pyとして保存してください。
import requests
import os
class DiscordSendMessage:
__default_token: str = '****.*********' #トークン
__default_channel_id: str = '*********' #チャンネルID
def __init__(self, token: str = __default_token, channel_id: str = __default_channel_id):
self.__token = token
self.__channel_id = channel_id
def send_discord_message(self, file_path: str = None, message: str = ""):
url = f"https://discord.com/api/v10/channels/{self.__channel_id}/messages"
headers = {
"Authorization": f"Bot {self.__token}"
}
# ファイルが指定されていない or 存在しない場合は、メッセージのみ送信
if not file_path or not os.path.isfile(file_path):
headers["Content-Type"] = "application/json"
data = {
"content": message
}
response = requests.post(url, headers=headers, json=data)
if response.status_code == 200:
print("メッセージのみ送信完了")
else:
print(f"メッセージ送信失敗: {response.status_code}, {response.text}")
return
# ファイルが存在する場合は、ファイル + メッセージを送信
try:
with open(file_path, 'rb') as file:
files = {
'file': (os.path.basename(file_path), file)
}
data = {
"content": message
}
response = requests.post(url, headers=headers, data=data, files=files)
if response.status_code == 200:
print(f"ファイル送信完了: {file_path}")
else:
print(f"ファイル送信失敗: {response.status_code}, {response.text}")
except Exception as e:
print(f"ファイル送信中にエラーが発生しました: {e}")
# 送信失敗しても、メッセージだけ送る
self.send_file(file_path=None, message=message)
if __name__ == "__main__":
discord_bot = DiscordSendMessage()
file_path = r'C:\Users\***\***.jpg'
message = 'abcdefg'
discord_bot.send_discord_message(file_path=file_path,message=message)別のプログラム(main.py)で使用するコードです。
わかりやすいように、discord_send_message.pyとmain.pyは同じ階層に保存してください。
import requests
import os
import discord_send_message
discord_bot = discord_send_message.DiscordSendMessage() # インスタンス化
file_path = 'C:\***\***\***\***.jpg' # 送信したいファイルパス
message = 'abcdef' # 送信したい文字列
discord_bot.send_discord_message(file_path=file_path,message=message)メッセージを特定の人にメンションしたい場合は、以下のようにするとうまくいきます。
<@{ユーザID}> です
discord_bot.send_discord_message(file_path=url_images_data+"kaime.jpg", message=f'<@{******}>'+comment)まとめ
botほどの機能が不要な場合はウェブフックがとても簡単です。是非試してみてください。

コメント