[discord] add 'server-search' extractor

requested on Discord

https://discord.com/channels/SERVER_ID/search?from=USER_ID
This commit is contained in:
Mike Fährmann
2026-01-29 21:42:08 +01:00
parent 690b3ba200
commit 532ab7112e
3 changed files with 54 additions and 1 deletions

View File

@@ -268,7 +268,7 @@ Consider all listed sites to potentially be NSFW.
<tr id="discord" title="discord">
<td>Discord</td>
<td>https://discord.com/</td>
<td>Channels, DMs, Messages, Servers, Server Assets</td>
<td>Channels, DMs, Messages, Servers, Server Assets, Server Searches</td>
<td></td>
</tr>
<tr id="dynastyscans" title="dynastyscans">

View File

@@ -126,6 +126,14 @@ class DiscordExtractor(Extractor):
message_metadata_file.update(file)
yield Message.Url, file["url"], message_metadata_file
def extract_search(self, server_id, params):
for messages in self.api.get_search_messages(server_id, params):
for message in messages:
if message["channel_id"] not in self.server_channels_metadata:
self.parse_channel(self.api.get_channel(
message["channel_id"]))
yield from self.extract_message(message)
def extract_channel_text(self, channel_id):
for message in self.api.get_channel_messages(channel_id):
yield from self.extract_message(message)
@@ -312,6 +320,30 @@ class DiscordServerAssetsExtractor(DiscordExtractor):
yield Message.Url, asset["url"], asset
class DiscordServerSearchExtractor(DiscordExtractor):
subcategory = "server-search"
pattern = BASE_PATTERN + r"/channels/(\d+)/search/?\?([^#]+)"
example = "https://discord.com/channels/1234567890/search?QUERY"
def items(self):
server_id, query = self.groups
server = self.api.get_server(server_id)
self.kwdict.update(self.parse_server(server))
params = {
**text.parse_query_list(query, {
"from", "in", "has", "mentions", "author_id", "channel_id"}),
"sort_by" : "timestamp",
"sort_order": "desc",
}
if "from" in params:
params["author_id"] = params.pop("from")
if "in" in params:
params["channel_id"] = params.pop("in")
return self.extract_search(server_id, params)
class DiscordServerExtractor(DiscordExtractor):
subcategory = "server"
pattern = BASE_PATTERN + r"/channels/(\d+)/?$"
@@ -410,6 +442,17 @@ class DiscordAPI():
return self._pagination(_method, MESSAGES_BATCH)
def get_search_messages(self, server_id, params):
"""Get search messages"""
MESSAGES_BATCH = 25
def _method(offset):
params["offset"] = offset
return self._call(url, params)["messages"]
url = f"/guilds/{server_id}/messages/search"
return self._pagination(_method, MESSAGES_BATCH)
def get_message(self, channel_id, message_id):
"""Get message information"""
return self._call("/channels/" + channel_id + "/messages", {

View File

@@ -107,4 +107,14 @@ __tests__ = (
"url" : str,
},
{
"#url" : "https://discord.com/channels/1067148002722062416/search?from=429235270664060948",
"#class" : discord.DiscordServerSearchExtractor,
},
{
"#url" : "https://discord.com/channels/1067148002722062416/search?has=file&has=link&mentions=429235270664060948",
"#class" : discord.DiscordServerSearchExtractor,
},
)