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


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

[公式](https://discord.com/developers/docs/resources/webhook)ちゃんと読めよって話ですが、サンプル殆ど載っていないので備忘録。


# 参考
[DiscordにWebhookでいろいろ投稿する](https://qiita.com/Eai/items/1165d08dce9f183eac74)
[Webhook Resource](https://discord.com/developers/docs/resources/webhook)
[file](https://birdie0.github.io/discord-webhooks-guide/structure/file.html)
[Visualizer and validator for Discord embeds.](https://leovoel.github.io/embed-visualizer/)
[Videos in Rich Embeds](https://support.discord.com/hc/en-us/community/posts/360037387352-Videos-in-Rich-Embeds)


# 材料
python3：3.7.3
json：2.0.9
requests：2.21.0
添付ファイルサンプルとして：[ブランドガイドライン](https://help.qiita.com/ja/articles/others-brand-guideline)


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

# 添付ファイルだけ
```python
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＋添付ファイル
```python
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とかそのまま使うと怒られる](https://birdie0.github.io/discord-webhooks-guide/structure/file.html)。代わりに`payload_json`に全部入れてdumpして文字列化、`data`に指定。これで何とかなった。
添付した画像ファイルは`embeds`内では使えたが、`avatar_url`には使えなかった。
[Embed Object](https://discord.com/developers/docs/resources/channel#embed-object)に`video`は居たので youtube URL を試してみるが、[現状webhookには使えなさそう。](https://support.discord.com/hc/en-us/community/posts/360037387352-Videos-in-Rich-Embeds)
`wait`付くなくても`content`返ってくる。
実際に投稿するとこんな感じ。
![goal.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691462/db5a0901-aaf6-64e6-94f2-e01563a82a0e.jpeg)