Skip to content

Commit f3544ae

Browse files
committed
fix removing embeds and files when editing a webhook
1 parent 385ada8 commit f3544ae

File tree

3 files changed

+60
-36
lines changed

3 files changed

+60
-36
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -244,9 +244,9 @@ embed = DiscordEmbed(title='Embed Title', description='Your Embed Description',
244244
embed.set_thumbnail(url='attachment://example.jpg')
245245

246246
webhook.add_embed(embed)
247-
response = webhook.execute(remove_embeds=True, remove_files=True)
248-
# webhook.files and webhook.embeds will be empty after webhook is executed
249-
# You could also manually call the functions webhook.remove_files() and webhook.remove_embeds()
247+
response = webhook.execute(remove_embeds=True)
248+
# webhook.embeds will be empty after webhook is executed
249+
# You could also manually call the function webhook.remove_embeds()
250250
```
251251

252252
`.remove_file()` removes the given file

discord_webhook/async_webhook.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,10 @@ async def handle_rate_limit(self, response, request):
8888
if response.status_code in [200, 204]:
8989
return response
9090

91-
async def execute(self, remove_embeds=False, remove_files=False):
91+
async def execute(self, remove_embeds=False):
9292
"""
9393
executes the Webhook
9494
:param remove_embeds: if set to True, calls `self.remove_embeds()` to empty `self.embeds` after webhook is executed
95-
:param remove_files: if set to True, calls `self.remove_files()` to empty `self.files` after webhook is executed
9695
:return: Webhook response
9796
"""
9897
response = await self.api_post_request()
@@ -109,8 +108,7 @@ async def execute(self, remove_embeds=False, remove_files=False):
109108
)
110109
if remove_embeds:
111110
self.remove_embeds()
112-
if remove_files:
113-
self.remove_files()
111+
self.remove_files(clear_attachments=False)
114112
if webhook_id := json.loads(response.content.decode("utf-8")).get('id'):
115113
self.id = webhook_id
116114
return response

discord_webhook/webhook.py

Lines changed: 55 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ class DiscordWebhook:
233233
username: Optional[str]
234234
avatar_url: Optional[str]
235235
tts: bool
236+
attachments: Optional[List[Dict[str, Any]]]
236237
files: Dict[str, Tuple[Optional[str], Union[bytes, str]]]
237238
embeds: List[Dict[str, Any]]
238239
proxies: Optional[Dict[str, str]]
@@ -249,6 +250,7 @@ def __init__(
249250
username: Optional[str] = None,
250251
avatar_url: Optional[str] = None,
251252
tts: bool = False,
253+
attachments: Optional[List[Dict[str, Any]]] = None,
252254
files: Optional[Dict[str, Tuple[Optional[str], Union[bytes, str]]]] = None,
253255
embeds: Optional[List[Dict[str, Any]]] = None,
254256
proxies: Optional[Dict[str, str]] = None,
@@ -265,11 +267,11 @@ def __init__(
265267
:keyword ``username:`` override the default username of the webhook\n
266268
:keyword ``avatar_url:`` override the default avatar of the webhook\n
267269
:keyword ``tts:`` true if this is a TTS message\n
268-
:keyword ``file``: to apply file(s) with message
269-
(For example: file=f.read() (here, f = variable that contain
270-
attachement path as "rb" mode))\n
271-
:keyword ``filename:`` apply custom file name on attached file
272-
content(s)\n
270+
:keyword ``attachments`` optional dict of attachments.
271+
Will be set after executing a webhook\n
272+
:keyword ``files``: to apply file(s) with message
273+
(For example: file=f.read() (here, f = variable that contains the
274+
attachment path as "rb" mode))\n
273275
:keyword ``embeds:`` list of embedded rich content\n
274276
:keyword ``allowed_mentions:`` allowed mentions for the message\n
275277
:keyword ``proxies:`` dict of proxies\n
@@ -282,12 +284,15 @@ def __init__(
282284
files = {}
283285
if allowed_mentions is None:
284286
allowed_mentions = []
287+
if attachments is None:
288+
attachments = []
285289
self.url = url
286290
self.id = id
287291
self.content = content
288292
self.username = username
289293
self.avatar_url = avatar_url
290294
self.tts = tts
295+
self.attachments = attachments
291296
self.files = files
292297
self.embeds = embeds
293298
self.proxies = proxies
@@ -320,16 +325,50 @@ def remove_embed(self, index: int) -> None:
320325

321326
def remove_file(self, filename: str) -> None:
322327
"""
323-
Remove file from `self.files` using specified `filename` if it exists.
328+
Remove file by given `filename` if it exists.
324329
:param filename: filename
325330
"""
326-
filename = f"_{filename}"
327-
if filename in self.files:
328-
del self.files[filename]
331+
self.files.pop(f'_{filename}', None)
332+
if self.attachments:
333+
index = next(
334+
(
335+
i
336+
for i, item in enumerate(self.attachments)
337+
if item.get('filename') == filename
338+
),
339+
None,
340+
)
341+
if index is not None:
342+
self.attachments.pop(index)
343+
344+
def remove_embeds(self) -> None:
345+
"""
346+
Remove all embeds.
347+
:return: None
348+
"""
349+
self.embeds = []
350+
351+
def remove_files(self, clear_attachments: bool = True) -> None:
352+
"""
353+
Remove all files and optionally clear the attachments.
354+
:keyword clear_attachments: Clear the attachments.
355+
:type clear_attachments: bool
356+
:return: None
357+
"""
358+
self.files = {}
359+
if clear_attachments:
360+
self.clear_attachments()
361+
362+
def clear_attachments(self) -> None:
363+
"""
364+
Remove all attachments.
365+
:return: None
366+
"""
367+
self.attachments = []
329368

330369
def get_embeds(self) -> List[Dict[str, Any]]:
331370
"""
332-
Get all self.embeds as list.
371+
Get all embeds as a list.
333372
:return: self.embeds
334373
"""
335374
return self.embeds
@@ -364,25 +403,13 @@ def json(self) -> Dict[str, Any]:
364403
data = {
365404
key: value
366405
for key, value in self.__dict__.items()
367-
if value and key not in {"url", "files", "filename"}
406+
if value and key not in ['url', 'files'] or key in ['embeds', 'attachments']
368407
}
369408
embeds_empty = not any(data["embeds"]) if "embeds" in data else True
370409
if embeds_empty and "content" not in data and bool(self.files) is False:
371410
logger.error("webhook message is empty! set content or embed data")
372411
return data
373412

374-
def remove_embeds(self) -> None:
375-
"""
376-
Set `self.embeds` to empty `list`.
377-
"""
378-
self.embeds = []
379-
380-
def remove_files(self) -> None:
381-
"""
382-
Set `self.files` to empty `dict`.
383-
"""
384-
self.files = {}
385-
386413
def api_post_request(self) -> requests.post:
387414
if bool(self.files) is False:
388415
return requests.post(
@@ -422,14 +449,11 @@ def handle_rate_limit(self, response, request):
422449
def execute(
423450
self,
424451
remove_embeds: bool = False,
425-
remove_files: bool = False,
426452
) -> requests.Response:
427453
"""
428454
Execute the Webhook.
429455
:param remove_embeds: if set to True, calls `self.remove_embeds()`
430456
to empty `self.embeds` after webhook is executed
431-
:param remove_files: if set to True, calls `self.remove_files()`
432-
to empty `self.files` after webhook is executed
433457
:return: Webhook response
434458
"""
435459
response = self.api_post_request()
@@ -447,10 +471,12 @@ def execute(
447471
)
448472
if remove_embeds:
449473
self.remove_embeds()
450-
if remove_files:
451-
self.remove_files()
452-
if webhook_id := json.loads(response.content.decode("utf-8")).get('id'):
474+
self.remove_files(clear_attachments=False)
475+
response_content = json.loads(response.content.decode("utf-8"))
476+
if webhook_id := response_content.get('id'):
453477
self.id = webhook_id
478+
if attachments := response_content.get('attachments'):
479+
self.attachments = attachments
454480
return response
455481

456482
def edit(self) -> requests.Response:

0 commit comments

Comments
 (0)