feat: guild messages search (#1583)

Co-authored-by: Almeida <almeidx@pm.me>
This commit is contained in:
kshitijanurag
2026-03-25 18:15:57 +05:30
committed by GitHub
parent c080b2a838
commit a99c8c0f53
14 changed files with 1424 additions and 6 deletions

View File

@@ -3,7 +3,7 @@
import type { Snowflake } from '../../globals.ts';
import type { _NonNullableFields } from '../../utils/internals.ts';
import type { APIApplication } from './application.ts';
import type { APIChannel, ChannelType } from './channel.ts';
import type { APIChannel, APIThreadChannel, APIThreadMember, ChannelType } from './channel.ts';
import type { APIPartialEmoji } from './emoji.ts';
import type { APIInteractionDataResolved, APIMessageInteraction, APIMessageInteractionMetadata } from './interactions.ts';
import type { APIRole } from './permissions.ts';
@@ -1998,3 +1998,198 @@ export interface APIMessagePin {
*/
message: APIMessage;
}
/**
* @remarks All types can be negated by prefixing them with `-`, which means results will not include messages that match the type.
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages-author-types}
*/
export enum MessageSearchAuthorType {
/**
* Return messages sent by user accounts
*/
User = 'user',
/**
* Return messages sent by bot accounts
*/
Bot = 'bot',
/**
* Return messages sent by webhooks
*/
Webhook = 'webhook',
/**
* Return messages not sent by user accounts
*/
NotUser = '-user',
/**
* Return messages not sent by bot accounts
*/
NotBot = '-bot',
/**
* Return messages not sent by webhooks
*/
NotWebhook = '-webhook',
}
/**
* @remarks All types can be negated by prefixing them with `-`, which means results will not include messages that match the type.
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages-search-has-types}
*/
export enum MessageSearchHasType {
/**
* Return messages that have an image
*/
Image = 'image',
/**
* Return messages that have a sound attachment
*/
Sound = 'sound',
/**
* Return messages that have a video
*/
Video = 'video',
/**
* Return messages that have an attachment
*/
File = 'file',
/**
* Return messages that have a sent sticker
*/
Sticker = 'sticker',
/**
* Return messages that have an embed
*/
Embed = 'embed',
/**
* Return messages that have a link
*/
Link = 'link',
/**
* Return messages that have a poll
*/
Poll = 'poll',
/**
* Return messages that have a forwarded message
*/
Snapshot = 'snapshot',
/**
* Return messages that don't have an image
*/
NotImage = '-image',
/**
* Return messages that don't have a sound attachment
*/
NotSound = '-sound',
/**
* Return messages that don't have a video
*/
NotVideo = '-video',
/**
* Return messages that don't have an attachment
*/
NotFile = '-file',
/**
* Return messages that don't have a sent sticker
*/
NotSticker = '-sticker',
/**
* Return messages that don't have an embed
*/
NotEmbed = '-embed',
/**
* Return messages that don't have a link
*/
NotLink = '-link',
/**
* Return messages that don't have a poll
*/
NotPoll = '-poll',
/**
* Return messages that don't have a forwarded message
*/
NotSnapshot = '-snapshot',
}
/**
* @remarks These do not correspond 1:1 to actual {@link https://docs.discord.com/developers/resources/message#embed-object-embed-types | embed types} and encompass a wider range of actual types.
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages-search-embed-types}
*/
export enum MessageSearchEmbedType {
/**
* Return messages that have an image embed
*/
Image = 'image',
/**
* Return messages that have a video embed
*/
Video = 'video',
/**
* Return messages that have a gifv embed
*
* @remarks Messages sent before February 24, 2026 may not be properly indexed under the `gif` embed type.
*/
Gif = 'gif',
/**
* Return messages that have a sound embed
*/
Sound = 'sound',
/**
* Return messages that have an article embed
*/
Article = 'article',
}
/**
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages-search-sort-modes}
*/
export enum MessageSearchSortMode {
/**
* Sort by the message creation time (default)
*/
Timestamp = 'timestamp',
/**
* Sort by the relevance of the message to the search query
*/
Relevance = 'relevance',
}
/**
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages}
*/
export interface APIMessageSearchIndexNotReadyResponse {
message: string;
code: number;
documents_indexed: number;
retry_after: number;
}
/**
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages-response-body}
*/
export interface APIMessageSearchResult {
/**
* Whether the guild is undergoing a deep historical indexing operation
*/
doing_deep_historical_index: boolean;
/**
* The number of documents that have been indexed during the current index operation, if any
*/
documents_indexed?: number;
/**
* The total number of results that match the query
*/
total_results: number;
/**
* A nested array of messages that match the query
*
* @remarks The nested array was used to provide surrounding context to search results. However, surrounding context is no longer returned.
*/
messages: Omit<APIMessage, 'reactions'>[][];
/**
* The threads that contain the returned messages
*/
threads?: APIThreadChannel[];
/**
* A thread member object for each returned thread the current user has joined
*/
members?: APIThreadMember[];
}

View File

@@ -3,7 +3,7 @@
import type { Snowflake } from '../../globals.ts';
import type { _NonNullableFields } from '../../utils/internals.ts';
import type { APIApplication } from './application.ts';
import type { APIChannel, ChannelType } from './channel.ts';
import type { APIChannel, APIThreadChannel, APIThreadMember, ChannelType } from './channel.ts';
import type { APIPartialEmoji } from './emoji.ts';
import type { APIInteractionDataResolved, APIMessageInteraction, APIMessageInteractionMetadata } from './interactions.ts';
import type { APIRole } from './permissions.ts';
@@ -1994,3 +1994,198 @@ export interface APIMessagePin {
*/
message: APIMessage;
}
/**
* @remarks All types can be negated by prefixing them with `-`, which means results will not include messages that match the type.
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages-author-types}
*/
export enum MessageSearchAuthorType {
/**
* Return messages sent by user accounts
*/
User = 'user',
/**
* Return messages sent by bot accounts
*/
Bot = 'bot',
/**
* Return messages sent by webhooks
*/
Webhook = 'webhook',
/**
* Return messages not sent by user accounts
*/
NotUser = '-user',
/**
* Return messages not sent by bot accounts
*/
NotBot = '-bot',
/**
* Return messages not sent by webhooks
*/
NotWebhook = '-webhook',
}
/**
* @remarks All types can be negated by prefixing them with `-`, which means results will not include messages that match the type.
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages-search-has-types}
*/
export enum MessageSearchHasType {
/**
* Return messages that have an image
*/
Image = 'image',
/**
* Return messages that have a sound attachment
*/
Sound = 'sound',
/**
* Return messages that have a video
*/
Video = 'video',
/**
* Return messages that have an attachment
*/
File = 'file',
/**
* Return messages that have a sent sticker
*/
Sticker = 'sticker',
/**
* Return messages that have an embed
*/
Embed = 'embed',
/**
* Return messages that have a link
*/
Link = 'link',
/**
* Return messages that have a poll
*/
Poll = 'poll',
/**
* Return messages that have a forwarded message
*/
Snapshot = 'snapshot',
/**
* Return messages that don't have an image
*/
NotImage = '-image',
/**
* Return messages that don't have a sound attachment
*/
NotSound = '-sound',
/**
* Return messages that don't have a video
*/
NotVideo = '-video',
/**
* Return messages that don't have an attachment
*/
NotFile = '-file',
/**
* Return messages that don't have a sent sticker
*/
NotSticker = '-sticker',
/**
* Return messages that don't have an embed
*/
NotEmbed = '-embed',
/**
* Return messages that don't have a link
*/
NotLink = '-link',
/**
* Return messages that don't have a poll
*/
NotPoll = '-poll',
/**
* Return messages that don't have a forwarded message
*/
NotSnapshot = '-snapshot',
}
/**
* @remarks These do not correspond 1:1 to actual {@link https://docs.discord.com/developers/resources/message#embed-object-embed-types | embed types} and encompass a wider range of actual types.
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages-search-embed-types}
*/
export enum MessageSearchEmbedType {
/**
* Return messages that have an image embed
*/
Image = 'image',
/**
* Return messages that have a video embed
*/
Video = 'video',
/**
* Return messages that have a gifv embed
*
* @remarks Messages sent before February 24, 2026 may not be properly indexed under the `gif` embed type.
*/
Gif = 'gif',
/**
* Return messages that have a sound embed
*/
Sound = 'sound',
/**
* Return messages that have an article embed
*/
Article = 'article',
}
/**
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages-search-sort-modes}
*/
export enum MessageSearchSortMode {
/**
* Sort by the message creation time (default)
*/
Timestamp = 'timestamp',
/**
* Sort by the relevance of the message to the search query
*/
Relevance = 'relevance',
}
/**
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages}
*/
export interface APIMessageSearchIndexNotReadyResponse {
message: string;
code: number;
documents_indexed: number;
retry_after: number;
}
/**
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages-response-body}
*/
export interface APIMessageSearchResult {
/**
* Whether the guild is undergoing a deep historical indexing operation
*/
doing_deep_historical_index: boolean;
/**
* The number of documents that have been indexed during the current index operation, if any
*/
documents_indexed?: number;
/**
* The total number of results that match the query
*/
total_results: number;
/**
* A nested array of messages that match the query
*
* @remarks The nested array was used to provide surrounding context to search results. However, surrounding context is no longer returned.
*/
messages: Omit<APIMessage, 'reactions'>[][];
/**
* The threads that contain the returned messages
*/
threads?: APIThreadChannel[];
/**
* A thread member object for each returned thread the current user has joined
*/
members?: APIThreadMember[];
}

3
deno/rest/common.ts generated
View File

@@ -287,7 +287,8 @@ export enum RESTJSONErrorCodes {
ReactionWasBlocked = 90_001,
UserCannotUseBurstReactions,
ApplicationNotYetAvailable = 110_001,
IndexNotYetAvailable = 110_000,
ApplicationNotYetAvailable,
APIResourceOverloaded = 130_000,

151
deno/rest/v10/guild.ts generated
View File

@@ -30,6 +30,12 @@ import type {
APIRoleColors,
APIIncidentsData,
APIGuildChannel,
APIMessageSearchIndexNotReadyResponse,
APIMessageSearchResult,
MessageSearchAuthorType,
MessageSearchEmbedType,
MessageSearchHasType,
MessageSearchSortMode,
} from '../../payloads/v10/mod.ts';
import type {
_AddUndefinedToPossiblyUndefinedPropertiesOfInterface,
@@ -536,6 +542,151 @@ export interface RESTPatchAPIGuildMemberJSONBody {
*/
export type RESTPatchAPIGuildMemberResult = APIGuildMember;
/**
* Returns a list of messages without the `reactions` key that match a search query in the guild. Requires the `READ_MESSAGE_HISTORY` permission.
*
* @remarks The Search Guild Messages endpoint is restricted according to whether the `MESSAGE_CONTENT` Privileged Intent is enabled for your application.
*
* If the entity you are searching is not yet indexed, the endpoint will return a 202 accepted response. The response body will not contain any search results, and will look similar to an error response:
* ```json
* {
* "message": "Index not yet available. Try again later",
* "code": 110000,
* "documents_indexed": 0,
* "retry_after": 2
* }
* ```
*
* Due to speed optimizations, search may return slightly fewer results than the limit specified when messages have not been accessed for a long time.
* Clients should not rely on the length of the `messages` array to paginate results.
*
* Additionally, when messages are actively being created or deleted, the `total_results` field may not be accurate.
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages}
*/
export interface RESTGetAPIGuildMessagesSearchQuery {
/**
* Max number of messages to return (1-25)
*
* @defaultValue `25`
*/
limit?: number;
/**
* Number to offset the returned messages by (max 9975)
*/
offset?: number;
/**
* Get messages before this message ID
*/
max_id?: Snowflake;
/**
* Get messages after this message ID
*/
min_id?: Snowflake;
/**
* Max number of words to skip between matching tokens in the search `content` (max 100)
*
* @defaultValue `2`
*/
slop?: number;
/**
* Filter messages by content (max 1024 characters)
*/
content?: string;
/**
* Filter messages by these channels (max 500)
*/
channel_id?: Snowflake[];
/**
* Filter messages by author type
*
* @remarks All types can be negated by prefixing them with `-`, which means results will not include messages that match the type.
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages-author-types}
*/
author_type?: MessageSearchAuthorType[];
/**
* Filter messages by these authors (max 100)
*/
author_id?: Snowflake[];
/**
* Filter messages that mention these users (max 100)
*/
mentions?: Snowflake[];
/**
* Filter messages that mention these roles (max 100)
*/
mentions_role_id?: Snowflake[];
/**
* Filter messages that do or do not mention @everyone
*/
mention_everyone?: boolean;
/**
* Filter messages that reply to these users (max 100)
*/
replied_to_user_id?: Snowflake[];
/**
* Filter messages that reply to these messages (max 100)
*/
replied_to_message_id?: Snowflake[];
/**
* Filter messages by whether they are or are not pinned
*/
pinned?: boolean;
/**
* Filter messages by whether or not they have specific things
*
* @remarks All types can be negated by prefixing them with `-`, which means results will not include messages that match the type.
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages-search-has-types}
*/
has?: MessageSearchHasType[];
/**
* Filter messages by embed type
*
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages-search-embed-types}
*/
embed_type?: MessageSearchEmbedType[];
/**
* Filter messages by embed provider (case-sensitive, e.g. `Tenor`) (max 256 characters, max 100)
*/
embed_provider?: string[];
/**
* Filter messages by link hostname (e.g. `discordapp.com`) (max 256 characters, max 100)
*/
link_hostname?: string[];
/**
* Filter messages by attachment filename (max 1024 characters, max 100)
*/
attachment_filename?: string[];
/**
* Filter messages by attachment extension (e.g. `txt`) (max 256 characters, max 100)
*/
attachment_extension?: string[];
/**
* The sorting algorithm to use
*
* @remarks Sort order is not respected when sorting by relevance.
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages-search-sort-modes}
*/
sort_by?: MessageSearchSortMode;
/**
* The direction to sort (`asc` or `desc`)
*
* @defaultValue `'desc'`
* @remarks Sort order is not respected when sorting by relevance.
*/
sort_order?: 'asc' | 'desc';
/**
* Whether to include results from age-restricted channels
*
* @defaultValue `false`
*/
include_nsfw?: boolean;
}
/**
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages-response-body}
*/
export type RESTGetAPIGuildMessagesSearchResult = APIMessageSearchIndexNotReadyResponse | APIMessageSearchResult;
/**
* @see {@link https://discord.com/developers/docs/resources/guild#modify-current-user-nick}
* @deprecated Use {@link https://discord.com/developers/docs/resources/guild#modify-current-member | Modify Current Member} instead.

8
deno/rest/v10/mod.ts generated
View File

@@ -313,6 +313,14 @@ export const Routes = {
return `/guilds/${guildId}/members/search` as const;
},
/**
* Route for:
* - GET `/guilds/{guild.id}/messages/search`
*/
guildMessagesSearch(guildId: Snowflake) {
return `/guilds/${guildId}/messages/search` as const;
},
/**
* Route for:
* - PATCH `/guilds/{guild.id}/members/@me/nick`

151
deno/rest/v9/guild.ts generated
View File

@@ -30,6 +30,12 @@ import type {
APIRoleColors,
APIIncidentsData,
APIGuildChannel,
APIMessageSearchIndexNotReadyResponse,
APIMessageSearchResult,
MessageSearchAuthorType,
MessageSearchEmbedType,
MessageSearchHasType,
MessageSearchSortMode,
} from '../../payloads/v9/mod.ts';
import type {
_AddUndefinedToPossiblyUndefinedPropertiesOfInterface,
@@ -536,6 +542,151 @@ export interface RESTPatchAPIGuildMemberJSONBody {
*/
export type RESTPatchAPIGuildMemberResult = APIGuildMember;
/**
* Returns a list of messages without the `reactions` key that match a search query in the guild. Requires the `READ_MESSAGE_HISTORY` permission.
*
* @remarks The Search Guild Messages endpoint is restricted according to whether the `MESSAGE_CONTENT` Privileged Intent is enabled for your application.
*
* If the entity you are searching is not yet indexed, the endpoint will return a 202 accepted response. The response body will not contain any search results, and will look similar to an error response:
* ```json
* {
* "message": "Index not yet available. Try again later",
* "code": 110000,
* "documents_indexed": 0,
* "retry_after": 2
* }
* ```
*
* Due to speed optimizations, search may return slightly fewer results than the limit specified when messages have not been accessed for a long time.
* Clients should not rely on the length of the `messages` array to paginate results.
*
* Additionally, when messages are actively being created or deleted, the `total_results` field may not be accurate.
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages}
*/
export interface RESTGetAPIGuildMessagesSearchQuery {
/**
* Max number of messages to return (1-25)
*
* @defaultValue `25`
*/
limit?: number;
/**
* Number to offset the returned messages by (max 9975)
*/
offset?: number;
/**
* Get messages before this message ID
*/
max_id?: Snowflake;
/**
* Get messages after this message ID
*/
min_id?: Snowflake;
/**
* Max number of words to skip between matching tokens in the search `content` (max 100)
*
* @defaultValue `2`
*/
slop?: number;
/**
* Filter messages by content (max 1024 characters)
*/
content?: string;
/**
* Filter messages by these channels (max 500)
*/
channel_id?: Snowflake[];
/**
* Filter messages by author type
*
* @remarks All types can be negated by prefixing them with `-`, which means results will not include messages that match the type.
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages-author-types}
*/
author_type?: MessageSearchAuthorType[];
/**
* Filter messages by these authors (max 100)
*/
author_id?: Snowflake[];
/**
* Filter messages that mention these users (max 100)
*/
mentions?: Snowflake[];
/**
* Filter messages that mention these roles (max 100)
*/
mentions_role_id?: Snowflake[];
/**
* Filter messages that do or do not mention @everyone
*/
mention_everyone?: boolean;
/**
* Filter messages that reply to these users (max 100)
*/
replied_to_user_id?: Snowflake[];
/**
* Filter messages that reply to these messages (max 100)
*/
replied_to_message_id?: Snowflake[];
/**
* Filter messages by whether they are or are not pinned
*/
pinned?: boolean;
/**
* Filter messages by whether or not they have specific things
*
* @remarks All types can be negated by prefixing them with `-`, which means results will not include messages that match the type.
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages-search-has-types}
*/
has?: MessageSearchHasType[];
/**
* Filter messages by embed type
*
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages-search-embed-types}
*/
embed_type?: MessageSearchEmbedType[];
/**
* Filter messages by embed provider (case-sensitive, e.g. `Tenor`) (max 256 characters, max 100)
*/
embed_provider?: string[];
/**
* Filter messages by link hostname (e.g. `discordapp.com`) (max 256 characters, max 100)
*/
link_hostname?: string[];
/**
* Filter messages by attachment filename (max 1024 characters, max 100)
*/
attachment_filename?: string[];
/**
* Filter messages by attachment extension (e.g. `txt`) (max 256 characters, max 100)
*/
attachment_extension?: string[];
/**
* The sorting algorithm to use
*
* @remarks Sort order is not respected when sorting by relevance.
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages-search-sort-modes}
*/
sort_by?: MessageSearchSortMode;
/**
* The direction to sort (`asc` or `desc`)
*
* @defaultValue `'desc'`
* @remarks Sort order is not respected when sorting by relevance.
*/
sort_order?: 'asc' | 'desc';
/**
* Whether to include results from age-restricted channels
*
* @defaultValue `false`
*/
include_nsfw?: boolean;
}
/**
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages-response-body}
*/
export type RESTGetAPIGuildMessagesSearchResult = APIMessageSearchIndexNotReadyResponse | APIMessageSearchResult;
/**
* @see {@link https://discord.com/developers/docs/resources/guild#modify-current-user-nick}
* @deprecated Use {@link https://discord.com/developers/docs/resources/guild#modify-current-member | Modify Current Member} instead.

8
deno/rest/v9/mod.ts generated
View File

@@ -313,6 +313,14 @@ export const Routes = {
return `/guilds/${guildId}/members/search` as const;
},
/**
* Route for:
* - GET `/guilds/{guild.id}/messages/search`
*/
guildMessagesSearch(guildId: Snowflake) {
return `/guilds/${guildId}/messages/search` as const;
},
/**
* Route for:
* - PATCH `/guilds/{guild.id}/members/@me/nick`

View File

@@ -3,7 +3,7 @@
import type { Snowflake } from '../../globals';
import type { _NonNullableFields } from '../../utils/internals';
import type { APIApplication } from './application';
import type { APIChannel, ChannelType } from './channel';
import type { APIChannel, APIThreadChannel, APIThreadMember, ChannelType } from './channel';
import type { APIPartialEmoji } from './emoji';
import type { APIInteractionDataResolved, APIMessageInteraction, APIMessageInteractionMetadata } from './interactions';
import type { APIRole } from './permissions';
@@ -1998,3 +1998,198 @@ export interface APIMessagePin {
*/
message: APIMessage;
}
/**
* @remarks All types can be negated by prefixing them with `-`, which means results will not include messages that match the type.
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages-author-types}
*/
export enum MessageSearchAuthorType {
/**
* Return messages sent by user accounts
*/
User = 'user',
/**
* Return messages sent by bot accounts
*/
Bot = 'bot',
/**
* Return messages sent by webhooks
*/
Webhook = 'webhook',
/**
* Return messages not sent by user accounts
*/
NotUser = '-user',
/**
* Return messages not sent by bot accounts
*/
NotBot = '-bot',
/**
* Return messages not sent by webhooks
*/
NotWebhook = '-webhook',
}
/**
* @remarks All types can be negated by prefixing them with `-`, which means results will not include messages that match the type.
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages-search-has-types}
*/
export enum MessageSearchHasType {
/**
* Return messages that have an image
*/
Image = 'image',
/**
* Return messages that have a sound attachment
*/
Sound = 'sound',
/**
* Return messages that have a video
*/
Video = 'video',
/**
* Return messages that have an attachment
*/
File = 'file',
/**
* Return messages that have a sent sticker
*/
Sticker = 'sticker',
/**
* Return messages that have an embed
*/
Embed = 'embed',
/**
* Return messages that have a link
*/
Link = 'link',
/**
* Return messages that have a poll
*/
Poll = 'poll',
/**
* Return messages that have a forwarded message
*/
Snapshot = 'snapshot',
/**
* Return messages that don't have an image
*/
NotImage = '-image',
/**
* Return messages that don't have a sound attachment
*/
NotSound = '-sound',
/**
* Return messages that don't have a video
*/
NotVideo = '-video',
/**
* Return messages that don't have an attachment
*/
NotFile = '-file',
/**
* Return messages that don't have a sent sticker
*/
NotSticker = '-sticker',
/**
* Return messages that don't have an embed
*/
NotEmbed = '-embed',
/**
* Return messages that don't have a link
*/
NotLink = '-link',
/**
* Return messages that don't have a poll
*/
NotPoll = '-poll',
/**
* Return messages that don't have a forwarded message
*/
NotSnapshot = '-snapshot',
}
/**
* @remarks These do not correspond 1:1 to actual {@link https://docs.discord.com/developers/resources/message#embed-object-embed-types | embed types} and encompass a wider range of actual types.
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages-search-embed-types}
*/
export enum MessageSearchEmbedType {
/**
* Return messages that have an image embed
*/
Image = 'image',
/**
* Return messages that have a video embed
*/
Video = 'video',
/**
* Return messages that have a gifv embed
*
* @remarks Messages sent before February 24, 2026 may not be properly indexed under the `gif` embed type.
*/
Gif = 'gif',
/**
* Return messages that have a sound embed
*/
Sound = 'sound',
/**
* Return messages that have an article embed
*/
Article = 'article',
}
/**
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages-search-sort-modes}
*/
export enum MessageSearchSortMode {
/**
* Sort by the message creation time (default)
*/
Timestamp = 'timestamp',
/**
* Sort by the relevance of the message to the search query
*/
Relevance = 'relevance',
}
/**
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages}
*/
export interface APIMessageSearchIndexNotReadyResponse {
message: string;
code: number;
documents_indexed: number;
retry_after: number;
}
/**
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages-response-body}
*/
export interface APIMessageSearchResult {
/**
* Whether the guild is undergoing a deep historical indexing operation
*/
doing_deep_historical_index: boolean;
/**
* The number of documents that have been indexed during the current index operation, if any
*/
documents_indexed?: number;
/**
* The total number of results that match the query
*/
total_results: number;
/**
* A nested array of messages that match the query
*
* @remarks The nested array was used to provide surrounding context to search results. However, surrounding context is no longer returned.
*/
messages: Omit<APIMessage, 'reactions'>[][];
/**
* The threads that contain the returned messages
*/
threads?: APIThreadChannel[];
/**
* A thread member object for each returned thread the current user has joined
*/
members?: APIThreadMember[];
}

View File

@@ -3,7 +3,7 @@
import type { Snowflake } from '../../globals';
import type { _NonNullableFields } from '../../utils/internals';
import type { APIApplication } from './application';
import type { APIChannel, ChannelType } from './channel';
import type { APIChannel, APIThreadChannel, APIThreadMember, ChannelType } from './channel';
import type { APIPartialEmoji } from './emoji';
import type { APIInteractionDataResolved, APIMessageInteraction, APIMessageInteractionMetadata } from './interactions';
import type { APIRole } from './permissions';
@@ -1994,3 +1994,198 @@ export interface APIMessagePin {
*/
message: APIMessage;
}
/**
* @remarks All types can be negated by prefixing them with `-`, which means results will not include messages that match the type.
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages-author-types}
*/
export enum MessageSearchAuthorType {
/**
* Return messages sent by user accounts
*/
User = 'user',
/**
* Return messages sent by bot accounts
*/
Bot = 'bot',
/**
* Return messages sent by webhooks
*/
Webhook = 'webhook',
/**
* Return messages not sent by user accounts
*/
NotUser = '-user',
/**
* Return messages not sent by bot accounts
*/
NotBot = '-bot',
/**
* Return messages not sent by webhooks
*/
NotWebhook = '-webhook',
}
/**
* @remarks All types can be negated by prefixing them with `-`, which means results will not include messages that match the type.
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages-search-has-types}
*/
export enum MessageSearchHasType {
/**
* Return messages that have an image
*/
Image = 'image',
/**
* Return messages that have a sound attachment
*/
Sound = 'sound',
/**
* Return messages that have a video
*/
Video = 'video',
/**
* Return messages that have an attachment
*/
File = 'file',
/**
* Return messages that have a sent sticker
*/
Sticker = 'sticker',
/**
* Return messages that have an embed
*/
Embed = 'embed',
/**
* Return messages that have a link
*/
Link = 'link',
/**
* Return messages that have a poll
*/
Poll = 'poll',
/**
* Return messages that have a forwarded message
*/
Snapshot = 'snapshot',
/**
* Return messages that don't have an image
*/
NotImage = '-image',
/**
* Return messages that don't have a sound attachment
*/
NotSound = '-sound',
/**
* Return messages that don't have a video
*/
NotVideo = '-video',
/**
* Return messages that don't have an attachment
*/
NotFile = '-file',
/**
* Return messages that don't have a sent sticker
*/
NotSticker = '-sticker',
/**
* Return messages that don't have an embed
*/
NotEmbed = '-embed',
/**
* Return messages that don't have a link
*/
NotLink = '-link',
/**
* Return messages that don't have a poll
*/
NotPoll = '-poll',
/**
* Return messages that don't have a forwarded message
*/
NotSnapshot = '-snapshot',
}
/**
* @remarks These do not correspond 1:1 to actual {@link https://docs.discord.com/developers/resources/message#embed-object-embed-types | embed types} and encompass a wider range of actual types.
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages-search-embed-types}
*/
export enum MessageSearchEmbedType {
/**
* Return messages that have an image embed
*/
Image = 'image',
/**
* Return messages that have a video embed
*/
Video = 'video',
/**
* Return messages that have a gifv embed
*
* @remarks Messages sent before February 24, 2026 may not be properly indexed under the `gif` embed type.
*/
Gif = 'gif',
/**
* Return messages that have a sound embed
*/
Sound = 'sound',
/**
* Return messages that have an article embed
*/
Article = 'article',
}
/**
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages-search-sort-modes}
*/
export enum MessageSearchSortMode {
/**
* Sort by the message creation time (default)
*/
Timestamp = 'timestamp',
/**
* Sort by the relevance of the message to the search query
*/
Relevance = 'relevance',
}
/**
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages}
*/
export interface APIMessageSearchIndexNotReadyResponse {
message: string;
code: number;
documents_indexed: number;
retry_after: number;
}
/**
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages-response-body}
*/
export interface APIMessageSearchResult {
/**
* Whether the guild is undergoing a deep historical indexing operation
*/
doing_deep_historical_index: boolean;
/**
* The number of documents that have been indexed during the current index operation, if any
*/
documents_indexed?: number;
/**
* The total number of results that match the query
*/
total_results: number;
/**
* A nested array of messages that match the query
*
* @remarks The nested array was used to provide surrounding context to search results. However, surrounding context is no longer returned.
*/
messages: Omit<APIMessage, 'reactions'>[][];
/**
* The threads that contain the returned messages
*/
threads?: APIThreadChannel[];
/**
* A thread member object for each returned thread the current user has joined
*/
members?: APIThreadMember[];
}

View File

@@ -287,7 +287,8 @@ export enum RESTJSONErrorCodes {
ReactionWasBlocked = 90_001,
UserCannotUseBurstReactions,
ApplicationNotYetAvailable = 110_001,
IndexNotYetAvailable = 110_000,
ApplicationNotYetAvailable,
APIResourceOverloaded = 130_000,

View File

@@ -30,6 +30,12 @@ import type {
APIRoleColors,
APIIncidentsData,
APIGuildChannel,
APIMessageSearchIndexNotReadyResponse,
APIMessageSearchResult,
MessageSearchAuthorType,
MessageSearchEmbedType,
MessageSearchHasType,
MessageSearchSortMode,
} from '../../payloads/v10/index';
import type {
_AddUndefinedToPossiblyUndefinedPropertiesOfInterface,
@@ -536,6 +542,151 @@ export interface RESTPatchAPIGuildMemberJSONBody {
*/
export type RESTPatchAPIGuildMemberResult = APIGuildMember;
/**
* Returns a list of messages without the `reactions` key that match a search query in the guild. Requires the `READ_MESSAGE_HISTORY` permission.
*
* @remarks The Search Guild Messages endpoint is restricted according to whether the `MESSAGE_CONTENT` Privileged Intent is enabled for your application.
*
* If the entity you are searching is not yet indexed, the endpoint will return a 202 accepted response. The response body will not contain any search results, and will look similar to an error response:
* ```json
* {
* "message": "Index not yet available. Try again later",
* "code": 110000,
* "documents_indexed": 0,
* "retry_after": 2
* }
* ```
*
* Due to speed optimizations, search may return slightly fewer results than the limit specified when messages have not been accessed for a long time.
* Clients should not rely on the length of the `messages` array to paginate results.
*
* Additionally, when messages are actively being created or deleted, the `total_results` field may not be accurate.
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages}
*/
export interface RESTGetAPIGuildMessagesSearchQuery {
/**
* Max number of messages to return (1-25)
*
* @defaultValue `25`
*/
limit?: number;
/**
* Number to offset the returned messages by (max 9975)
*/
offset?: number;
/**
* Get messages before this message ID
*/
max_id?: Snowflake;
/**
* Get messages after this message ID
*/
min_id?: Snowflake;
/**
* Max number of words to skip between matching tokens in the search `content` (max 100)
*
* @defaultValue `2`
*/
slop?: number;
/**
* Filter messages by content (max 1024 characters)
*/
content?: string;
/**
* Filter messages by these channels (max 500)
*/
channel_id?: Snowflake[];
/**
* Filter messages by author type
*
* @remarks All types can be negated by prefixing them with `-`, which means results will not include messages that match the type.
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages-author-types}
*/
author_type?: MessageSearchAuthorType[];
/**
* Filter messages by these authors (max 100)
*/
author_id?: Snowflake[];
/**
* Filter messages that mention these users (max 100)
*/
mentions?: Snowflake[];
/**
* Filter messages that mention these roles (max 100)
*/
mentions_role_id?: Snowflake[];
/**
* Filter messages that do or do not mention @everyone
*/
mention_everyone?: boolean;
/**
* Filter messages that reply to these users (max 100)
*/
replied_to_user_id?: Snowflake[];
/**
* Filter messages that reply to these messages (max 100)
*/
replied_to_message_id?: Snowflake[];
/**
* Filter messages by whether they are or are not pinned
*/
pinned?: boolean;
/**
* Filter messages by whether or not they have specific things
*
* @remarks All types can be negated by prefixing them with `-`, which means results will not include messages that match the type.
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages-search-has-types}
*/
has?: MessageSearchHasType[];
/**
* Filter messages by embed type
*
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages-search-embed-types}
*/
embed_type?: MessageSearchEmbedType[];
/**
* Filter messages by embed provider (case-sensitive, e.g. `Tenor`) (max 256 characters, max 100)
*/
embed_provider?: string[];
/**
* Filter messages by link hostname (e.g. `discordapp.com`) (max 256 characters, max 100)
*/
link_hostname?: string[];
/**
* Filter messages by attachment filename (max 1024 characters, max 100)
*/
attachment_filename?: string[];
/**
* Filter messages by attachment extension (e.g. `txt`) (max 256 characters, max 100)
*/
attachment_extension?: string[];
/**
* The sorting algorithm to use
*
* @remarks Sort order is not respected when sorting by relevance.
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages-search-sort-modes}
*/
sort_by?: MessageSearchSortMode;
/**
* The direction to sort (`asc` or `desc`)
*
* @defaultValue `'desc'`
* @remarks Sort order is not respected when sorting by relevance.
*/
sort_order?: 'asc' | 'desc';
/**
* Whether to include results from age-restricted channels
*
* @defaultValue `false`
*/
include_nsfw?: boolean;
}
/**
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages-response-body}
*/
export type RESTGetAPIGuildMessagesSearchResult = APIMessageSearchIndexNotReadyResponse | APIMessageSearchResult;
/**
* @see {@link https://discord.com/developers/docs/resources/guild#modify-current-user-nick}
* @deprecated Use {@link https://discord.com/developers/docs/resources/guild#modify-current-member | Modify Current Member} instead.

View File

@@ -313,6 +313,14 @@ export const Routes = {
return `/guilds/${guildId}/members/search` as const;
},
/**
* Route for:
* - GET `/guilds/{guild.id}/messages/search`
*/
guildMessagesSearch(guildId: Snowflake) {
return `/guilds/${guildId}/messages/search` as const;
},
/**
* Route for:
* - PATCH `/guilds/{guild.id}/members/@me/nick`

View File

@@ -30,6 +30,12 @@ import type {
APIRoleColors,
APIIncidentsData,
APIGuildChannel,
APIMessageSearchIndexNotReadyResponse,
APIMessageSearchResult,
MessageSearchAuthorType,
MessageSearchEmbedType,
MessageSearchHasType,
MessageSearchSortMode,
} from '../../payloads/v9/index';
import type {
_AddUndefinedToPossiblyUndefinedPropertiesOfInterface,
@@ -536,6 +542,151 @@ export interface RESTPatchAPIGuildMemberJSONBody {
*/
export type RESTPatchAPIGuildMemberResult = APIGuildMember;
/**
* Returns a list of messages without the `reactions` key that match a search query in the guild. Requires the `READ_MESSAGE_HISTORY` permission.
*
* @remarks The Search Guild Messages endpoint is restricted according to whether the `MESSAGE_CONTENT` Privileged Intent is enabled for your application.
*
* If the entity you are searching is not yet indexed, the endpoint will return a 202 accepted response. The response body will not contain any search results, and will look similar to an error response:
* ```json
* {
* "message": "Index not yet available. Try again later",
* "code": 110000,
* "documents_indexed": 0,
* "retry_after": 2
* }
* ```
*
* Due to speed optimizations, search may return slightly fewer results than the limit specified when messages have not been accessed for a long time.
* Clients should not rely on the length of the `messages` array to paginate results.
*
* Additionally, when messages are actively being created or deleted, the `total_results` field may not be accurate.
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages}
*/
export interface RESTGetAPIGuildMessagesSearchQuery {
/**
* Max number of messages to return (1-25)
*
* @defaultValue `25`
*/
limit?: number;
/**
* Number to offset the returned messages by (max 9975)
*/
offset?: number;
/**
* Get messages before this message ID
*/
max_id?: Snowflake;
/**
* Get messages after this message ID
*/
min_id?: Snowflake;
/**
* Max number of words to skip between matching tokens in the search `content` (max 100)
*
* @defaultValue `2`
*/
slop?: number;
/**
* Filter messages by content (max 1024 characters)
*/
content?: string;
/**
* Filter messages by these channels (max 500)
*/
channel_id?: Snowflake[];
/**
* Filter messages by author type
*
* @remarks All types can be negated by prefixing them with `-`, which means results will not include messages that match the type.
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages-author-types}
*/
author_type?: MessageSearchAuthorType[];
/**
* Filter messages by these authors (max 100)
*/
author_id?: Snowflake[];
/**
* Filter messages that mention these users (max 100)
*/
mentions?: Snowflake[];
/**
* Filter messages that mention these roles (max 100)
*/
mentions_role_id?: Snowflake[];
/**
* Filter messages that do or do not mention @everyone
*/
mention_everyone?: boolean;
/**
* Filter messages that reply to these users (max 100)
*/
replied_to_user_id?: Snowflake[];
/**
* Filter messages that reply to these messages (max 100)
*/
replied_to_message_id?: Snowflake[];
/**
* Filter messages by whether they are or are not pinned
*/
pinned?: boolean;
/**
* Filter messages by whether or not they have specific things
*
* @remarks All types can be negated by prefixing them with `-`, which means results will not include messages that match the type.
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages-search-has-types}
*/
has?: MessageSearchHasType[];
/**
* Filter messages by embed type
*
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages-search-embed-types}
*/
embed_type?: MessageSearchEmbedType[];
/**
* Filter messages by embed provider (case-sensitive, e.g. `Tenor`) (max 256 characters, max 100)
*/
embed_provider?: string[];
/**
* Filter messages by link hostname (e.g. `discordapp.com`) (max 256 characters, max 100)
*/
link_hostname?: string[];
/**
* Filter messages by attachment filename (max 1024 characters, max 100)
*/
attachment_filename?: string[];
/**
* Filter messages by attachment extension (e.g. `txt`) (max 256 characters, max 100)
*/
attachment_extension?: string[];
/**
* The sorting algorithm to use
*
* @remarks Sort order is not respected when sorting by relevance.
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages-search-sort-modes}
*/
sort_by?: MessageSearchSortMode;
/**
* The direction to sort (`asc` or `desc`)
*
* @defaultValue `'desc'`
* @remarks Sort order is not respected when sorting by relevance.
*/
sort_order?: 'asc' | 'desc';
/**
* Whether to include results from age-restricted channels
*
* @defaultValue `false`
*/
include_nsfw?: boolean;
}
/**
* @see {@link https://docs.discord.com/developers/resources/message#search-guild-messages-response-body}
*/
export type RESTGetAPIGuildMessagesSearchResult = APIMessageSearchIndexNotReadyResponse | APIMessageSearchResult;
/**
* @see {@link https://discord.com/developers/docs/resources/guild#modify-current-user-nick}
* @deprecated Use {@link https://discord.com/developers/docs/resources/guild#modify-current-member | Modify Current Member} instead.

View File

@@ -313,6 +313,14 @@ export const Routes = {
return `/guilds/${guildId}/members/search` as const;
},
/**
* Route for:
* - GET `/guilds/{guild.id}/messages/search`
*/
guildMessagesSearch(guildId: Snowflake) {
return `/guilds/${guildId}/messages/search` as const;
},
/**
* Route for:
* - PATCH `/guilds/{guild.id}/members/@me/nick`