Webhooks¶
Ein Webhook postet Nachrichten in einen Kanal, unter eigenem Namen und eigenem Avatar. Seine URL enthält eine ID und ein Token, und das Token ist alles, was es zum Posten braucht; ein Deploy-Skript oder ein Monitoring-Job kann also ohne Bot Nachrichten senden.
import asyncio
import os
import bostie
from bostie import Embed, color, ui
async def announce(url: str, version: str) -> None:
async with bostie.WebhookClient(url) as webhook:
message = await webhook.execute(
embeds=[Embed(title=f"Deploying {version}", color=color.YELLOW)],
username="Deploy bot",
avatar_url="https://example.com/deploy.png",
)
await webhook.edit_message(
message.id,
embeds=[Embed(title=f"Deployed {version}", color=color.GREEN)],
)
await webhook.execute(
components=[ui.text(f"Release notes for {version} are out.")],
thread_name=f"Release {version}",
with_components=True,
)
def announce_from_a_script(url: str) -> None:
webhook = bostie.SyncWebhookClient(url)
message = webhook.execute("The nightly backup is running.")
webhook.edit_message(message.id, content="The nightly backup finished.")
if __name__ == "__main__":
asyncio.run(announce(os.environ["WEBHOOK_URL"], "2.0"))
WebhookClient(url) liest die ID und das Token aus einer Webhook-URL und löst bei allem anderen ValueError aus. Verwende ihn innerhalb von async with, das seinen HTTP-Client öffnet und schließt. SyncWebhookClient(url) hat dieselben Methoden für Code ohne Event-Loop; jeder Aufruf betreibt seine eigene.
| Methode | Bewirkt |
|---|---|
execute(content, **parts) |
postet eine Nachricht und gibt sie zurück, sobald Discord sie gespeichert hat |
edit_message(message_id, **parts) |
bearbeitet eine Nachricht, die der Webhook gesendet hat; ein weggelassener Teil bleibt, None leert ihn |
fetch_message(message_id), delete_message(message_id) |
eine holen oder löschen |
fetch(), edit(name=..., avatar=...), delete() |
der Webhook selbst |
execute_slack(payload), execute_github(payload) |
einen Payload in den Formaten posten, die Discords Slack- und GitHub-kompatible Endpunkte annehmen |
execute nimmt die Nachrichtenteile und außerdem:
usernameundavatar_url, die für diese Nachricht statt der eigenen des Webhooks angezeigt werden;thread_id, um in einem Thread des Kanals zu posten; die Nachrichtenmethoden nehmen es ebenfalls;thread_name, um in einem Forum- oder Medienkanal einen Thread zu beginnen, mitapplied_tags;with_components=True, nötig für Komponenten an einem Webhook, der keiner App gehört.
Die Clients nehmen api_url, http_settings und allowed_mentions wie der Bot; standardmäßig kann ein Webhook Benutzer und Rollen anpingen, aber nicht @everyone.
Antwortet Discord mit 404 Unknown Webhook, wurde der Webhook gelöscht. bostie beantwortet dann jede spätere Anfrage dafür mit demselben 404, ohne sie zu senden, sodass ein toter Webhook nicht auf das Limit für ungültige Anfragen angerechnet wird.
Webhooks mit einem Bot verwalten¶
bot.rest.webhooks erstellt und listet die Webhooks eines Kanals oder Servers, was die Berechtigung „Webhooks verwalten“ braucht, und hat auch die Token-Methoden:
create(channel_id, name=..., avatar=File(...))gibt einenWebhookzurück, dessenurldu an einenWebhookClientübergeben kannst.list(channel_id),list_guild(guild_id),fetch(webhook_id),edit(webhook_id, ...)unddelete(webhook_id)arbeiten mit dem Token des Bots.execute(webhook_id, token, ...)und die übrigen_with_token- und Nachrichtenmethoden sind das, wasWebhookClientaufruft.
Das Event WebhooksUpdate meldet, dass sich die Webhooks eines Kanals geändert haben. Eine Nachricht, die ein Webhook gesendet hat, kommt als WebhookMessage an, deren author ein PartialUser ist und deren webhook_id gesetzt ist.