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);
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
return new Promise((resolve, reject) => {
this._fetchMany({
@ -292,17 +261,21 @@ class MessageManager extends CachedManager {
/**
* @typedef {object} MessageSearchOptions
* @property {Array<Snowflake>} [author] An array of author IDs to filter by
* @property {Array<Snowflake>} [mentions] An array of user IDs (mentioned) to filter by
* @property {Array<UserResolvable>} [authors] An array of author to filter by
* @property {Array<UserResolvable>} [mentions] An array of user (mentioned) to filter by
* @property {string} [content] A messageContent to filter by
* @property {Snowflake} [maxId] The maximum 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 {Array<string>} [has] Message has: `link`, `embed`, `file`, `video`, `image`, or `sound`
* @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} [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}
*/
async search(options = {}) {
let { author, content, mentions, has, maxId, minId, channelId, pinned, nsfw, offset, limit } = Object.assign(
{
author: [],
content: '',
mentions: [],
has: [],
maxId: null,
minId: null,
channelId: [],
pinned: false,
nsfw: false,
offset: 0,
limit: 25,
},
options,
);
// eslint-disable-next-line no-unused-vars
let { authors, content, mentions, has, maxId, minId, channels, pinned, nsfw, offset, limit, sortBy, sortOrder } =
Object.assign(
{
authors: [],
content: '',
mentions: [],
has: [],
maxId: null,
minId: null,
channels: [],
pinned: false,
nsfw: false,
offset: 0,
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 = [];
const result = new Collection();
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 (mentions.length > 0) stringQuery.push(mentions.map(id => `mentions=${id}`).join('&'));
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 (offset !== 0) stringQuery.push(`offset=${offset}`);
if (limit !== 25) stringQuery.push(`limit=${limit}`);
if (this.channel.guildId && channelId.length > 0) {
stringQuery.push(channelId.map(id => `channel_id=${id}`).join('&'));
if (['timestamp', 'relevance'].includes(options.sortBy)) {
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}`);
// Main
@ -363,6 +369,7 @@ class MessageManager extends CachedManager {
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();
}
console.log(stringQuery);
for await (const message of data.messages) result.set(message[0].id, new Message(this.client, message[0]));
return {
messages: result,

8
typings/index.d.ts vendored
View File

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