diff --git a/packages/discord.js/src/managers/MessageManager.js b/packages/discord.js/src/managers/MessageManager.js index 840dc371cfd5c..8e643873fb417 100644 --- a/packages/discord.js/src/managers/MessageManager.js +++ b/packages/discord.js/src/managers/MessageManager.js @@ -266,6 +266,38 @@ class MessageManager extends CachedManager { await this.client.rest.delete(Routes.channelMessage(this.channel.id, message)); } + + /** + * Ends a poll. + * @param {Snowflake} channelId The id of the channel + * @param {Snowflake} messageId The id of the message + * @returns {Promise} + */ + async endPoll(channelId, messageId) { + const message = await this.client.rest.post(Routes.expirePoll(channelId, messageId)); + return this._add(message, false); + } + + /** + * Options used for fetching voters of an answer in an uncached poll. + * @typedef {FetchPollAnswerVotersOptions} FetchUncachedPollAnswerVotersOptions + * @param {Snowflake} channelId The id of the channel + * @param {Snowflake} messageId The id of the message + * @param {number} answerId The id of the answer + */ + + /** + * Fetches the users that voted for a poll answer. + * @param {FetchUncachedPollAnswerVotersOptions} options The options for fetching the poll answer voters + * @returns {Promise>} + */ + async fetchPollAnswerVoters({ channelId, messageId, answerId, after, limit }) { + const voters = await this.client.rest.get(Routes.pollAnswerVoters(channelId, messageId, answerId), { + query: makeURLSearchParams({ limit, after }), + }); + + return voters.users.reduce((acc, user) => acc.set(user.id, this.client.users._add(user, false)), new Collection()); + } } module.exports = MessageManager; diff --git a/packages/discord.js/src/structures/Poll.js b/packages/discord.js/src/structures/Poll.js index 5492ef3d8cc6d..710ac267cb79d 100644 --- a/packages/discord.js/src/structures/Poll.js +++ b/packages/discord.js/src/structures/Poll.js @@ -1,7 +1,6 @@ 'use strict'; const { Collection } = require('@discordjs/collection'); -const { Routes } = require('discord-api-types/v10'); const Base = require('./Base'); const { PollAnswer } = require('./PollAnswer'); const { DiscordjsError } = require('../errors/DJSError'); @@ -95,19 +94,15 @@ class Poll extends Base { } /** - * End this poll + * Ends this poll. * @returns {Promise} */ - async end() { + end() { if (Date.now() > this.expiresTimestamp) { - throw new DiscordjsError(ErrorCodes.PollAlreadyExpired); + return Promise.reject(new DiscordjsError(ErrorCodes.PollAlreadyExpired)); } - const message = await this.client.rest.post(Routes.expirePoll(this.message.channel.id, this.message.id)); - - const clone = this.message._clone(); - clone._patch(message); - return clone; + return this.message.channel.messages.endPoll(this.message.channel.id, this.message.id); } } diff --git a/packages/discord.js/src/structures/PollAnswer.js b/packages/discord.js/src/structures/PollAnswer.js index 56f66c6bbcd0f..2f42ca5c8e2aa 100644 --- a/packages/discord.js/src/structures/PollAnswer.js +++ b/packages/discord.js/src/structures/PollAnswer.js @@ -1,8 +1,5 @@ 'use strict'; -const { Collection } = require('@discordjs/collection'); -const { makeURLSearchParams } = require('@discordjs/rest'); -const { Routes } = require('discord-api-types/v10'); const Base = require('./Base'); const { Emoji } = require('./Emoji'); @@ -68,24 +65,25 @@ class PollAnswer extends Base { } /** - * @typedef {Object} FetchPollVotersOptions + * Options used for fetching voters of a poll answer. + * @typedef {Object} FetchPollAnswerVotersOptions * @property {number} [limit] The maximum number of voters to fetch * @property {Snowflake} [after] The user id to fetch voters after */ /** - * Fetches the users that voted for this answer - * @param {FetchPollVotersOptions} [options={}] The options for fetching voters + * Fetches the users that voted for this answer. + * @param {FetchPollAnswerVotersOptions} [options={}] The options for fetching voters * @returns {Promise>} */ - async fetchVoters({ after, limit } = {}) { - const { message } = this.poll; - - const voters = await this.client.rest.get(Routes.pollAnswerVoters(message.channel.id, message.id, this.id), { - query: makeURLSearchParams({ limit, after }), + fetchVoters({ after, limit } = {}) { + return this.poll.message.channel.fetchPollAnswerVoters({ + channelId: this.poll.message.channel.id, + messageId: this.poll.message.id, + answerId: this.id, + after, + limit, }); - - return voters.users.reduce((acc, user) => acc.set(user.id, this.client.users._add(user, false)), new Collection()); } } diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index f1a2d8b1cd0ac..939d29eb8eddd 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -2606,7 +2606,7 @@ export class Poll extends Base { public end(): Promise; } -export interface FetchPollVotersOptions { +export interface FetchPollAnswerVotersOptions { after?: Snowflake; limit?: number; } @@ -2619,7 +2619,7 @@ export class PollAnswer extends Base { public text: string | null; public voteCount: number; public get emoji(): GuildEmoji | Emoji | null; - public fetchVoters(options?: FetchPollVotersOptions): Promise>; + public fetchVoters(options?: FetchPollAnswerVotersOptions): Promise>; } export class ReactionCollector extends Collector { @@ -4394,6 +4394,12 @@ export class GuildMemberRoleManager extends DataManager; } +export interface FetchUncachedPollAnswerVotersOptions extends FetchPollAnswerVotersOptions { + channelId: Snowflake; + messageId: Snowflake; + answerId: number; +} + export abstract class MessageManager extends CachedManager< Snowflake, Message, @@ -4412,6 +4418,8 @@ export abstract class MessageManager extends public react(message: MessageResolvable, emoji: EmojiIdentifierResolvable): Promise; public pin(message: MessageResolvable, reason?: string): Promise; public unpin(message: MessageResolvable, reason?: string): Promise; + public endPoll(channelId: Snowflake, messageId: Snowflake): Promise; + public fetchPollAnswerVoters(options: FetchUncachedPollAnswerVotersOptions): Promise>; } export class DMMessageManager extends MessageManager { diff --git a/packages/discord.js/typings/index.test-d.ts b/packages/discord.js/typings/index.test-d.ts index de82182fc7f61..5f1713c5b06ed 100644 --- a/packages/discord.js/typings/index.test-d.ts +++ b/packages/discord.js/typings/index.test-d.ts @@ -2546,4 +2546,11 @@ declare const poll: Poll; expectType(answer.voteCount); expectType>(await answer.fetchVoters({ after: snowflake, limit: 10 })); + + await messageManager.endPoll(snowflake, snowflake); + await messageManager.fetchPollAnswerVoters({ + channelId: snowflake, + messageId: snowflake, + answerId: 1, + }); }