5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

DiscordのWebhooksをurllib経由でたたいて簡単自動発言ボット作成

Last updated at Posted at 2020-09-18

概要

AWS Lambda の Python 3.7 ランタイムを使ってDiscordのWebhook URL を叩くと 403 でうまいこと叩けずに困った。

原因を調べたらどうやらUAをチェックしているらしく、UAが urllib だとNG。( 試しに使った curl はOK )

Discordのライブラリを入れればいいんだろうけど、Lambdaという都合上、ほか依存ライブラリ追加したくない。

UAをcurlに偽装することでうまいこと叩けた。よかったよかった。

反省

  • うまくいくパターンとだめなパターンの差分はHTTPヘッダをみよ。
  • APIがコケる場合にはちゃんとステータス値とレスポンスボディとマニュアルをみよ。

参照

Python3のスクリプトでjsonをPOSTする - Qiita

詳細

What is Webhooks

Discordにおいて、なにかあったら自動で特定のチャンネルにメッセージを送りたい。

なんでも Webhookってのが作られるらしく、それならシンプルにJSONをポストするだけでそういうことができる。
(本当はDMを送りたかったんだけど、そっちはAPI経由になってだるそうなんでヤメ)

How to get Webhook URL

たぶん管理者権限がいる。

  1. チャンネルの右側に表示されているギアをクリック
  2. 左のメニューから「連携サービス」をクリック
  3. 「ウェブフック」とあるのでそこの「詳細」 or 「ウェブフックを確認」をクリック
  4. 「新しいウェブフック」をクリック、ポストされるときの名前を指定し、チャンネルを指定
  5. 「ウェブフックURLをコピー」をクリックすればOK

試す

とりあえず POST はオオゴトなんでまずは GET から。curlを使って試す。

$ curl -v https://discordapp.com/api/webhooks/xxxxxxxx
略
< HTTP/2 200
略
{"type": 1, "id": "xxxx", "name": "xxxxx", "avatar": null, "channel_id": "xxxxxx", "guild_id": "xxxxxx", "application_id": null, "token": "xxxxxx"}

OK。エンドポイントが正しくあることは確認できた。

POSTを試す。

$ curl -v -X POST -H "Content-Type: application/json" -d '{"content":"ふぁらおからウェブフック経由のポストで参上"}' https://discordapp.com/api/webhooks/xxxxxxxx

でOK。

Pythonのコードから試す

以下で試せばOK。試しに urllib.request.Request の第3パラメータの User-Agent を削除してみてほしい。それだと弾かれてしまう。

    url = "https://discordapp.com/api/webhooks/xxxxxxxx"
    method = "POST"
    headers = {"Content-Type" : "application/json"}
    obj = {"content" : "ふぁらおからウェブフック経由のポストで参上"}
    json_data = json.dumps(obj).encode("utf-8")
    request = urllib.request.Request(
        url,
        json_data,
        {"User-Agent": "curl/7.64.1", "Content-Type" : "application/json"},
        method
    )
    with urllib.request.urlopen(request) as response:
        response_body = response.read().decode("utf-8")
        print(response_body)

5
0
1

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
5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?