1
1
from datetime import datetime
2
2
from typing import List , Optional , Union
3
3
4
- from ...client .models .component import ActionRow , Button , SelectMenu
4
+ from ...client .models .component import ActionRow , Button , SelectMenu , _build_components
5
5
from .channel import Channel , ThreadMember
6
6
from .member import Member
7
7
from .message import Embed , Emoji , Message , MessageInteraction , Sticker
8
- from .misc import MISSING , ClientStatus , DictSerializerMixin , Snowflake
8
+ from .misc import MISSING , ClientStatus , DictSerializerMixin , File , Snowflake
9
9
from .presence import PresenceActivity
10
10
from .role import Role
11
11
from .user import User
@@ -347,7 +347,7 @@ async def send(
347
347
]
348
348
] = MISSING ,
349
349
tts : Optional [bool ] = MISSING ,
350
- # attachments : Optional[List[Any]] = None, # TODO: post-v4: Replace with own file type.
350
+ files : Optional [Union [ File , List [File ]]] = MISSING ,
351
351
embeds : Optional [Union [Embed , List [Embed ]]] = MISSING ,
352
352
allowed_mentions : Optional [MessageInteraction ] = MISSING ,
353
353
) -> Message :
@@ -360,6 +360,8 @@ async def send(
360
360
:type components: Optional[Union[ActionRow, Button, SelectMenu, List[Actionrow], List[Button], List[SelectMenu]]]
361
361
:param tts?: Whether the message utilizes the text-to-speech Discord programme or not.
362
362
:type tts: Optional[bool]
363
+ :param files?: A file or list of files to be attached to the message.
364
+ :type files: Optional[Union[File, List[File]]]
363
365
:param embeds?: An embed, or list of embeds for the message.
364
366
:type embeds: Optional[Union[Embed, List[Embed]]]
365
367
:param allowed_mentions?: The message interactions/mention limits that the message can refer to.
@@ -383,117 +385,30 @@ async def send(
383
385
384
386
if not components or components is MISSING :
385
387
_components = []
386
- # TODO: Break this obfuscation pattern down to a "builder" method.
387
388
else :
388
- _components : List [dict ] = [{"type" : 1 , "components" : []}]
389
- if isinstance (components , list ) and all (
390
- isinstance (action_row , ActionRow ) for action_row in components
391
- ):
392
- _components = [
393
- {
394
- "type" : 1 ,
395
- "components" : [
396
- (
397
- component ._json
398
- if component ._json .get ("custom_id" ) or component ._json .get ("url" )
399
- else []
400
- )
401
- for component in action_row .components
402
- ],
403
- }
404
- for action_row in components
405
- ]
406
- elif isinstance (components , list ) and all (
407
- isinstance (component , (Button , SelectMenu )) for component in components
408
- ):
409
- for component in components :
410
- if isinstance (component , SelectMenu ):
411
- component ._json ["options" ] = [
412
- options ._json if not isinstance (options , dict ) else options
413
- for options in component ._json ["options" ]
414
- ]
415
- _components = [
416
- {
417
- "type" : 1 ,
418
- "components" : [
419
- (
420
- component ._json
421
- if component ._json .get ("custom_id" ) or component ._json .get ("url" )
422
- else []
423
- )
424
- for component in components
425
- ],
426
- }
427
- ]
428
- elif isinstance (components , list ) and all (
429
- isinstance (action_row , (list , ActionRow )) for action_row in components
430
- ):
431
- _components = []
432
- for action_row in components :
433
- for component in (
434
- action_row if isinstance (action_row , list ) else action_row .components
435
- ):
436
- if isinstance (component , SelectMenu ):
437
- component ._json ["options" ] = [
438
- option ._json for option in component .options
439
- ]
440
- _components .append (
441
- {
442
- "type" : 1 ,
443
- "components" : [
444
- (
445
- component ._json
446
- if component ._json .get ("custom_id" )
447
- or component ._json .get ("url" )
448
- else []
449
- )
450
- for component in (
451
- action_row
452
- if isinstance (action_row , list )
453
- else action_row .components
454
- )
455
- ],
456
- }
457
- )
458
- elif isinstance (components , ActionRow ):
459
- _components [0 ]["components" ] = [
460
- (
461
- component ._json
462
- if component ._json .get ("custom_id" ) or component ._json .get ("url" )
463
- else []
464
- )
465
- for component in components .components
466
- ]
467
- elif isinstance (components , Button ):
468
- _components [0 ]["components" ] = (
469
- [components ._json ]
470
- if components ._json .get ("custom_id" ) or components ._json .get ("url" )
471
- else []
472
- )
473
- elif isinstance (components , SelectMenu ):
474
- components ._json ["options" ] = [
475
- options ._json if not isinstance (options , dict ) else options
476
- for options in components ._json ["options" ]
477
- ]
478
- _components [0 ]["components" ] = (
479
- [components ._json ]
480
- if components ._json .get ("custom_id" ) or components ._json .get ("url" )
481
- else []
482
- )
483
-
484
- # TODO: post-v4: Add attachments into Message obj.
389
+ _components = _build_components (components = components )
390
+
391
+ if not files or files is MISSING :
392
+ _files = []
393
+ elif isinstance (files , list ):
394
+ _files = [file ._json_payload (id ) for id , file in enumerate (files )]
395
+ else :
396
+ _files = [files ._json_payload (0 )]
397
+ files = [files ]
398
+
485
399
payload = Message (
486
400
content = _content ,
487
401
tts = _tts ,
488
- # file=file,
489
- # attachments=_attachments,
402
+ attachments = _files ,
490
403
embeds = _embeds ,
491
404
components = _components ,
492
405
allowed_mentions = _allowed_mentions ,
493
406
)
494
407
495
408
channel = Channel (** await self ._client .create_dm (recipient_id = int (self .user .id )))
496
- res = await self ._client .create_message (channel_id = int (channel .id ), payload = payload ._json )
409
+ res = await self ._client .create_message (
410
+ channel_id = int (channel .id ), payload = payload ._json , files = files
411
+ )
497
412
498
413
return Message (** res , _client = self ._client )
499
414
0 commit comments