@@ -1309,9 +1309,18 @@ async def get_contexts(self, message, *, cls=commands.Context):
13091309 # Check if a snippet is being called.
13101310 # This needs to be done before checking for aliases since
13111311 # snippets can have multiple words.
1312+ snippet_invoked = False
13121313 try :
13131314 # Use removeprefix once PY3.9+
1314- snippet_text = self .snippets [message .content [len (invoked_prefix ) :]]
1315+ snippet_data = self .snippets [message .content [len (invoked_prefix ) :]]
1316+ # Extract text from snippet (handle both old string format and new dict format)
1317+ if isinstance (snippet_data , str ):
1318+ snippet_text = snippet_data
1319+ elif isinstance (snippet_data , dict ):
1320+ snippet_text = snippet_data .get ("text" , "" )
1321+ else :
1322+ snippet_text = None
1323+ snippet_invoked = True
13151324 except KeyError :
13161325 snippet_text = None
13171326
@@ -1327,9 +1336,43 @@ async def get_contexts(self, message, *, cls=commands.Context):
13271336 for alias in aliases :
13281337 command = None
13291338 try :
1330- snippet_text = self .snippets [alias ]
1339+ snippet_data = self .snippets [alias ]
1340+ # Extract text from snippet (handle both old string format and new dict format)
1341+ if isinstance (snippet_data , str ):
1342+ snippet_text = snippet_data
1343+ elif isinstance (snippet_data , dict ):
1344+ snippet_text = snippet_data .get ("text" , "" )
1345+ # Download attachment if present
1346+ if snippet_data .get ("file_id" ):
1347+ try :
1348+ import io
1349+
1350+ file_data , metadata = await self .api .download_snippet_attachment (
1351+ snippet_data ["file_id" ]
1352+ )
1353+
1354+ class AttachmentWrapper :
1355+ def __init__ (self , file_data , metadata ):
1356+ self .file_data = file_data
1357+ self .id = 0
1358+ self .url = f"attachment://{ metadata ['filename' ]} "
1359+ self .filename = metadata ["filename" ]
1360+ self .size = metadata ["length" ]
1361+ self .width = None
1362+
1363+ async def to_file (self ):
1364+ return discord .File (
1365+ io .BytesIO (self .file_data ), filename = self .filename
1366+ )
1367+
1368+ message .attachments = [AttachmentWrapper (file_data , metadata )]
1369+ except Exception as e :
1370+ logger .warning ("Failed to download snippet attachment: %s" , e )
1371+ else :
1372+ snippet_text = None
13311373 except KeyError :
13321374 command_invocation_text = alias
1375+ snippet_text = None
13331376 else :
13341377 command = self ._get_snippet_command ()
13351378 command_invocation_text = f"{ invoked_prefix } { command } { snippet_text } "
@@ -1346,11 +1389,38 @@ async def get_contexts(self, message, *, cls=commands.Context):
13461389
13471390 if snippet_text is not None :
13481391 # Process snippets
1392+ snippet_name = message .content [len (invoked_prefix ) :]
1393+ snippet_data = self .snippets .get (snippet_name )
1394+ # Download attachment if present
1395+ if isinstance (snippet_data , dict ) and snippet_data .get ("file_id" ):
1396+ try :
1397+ import io
1398+
1399+ file_data , metadata = await self .api .download_snippet_attachment (snippet_data ["file_id" ])
1400+
1401+ # Create a list-like object that mimics message.attachments
1402+ class AttachmentWrapper :
1403+ def __init__ (self , file_data , metadata ):
1404+ self .file_data = file_data
1405+ self .id = 0
1406+ self .url = f"attachment://{ metadata ['filename' ]} "
1407+ self .filename = metadata ["filename" ]
1408+ self .size = metadata ["length" ]
1409+ self .width = None
1410+
1411+ async def to_file (self ):
1412+ return discord .File (io .BytesIO (self .file_data ), filename = self .filename )
1413+
1414+ message .attachments = [AttachmentWrapper (file_data , metadata )]
1415+ except Exception as e :
1416+ logger .warning ("Failed to download snippet attachment: %s" , e )
13491417 ctx .command = self ._get_snippet_command ()
13501418 reply_view = StringView (f"{ invoked_prefix } { ctx .command } { snippet_text } " )
13511419 discord .utils .find (reply_view .skip_string , prefixes )
13521420 ctx .invoked_with = reply_view .get_word ().lower ()
13531421 ctx .view = reply_view
1422+ # Mark that a snippet was invoked so we can delete the command message
1423+ ctx .snippet_invoked = snippet_invoked
13541424 else :
13551425 ctx .command = self .all_commands .get (invoker )
13561426 ctx .invoked_with = invoker
0 commit comments