aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNadir Chowdhury <[email protected]>2020-07-01 04:35:42 +0100
committerGitHub <[email protected]>2020-06-30 23:35:42 -0400
commite971e2f16cba22decd25db6b44e9cc84adf08555 (patch)
tree7baf270018d377d4b4df49729cf4ecbdc93ce1e0
parentAllow Webhook to be hashable and comparable (diff)
downloaddiscord.py-e971e2f16cba22decd25db6b44e9cc84adf08555.tar.xz
discord.py-e971e2f16cba22decd25db6b44e9cc84adf08555.zip
Allow more methods to set an audit log reason
-rw-r--r--discord/channel.py8
-rw-r--r--discord/http.py12
-rw-r--r--discord/message.py22
-rw-r--r--discord/webhook.py40
4 files changed, 59 insertions, 23 deletions
diff --git a/discord/channel.py b/discord/channel.py
index a554d0d5..c02c00f3 100644
--- a/discord/channel.py
+++ b/discord/channel.py
@@ -471,7 +471,7 @@ class TextChannel(discord.abc.Messageable, discord.abc.GuildChannel, Hashable):
data = await self._state.http.create_webhook(self.id, name=str(name), avatar=avatar, reason=reason)
return Webhook.from_state(data, state=self._state)
- async def follow(self, *, destination):
+ async def follow(self, *, destination, reason=None):
"""
Follows a channel using a webhook.
@@ -488,6 +488,10 @@ class TextChannel(discord.abc.Messageable, discord.abc.GuildChannel, Hashable):
-----------
destination: :class:`TextChannel`
The channel you would like to follow from.
+ reason: Optional[:class:`str`]
+ The reason for following the channel. Shows up on the destination guild's audit log.
+
+ .. versionadded:: 1.4
Raises
-------
@@ -508,7 +512,7 @@ class TextChannel(discord.abc.Messageable, discord.abc.GuildChannel, Hashable):
if not isinstance(destination, TextChannel):
raise InvalidArgument('Expected TextChannel received {0.__name__}'.format(type(destination)))
- data = await self._state.http.follow_webhook(self.id, webhook_channel_id=destination.id)
+ data = await self._state.http.follow_webhook(self.id, webhook_channel_id=destination.id, reason=reason)
return Webhook._as_follower(data, channel=destination, user=self._state.user)
class VoiceChannel(discord.abc.Connectable, discord.abc.GuildChannel, Hashable):
diff --git a/discord/http.py b/discord/http.py
index 1ad5df26..07bed8cc 100644
--- a/discord/http.py
+++ b/discord/http.py
@@ -443,13 +443,13 @@ class HTTPClient:
return self.request(Route('POST', '/channels/{channel_id}/messages/{message_id}/crosspost',
channel_id=channel_id, message_id=message_id))
- def pin_message(self, channel_id, message_id):
+ def pin_message(self, channel_id, message_id, reason=None):
return self.request(Route('PUT', '/channels/{channel_id}/pins/{message_id}',
- channel_id=channel_id, message_id=message_id))
+ channel_id=channel_id, message_id=message_id), reason=reason)
- def unpin_message(self, channel_id, message_id):
+ def unpin_message(self, channel_id, message_id, reason=None):
return self.request(Route('DELETE', '/channels/{channel_id}/pins/{message_id}',
- channel_id=channel_id, message_id=message_id))
+ channel_id=channel_id, message_id=message_id), reason=reason)
def pins_from(self, channel_id):
return self.request(Route('GET', '/channels/{channel_id}/pins', channel_id=channel_id))
@@ -578,11 +578,11 @@ class HTTPClient:
def get_webhook(self, webhook_id):
return self.request(Route('GET', '/webhooks/{webhook_id}', webhook_id=webhook_id))
- def follow_webhook(self, channel_id, webhook_channel_id):
+ def follow_webhook(self, channel_id, webhook_channel_id, reason=None):
payload = {
'webhook_channel_id': str(webhook_channel_id)
}
- return self.request(Route('POST', '/channels/{channel_id}/followers', channel_id=channel_id), json=payload)
+ return self.request(Route('POST', '/channels/{channel_id}/followers', channel_id=channel_id), json=payload, reason=reason)
# Guild management
diff --git a/discord/message.py b/discord/message.py
index f6565ba1..5b4d79cb 100644
--- a/discord/message.py
+++ b/discord/message.py
@@ -856,7 +856,7 @@ class Message:
await self._state.http.publish_message(self.channel.id, self.id)
- async def pin(self):
+ async def pin(self, *, reason=None):
"""|coro|
Pins the message.
@@ -864,6 +864,13 @@ class Message:
You must have the :attr:`~Permissions.manage_messages` permission to do
this in a non-private channel context.
+ Parameters
+ -----------
+ reason: Optional[:class:`str`]
+ The reason for pinning the message. Shows up on the audit log.
+
+ .. versionadded:: 1.4
+
Raises
-------
Forbidden
@@ -875,10 +882,10 @@ class Message:
having more than 50 pinned messages.
"""
- await self._state.http.pin_message(self.channel.id, self.id)
+ await self._state.http.pin_message(self.channel.id, self.id, reason=reason)
self.pinned = True
- async def unpin(self):
+ async def unpin(self, *, reason=None):
"""|coro|
Unpins the message.
@@ -886,6 +893,13 @@ class Message:
You must have the :attr:`~Permissions.manage_messages` permission to do
this in a non-private channel context.
+ Parameters
+ -----------
+ reason: Optional[:class:`str`]
+ The reason for pinning the message. Shows up on the audit log.
+
+ .. versionadded:: 1.4
+
Raises
-------
Forbidden
@@ -896,7 +910,7 @@ class Message:
Unpinning the message failed.
"""
- await self._state.http.unpin_message(self.channel.id, self.id)
+ await self._state.http.unpin_message(self.channel.id, self.id, reason=reason)
self.pinned = False
async def add_reaction(self, emoji):
diff --git a/discord/webhook.py b/discord/webhook.py
index 64136b9e..317c54c4 100644
--- a/discord/webhook.py
+++ b/discord/webhook.py
@@ -28,6 +28,7 @@ import asyncio
import json
import time
import re
+from urllib.parse import quote as _uriquote
import aiohttp
@@ -84,11 +85,11 @@ class WebhookAdapter:
"""
raise NotImplementedError()
- def delete_webhook(self):
- return self.request('DELETE', self._request_url)
+ def delete_webhook(self, *, reason=None):
+ return self.request('DELETE', self._request_url, reason=reason)
- def edit_webhook(self, **payload):
- return self.request('PATCH', self._request_url, payload=payload)
+ def edit_webhook(self, *, reason=None, **payload):
+ return self.request('PATCH', self._request_url, payload=payload, reason=reason)
def handle_execution_response(self, data, *, wait):
"""Transforms the webhook execution response into something
@@ -174,13 +175,16 @@ class AsyncWebhookAdapter(WebhookAdapter):
self.session = session
self.loop = asyncio.get_event_loop()
- async def request(self, verb, url, payload=None, multipart=None, *, files=None):
+ async def request(self, verb, url, payload=None, multipart=None, *, files=None, reason=None):
headers = {}
data = None
files = files or []
if payload:
headers['Content-Type'] = 'application/json'
data = utils.to_json(payload)
+
+ if reason:
+ headers['X-Audit-Log-Reason'] = _uriquote(reason, safe='/ ')
if multipart:
data = aiohttp.FormData()
@@ -260,13 +264,16 @@ class RequestsWebhookAdapter(WebhookAdapter):
self.session = session or requests
self.sleep = sleep
- def request(self, verb, url, payload=None, multipart=None, *, files=None):
+ def request(self, verb, url, payload=None, multipart=None, *, files=None, reason=None):
headers = {}
data = None
files = files or []
if payload:
headers['Content-Type'] = 'application/json'
data = utils.to_json(payload)
+
+ if reason:
+ headers['X-Audit-Log-Reason'] = _uriquote(reason, safe='/ ')
if multipart is not None:
data = {'payload_json': multipart.pop('payload_json')}
@@ -640,7 +647,7 @@ class Webhook(Hashable):
url = '/avatars/{0.id}/{0.avatar}.{1}?size={2}'.format(self, format, size)
return Asset(self._state, url)
- def delete(self):
+ def delete(self, *, reason=None):
"""|maybecoro|
Deletes this Webhook.
@@ -648,6 +655,13 @@ class Webhook(Hashable):
If the webhook is constructed with a :class:`RequestsWebhookAdapter` then this is
not a coroutine.
+ Parameters
+ ------------
+ reason: Optional[:class:`str`]
+ The reason for deleting this webhook. Shows up on the audit log.
+
+ .. versionadded:: 1.4
+
Raises
-------
HTTPException
@@ -662,9 +676,9 @@ class Webhook(Hashable):
if self.token is None:
raise InvalidArgument('This webhook does not have a token associated with it')
- return self._adapter.delete_webhook()
+ return self._adapter.delete_webhook(reason=reason)
- def edit(self, **kwargs):
+ def edit(self, *, reason=None, **kwargs):
"""|maybecoro|
Edits this Webhook.
@@ -673,11 +687,15 @@ class Webhook(Hashable):
not a coroutine.
Parameters
- -------------
+ ------------
name: Optional[:class:`str`]
The webhook's new default name.
avatar: Optional[:class:`bytes`]
A :term:`py:bytes-like object` representing the webhook's new default avatar.
+ reason: Optional[:class:`str`]
+ The reason for deleting this webhook. Shows up on the audit log.
+
+ .. versionadded:: 1.4
Raises
-------
@@ -713,7 +731,7 @@ class Webhook(Hashable):
else:
payload['avatar'] = None
- return self._adapter.edit_webhook(**payload)
+ return self._adapter.edit_webhook(reason=reason, **payload)
def send(self, content=None, *, wait=False, username=None, avatar_url=None, tts=False,
file=None, files=None, embed=None, embeds=None, allowed_mentions=None):