@@ -126,6 +126,14 @@ def extract_message(self, message):
126126 message_metadata_file .update (file )
127127 yield Message .Url , file ["url" ], message_metadata_file
128128
129+ def extract_search (self , server_id , params ):
130+ for messages in self .api .get_search_messages (server_id , params ):
131+ for message in messages :
132+ if message ["channel_id" ] not in self .server_channels_metadata :
133+ self .parse_channel (self .api .get_channel (
134+ message ["channel_id" ]))
135+ yield from self .extract_message (message )
136+
129137 def extract_channel_text (self , channel_id ):
130138 for message in self .api .get_channel_messages (channel_id ):
131139 yield from self .extract_message (message )
@@ -312,6 +320,30 @@ def items(self):
312320 yield Message .Url , asset ["url" ], asset
313321
314322
323+ class DiscordServerSearchExtractor (DiscordExtractor ):
324+ subcategory = "server-search"
325+ pattern = BASE_PATTERN + r"/channels/(\d+)/search/?\?([^#]+)"
326+ example = "https://discord.com/channels/1234567890/search?QUERY"
327+
328+ def items (self ):
329+ server_id , query = self .groups
330+ server = self .api .get_server (server_id )
331+ self .kwdict .update (self .parse_server (server ))
332+
333+ params = {
334+ ** text .parse_query_list (query , {
335+ "from" , "in" , "has" , "mentions" , "author_id" , "channel_id" }),
336+ "sort_by" : "timestamp" ,
337+ "sort_order" : "desc" ,
338+ }
339+ if "from" in params :
340+ params ["author_id" ] = params .pop ("from" )
341+ if "in" in params :
342+ params ["channel_id" ] = params .pop ("in" )
343+
344+ return self .extract_search (server_id , params )
345+
346+
315347class DiscordServerExtractor (DiscordExtractor ):
316348 subcategory = "server"
317349 pattern = BASE_PATTERN + r"/channels/(\d+)/?$"
@@ -410,6 +442,17 @@ def _method(_):
410442
411443 return self ._pagination (_method , MESSAGES_BATCH )
412444
445+ def get_search_messages (self , server_id , params ):
446+ """Get search messages"""
447+ MESSAGES_BATCH = 25
448+
449+ def _method (offset ):
450+ params ["offset" ] = offset
451+ return self ._call (url , params )["messages" ]
452+
453+ url = f"/guilds/{ server_id } /messages/search"
454+ return self ._pagination (_method , MESSAGES_BATCH )
455+
413456 def get_message (self , channel_id , message_id ):
414457 """Get message information"""
415458 return self ._call ("/channels/" + channel_id + "/messages" , {
0 commit comments