こしあん
2024-04-28

Python(requests)でDiscordにWebhook経由で複数の画像+メッセージ投稿


544{icon} {views}


DiscordにWebhook経由で、複数の画像+メッセージを投稿する例を紹介します。Python+requestsでやったらかなりハマったのでメモがてらに。

やりたいこと

こんな感じに、複数の画像を添付して、メッセージ込で送信したい。Webhook経由での投稿を想定するが、Discordの専用のライブラリを使うのではなく、Pythonのrequestsのライブラリから送信する。

公式情報

https://discord.com/developers/docs/reference#uploading-files

multipart/form-dataを使ってポストすれば良い。ただ、この送り方がかなり癖がある。

Pythonのrequestsでファイル送信するときにヘッダーにmultipart/form-dataを直接指定してはいけない

この記事にある通り、multipart/form-dataをヘッダーとして指定すると、boundary周りでハマる。

実装

正解例を示す。ChatGPTに聞きながらようやく想定された結果になった例。

import requests
import json

def main():
    url = "https://discord.com/api/webhooks/{application_id}/{token}"

    payload = {
        "content": """こんにちは!プログラムから投稿しました。

## 見出し
* 箇条書き1
* 箇条書き2

[リンク](https://ja.wikipedia.org)""",
    }

    file_list = ["cat1.jpg", "cat2.jpg"]

    # 画像ファイルをmultipart formに追加
    multiple_files = []
    for i, image_file in enumerate(file_list):
        multiple_files.append((
            f"files[{i}]", (f"image{i+1}.jpg", open(image_file, "rb"), "image/jpg")
        ))

    # リクエスト送信
    response = requests.post(url, data={"payload_json": json.dumps(payload)}, files=multiple_files)
    print(response.status_code)

    # 開いたファイルを閉じる
    for name, filetuple in multiple_files:
        if isinstance(filetuple, tuple) and filetuple[1]:
            filetuple[1].close()

if __name__ == "__main__":
    main()

コード自体はとても単純。特にヘッダーを指定する必要はない。

payload_jsonの部分はdataの中にフックして指定するらしい。わかるか!



Shikoan's ML Blogの中の人が運営しているサークル「じゅ~しぃ~すくりぷと」の本のご案内

技術書コーナー

北海道の駅巡りコーナー


Add a Comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です