LoginSignup
3

More than 1 year has passed since last update.

pythonからDiscordのwebhookでメッセージ投稿する備忘録

Last updated at Posted at 2020-08-22

最近RaspberryPi上でpython走らせてDiscordにメッセージ投稿する・・・
みたいなのをチョコチョコ作ってるのに毎度毎度躓く。
悩みたいのはそこじゃない。

公式ちゃんと読めよって話ですが、サンプル殆ど載っていないので備忘録。

参考

DiscordにWebhookでいろいろ投稿する
Webhook Resource
file
Visualizer and validator for Discord embeds.
Videos in Rich Embeds

材料

python3:3.7.3
json:2.0.9
requests:2.21.0
添付ファイルサンプルとして:ブランドガイドライン

メッセージだけ

import json
import requests

WEBHOOK_URL = "うえぶふっくURL?wait=true"

payload = {
    "username"      : "メッセージ",
    "content"       : "だけだよ。",
    "avatar_url"    : "https://github.com/qiita.png",
}

### メッセージだけ
res = requests.post( WEBHOOK_URL, json=payload )
print( res.status_code )
print( json.dumps( json.loads(res.content), indent=4, ensure_ascii=False ) )

application/jsonjson指定するだけ。
webohook URL に?wait=trueを付けてあげるとcontent返してくれる。付けないとstatus_codeが204、content返ってこない。
チャンネル下のスレッドに投下したいなら、thread_idも付けてやる。アーカイブ済のスレッドは自動でアーカイブ解除してくれるらしい。
スレッドIDを取得するには「ユーザー設定」→「アプリの設定」→「詳細設定」で「開発者モード」をONにすると表示される「IDをコピー」メニューでコピーするのが手っ取り早い。
それぞれWebhookURLに繋げるとこんな感じ。
https://discord.com/api/webhooks/{webhookID}/{webhookトークン}?wait=true&thread_id={スレッドID}

添付ファイルだけ

import json
import requests

WEBHOOK_URL = "うえぶふっくURL?wait=true"

### 画像添付
with open("favicon.png", 'rb') as f:
    file_bin = f.read()
files_qiita = {
    "favicon" : ( "favicon.png", file_bin),
}
res = requests.post( WEBHOOK_URL, files = files_qiita )
print( res.status_code )
print( json.dumps( json.loads(res.content), indent=4, ensure_ascii=False ) )

multipart/form-data、バイナリreadしてfilesに指定するだけ。
wait付くなくてもcontent返ってくる。

メッセージ+embed+添付ファイル

import json
import requests

WEBHOOK_URL = "うえぶふっくURL?wait=true"

payload2 = {
    "payload_json" : {
        "username"      :"メッセージと、",
        "content"       :"添付ファイルと、",
        "avatar_url"    : "https://github.com/qiita.png",
        "embeds": [
            {
                "title"         : "payload_json",
                "description"   : "embedsそのまま使うと怒られる。代わりにpayload_jsonに全部ぶち込んで文字列にdumpしたら良さげ。ensure_ascii=False 無くても多分大丈夫。",
                "url"           : "https://birdie0.github.io/discord-webhooks-guide/structure/file.html",
                "timestamp"     : "2020-08-22T15:18:00+0900",
                "color"         : 5620992,
                "footer": {
                    "icon_url"  : "attachment://favicon.png",
                    "text"      : "Qiita",
                },
                "thumbnail": {
                    "url"       : "attachment://logo-background-color.png"
                },
                "image": {
                    "url"       : "attachment://logo-effect-background-color.png"
                },
                "author": {
                    "name"      : "embedと。",
                    "url"       : "https://qiita.com/",
                    "icon_url"  : "attachment://favicon.png",
                },
                "video": {
                    "url"       : "https://www.youtube.com/embed/q05aeEf17Kc"
                },
                "fields": [
                    {
                        "name"  : "添付画像を",
                        "value" : "embedsで使うと別表示しなくなるっぽい。",
                        "inline": True,
                    },
                    {
                        "name"  : "attachment:",
                        "value" : "embedの中でしか添付使えないっぽい。",
                        "inline": True,
                    },
                    {
                        "name"  : "Visualizer and validator for Discord embeds.",
                        "value" : "日本語入れたら怒らたけど、color pickerが地味に便利。",
                    },
                    {
                        "name"  : "Youtubeの",
                        "value" : "[埋め込みは無理っぽい](https://support.discord.com/hc/en-us/community/posts/360037387352-Videos-in-Rich-Embeds)\nvideo URL 指定しても無視される。",
                    },
                ],
            }
        ]
    }
}

### embed付き
with open("favicon.png", 'rb') as f:
    file_bin_favicon = f.read()
with open("logo-background-color.png", 'rb') as f:
    file_bin_logobg = f.read()
with open("logo-effect-background-color.png", 'rb') as f:
    file_bin_logoeffect = f.read()
files_qiita  = {
    "favicon" : ( "favicon.png", file_bin_favicon ),
    "logo_bg" : ( "logo-background-color.png", file_bin_logobg ),
    "logo_effect" : ( "logo-effect-background-color.png", file_bin_logoeffect ),
}
payload2['payload_json'] = json.dumps( payload2['payload_json'], ensure_ascii=False )
res = requests.post(WEBHOOK_URL, files = files_qiita  , data = payload2 )
print( res.status_code )
print( json.dumps( json.loads(res.content), indent=4, ensure_ascii=False ) )

multipart/form-data
添付ファイルは前項同様filesに指定。メッセージ内容の方は公式読んでもフワっとしててハッキリ分からない。
添付ファイルを付ける場合embedとかそのまま使うと怒られる。代わりにpayload_jsonに全部入れてdumpして文字列化、dataに指定。これで何とかなった。
添付した画像ファイルはembeds内では使えたが、avatar_urlには使えなかった。
Embed Objectvideoは居たので youtube URL を試してみるが、現状webhookには使えなさそう。
wait付くなくてもcontent返ってくる。
実際に投稿するとこんな感じ。
goal.jpg

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3