feat: update searchMessages

Breaking Change:
```diff
- author
- channelId
+ authors
+ channels
```
This commit is contained in:
Elysia 2023-04-28 19:46:37 +07:00
parent a5c0f09482
commit 3b793e80cd
2 changed files with 65 additions and 56 deletions

View File

@ -239,37 +239,6 @@ class MessageManager extends CachedManager {
const existing = this.cache.get(messageId); const existing = this.cache.get(messageId);
if (existing && !existing.partial) return existing; if (existing && !existing.partial) return existing;
} }
// Search API
/*
if (this.channel.guildId) {
const data = (
await this.client.api.guilds[this.channel.guild.id].messages.search.get({
query: {
channel_id: this.channel.id,
max_id: `${BigInt(messageId) + 1n}`,
min_id: `${BigInt(messageId) - 1n}`,
include_nsfw: true,
},
})
).messages[0];
if (data) return this._add(data[0], cache);
else throw new Error('MESSAGE_ID_NOT_FOUND');
} else {
const data = (
await this.client.api.channels[this.channel.id].messages.search.get({
query: {
max_id: `${BigInt(messageId) + 1n}`,
min_id: `${BigInt(messageId) - 1n}`,
},
})
).messages[0];
if (data) return this._add(data[0], cache);
else throw new Error('MESSAGE_ID_NOT_FOUND');
}
*/
// Get API
// https://discord.com/api/v9/channels/:id/messages?limit=50&around=:msgid // https://discord.com/api/v9/channels/:id/messages?limit=50&around=:msgid
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
this._fetchMany({ this._fetchMany({
@ -292,17 +261,21 @@ class MessageManager extends CachedManager {
/** /**
* @typedef {object} MessageSearchOptions * @typedef {object} MessageSearchOptions
* @property {Array<Snowflake>} [author] An array of author IDs to filter by * @property {Array<UserResolvable>} [authors] An array of author to filter by
* @property {Array<Snowflake>} [mentions] An array of user IDs (mentioned) to filter by * @property {Array<UserResolvable>} [mentions] An array of user (mentioned) to filter by
* @property {string} [content] A messageContent to filter by * @property {string} [content] A messageContent to filter by
* @property {Snowflake} [maxId] The maximum Message ID to filter by * @property {Snowflake} [maxId] The maximum Message ID to filter by
* @property {Snowflake} [minId] The minimum Message ID to filter by * @property {Snowflake} [minId] The minimum Message ID to filter by
* @property {Array<Snowflake>} [channel] An array of channel IDs to filter by * @property {Array<TextChannelResolvable>} [channels] An array of channel to filter by
* @property {boolean} [pinned] Whether to filter by pinned messages * @property {boolean} [pinned] Whether to filter by pinned messages
* @property {Array<string>} [has] Message has: `link`, `embed`, `file`, `video`, `image`, or `sound` * @property {Array<string>} [has] Message has: `link`, `embed`, `file`, `video`, `image`, or `sound`
* @property {boolean} [nsfw=false] Whether to filter by NSFW channels * @property {boolean} [nsfw=false] Whether to filter by NSFW channels
* @property {number} [offset=0] The number of messages to skip (for pagination, 25 results per page) * @property {number} [offset=0] The number of messages to skip (for pagination, 25 results per page)
* @property {number} [limit=25] The number of messages to fetch * @property {number} [limit=25] The number of messages to fetch
* <info>The maximum limit allowed is 25.</info>
* @property {string} [sortBy] The order to sort by (`timestamp` or `relevance`)
* @property {string} [sortOrder] The order to return results in (`asc` or `desc`)
* <info>The default sort is <code>timestamp</code> in descending order <code>desc</code> (newest first).</info>
*/ */
/** /**
@ -317,26 +290,49 @@ class MessageManager extends CachedManager {
* @returns {MessageSearchResult} * @returns {MessageSearchResult}
*/ */
async search(options = {}) { async search(options = {}) {
let { author, content, mentions, has, maxId, minId, channelId, pinned, nsfw, offset, limit } = Object.assign( // eslint-disable-next-line no-unused-vars
{ let { authors, content, mentions, has, maxId, minId, channels, pinned, nsfw, offset, limit, sortBy, sortOrder } =
author: [], Object.assign(
content: '', {
mentions: [], authors: [],
has: [], content: '',
maxId: null, mentions: [],
minId: null, has: [],
channelId: [], maxId: null,
pinned: false, minId: null,
nsfw: false, channels: [],
offset: 0, pinned: false,
limit: 25, nsfw: false,
}, offset: 0,
options, limit: 25,
); sortBy: 'timestamp',
sortOrder: 'desc',
},
options,
);
// Validate
if (authors.length > 0) authors = authors.map(u => this.client.users.resolveId(u));
if (mentions.length > 0) mentions = mentions.map(u => this.client.users.resolveId(u));
if (channels.length > 0) {
channels = channels
.map(c => this.client.channels.resolveId(c))
.filter(id => {
if (this.channel.guildId) {
const c = this.channel.guild.channels.cache.get(id);
if (!c || !c.messages) return false;
const perm = c.permissionsFor(this.client.user);
if (!perm.has('READ_MESSAGE_HISTORY') || !perm.has('VIEW_CHANNEL')) return false;
return true;
} else {
return true;
}
});
}
if (limit && limit > 25) throw new RangeError('MESSAGE_SEARCH_LIMIT');
let stringQuery = []; let stringQuery = [];
const result = new Collection(); const result = new Collection();
let data; let data;
if (author.length > 0) stringQuery.push(author.map(id => `author_id=${id}`).join('&')); if (authors.length > 0) stringQuery.push(authors.map(id => `author_id=${id}`).join('&'));
if (content && content.length) stringQuery.push(`content=${encodeURIComponent(content)}`); if (content && content.length) stringQuery.push(`content=${encodeURIComponent(content)}`);
if (mentions.length > 0) stringQuery.push(mentions.map(id => `mentions=${id}`).join('&')); if (mentions.length > 0) stringQuery.push(mentions.map(id => `mentions=${id}`).join('&'));
has = has.filter(v => ['link', 'embed', 'file', 'video', 'image', 'sound', 'sticker'].includes(v)); has = has.filter(v => ['link', 'embed', 'file', 'video', 'image', 'sound', 'sticker'].includes(v));
@ -346,8 +342,18 @@ class MessageManager extends CachedManager {
if (nsfw) stringQuery.push('include_nsfw=true'); if (nsfw) stringQuery.push('include_nsfw=true');
if (offset !== 0) stringQuery.push(`offset=${offset}`); if (offset !== 0) stringQuery.push(`offset=${offset}`);
if (limit !== 25) stringQuery.push(`limit=${limit}`); if (limit !== 25) stringQuery.push(`limit=${limit}`);
if (this.channel.guildId && channelId.length > 0) { if (['timestamp', 'relevance'].includes(options.sortBy)) {
stringQuery.push(channelId.map(id => `channel_id=${id}`).join('&')); stringQuery.push(`sort_by=${options.sortBy}`);
} else {
stringQuery.push('sort_by=timestamp');
}
if (['asc', 'desc'].includes(options.sortOrder)) {
stringQuery.push(`sort_order=${options.sortOrder}`);
} else {
stringQuery.push('sort_order=desc');
}
if (this.channel.guildId && channels.length > 0) {
stringQuery.push(channels.map(id => `channel_id=${id}`).join('&'));
} }
if (typeof pinned == 'boolean') stringQuery.push(`pinned=${pinned}`); if (typeof pinned == 'boolean') stringQuery.push(`pinned=${pinned}`);
// Main // Main
@ -363,6 +369,7 @@ class MessageManager extends CachedManager {
stringQuery = stringQuery.filter(v => !v.startsWith('channel_id') && !v.startsWith('include_nsfw')); stringQuery = stringQuery.filter(v => !v.startsWith('channel_id') && !v.startsWith('include_nsfw'));
data = await this.client.api.channels[this.channel.id].messages[`search?${stringQuery.join('&')}`].get(); data = await this.client.api.channels[this.channel.id].messages[`search?${stringQuery.join('&')}`].get();
} }
console.log(stringQuery);
for await (const message of data.messages) result.set(message[0].id, new Message(this.client, message[0])); for await (const message of data.messages) result.set(message[0].id, new Message(this.client, message[0]));
return { return {
messages: result, messages: result,

8
typings/index.d.ts vendored
View File

@ -4260,17 +4260,19 @@ export class InteractionResponse extends Base {
} }
export interface MessageSearchOptions { export interface MessageSearchOptions {
author: Snowflake[]; authors: UserResolvable[];
content: string; content: string;
mentions: Snowflake[]; mentions: UserResolvable[];
has: ('link' | 'embed' | 'file' | 'video' | 'image' | 'sound' | 'sticker')[]; has: ('link' | 'embed' | 'file' | 'video' | 'image' | 'sound' | 'sticker')[];
maxId: Snowflake; maxId: Snowflake;
minId: Snowflake; minId: Snowflake;
channelId: Snowflake[]; channels: TextChannelResolvable[];
pinned: boolean; pinned: boolean;
nsfw: boolean; nsfw: boolean;
offset: number; offset: number;
limit: number; limit: number;
sortBy: 'relevant' | 'timestamp';
sortOrder: 'asc' | 'desc';
} }
export interface MessageSearchResult { export interface MessageSearchResult {