Skip to content

Commit

Permalink
feat: support polls
Browse files Browse the repository at this point in the history
  • Loading branch information
Snazzah committed Sep 17, 2024
1 parent 8b04627 commit 4705fc4
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 9 deletions.
5 changes: 5 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,11 @@ export enum StickerFormat {
GIF = 4
}

/** The layouts polls can be in. */
export enum PollLayoutType {
DEFAULT = 1
}

/**
* An partial application command in Discord.
* @private
Expand Down
29 changes: 21 additions & 8 deletions src/structures/interfaces/messageInteraction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
FormattedAllowedMentions,
MessageAllowedMentions
} from '../../util';
import { Message, MessageEmbedOptions } from '../message';
import { CreatePollOptions, Message, MessageEmbedOptions } from '../message';
import { BaseInteractionContext } from './baseInteraction';

/** Represents a interaction context that handles messages. */
Expand Down Expand Up @@ -71,7 +71,8 @@ export class MessageInteractionContext<

const options = typeof content === 'string' ? { content } : content;
if (typeof options !== 'object') throw new Error('Message options is not an object.');
if (!options.content && !options.embeds && !options.files) throw new Error('No valid options were given.');
if (!options.content && !options.embeds && !options.files && !options.poll)
throw new Error('No valid options were given.');
if (options.ephemeral && !options.flags) options.flags = InteractionResponseFlags.EPHEMERAL;

const allowedMentions = options.allowedMentions
Expand All @@ -92,7 +93,8 @@ export class MessageInteractionContext<
flags: options.flags,
allowed_mentions: allowedMentions,
components: options.components,
attachments: options.attachments
attachments: options.attachments,
poll: options.poll
}
},
files: options.files
Expand All @@ -111,8 +113,8 @@ export class MessageInteractionContext<

const options = typeof content === 'string' ? { content } : content;
if (typeof options !== 'object') throw new Error('Message options is not an object.');
if (!options.content && !options.embeds && !options.files)
throw new Error('Message content, embeds or files need to be given.');
if (!options.content && !options.embeds && !options.files && !options.poll)
throw new Error('No valid options were given.');
if (options.ephemeral && !options.flags) options.flags = InteractionResponseFlags.EPHEMERAL;

const allowedMentions = options.allowedMentions
Expand All @@ -129,7 +131,8 @@ export class MessageInteractionContext<
allowed_mentions: allowedMentions,
components: options.components,
flags: options.flags,
attachments: options.attachments
attachments: options.attachments,
poll: options.poll
},
options.files
);
Expand All @@ -146,7 +149,14 @@ export class MessageInteractionContext<

const options = typeof content === 'string' ? { content } : content;
if (typeof options !== 'object') throw new Error('Message options is not an object.');
if (!options.content && !options.embeds && !options.components && !options.files && !options.attachments)
if (
!options.content &&
!options.embeds &&
!options.components &&
!options.files &&
!options.attachments &&
!options.poll
)
throw new Error('No valid options were given.');

const allowedMentions = options.allowedMentions
Expand All @@ -162,7 +172,8 @@ export class MessageInteractionContext<
embeds: options.embeds,
allowed_mentions: allowedMentions,
components: options.components,
attachments: options.attachments
attachments: options.attachments,
poll: options.poll
},
options.files
);
Expand Down Expand Up @@ -401,6 +412,8 @@ export interface EditMessageOptions {
components?: AnyComponent[];
/** The attachment data of the message. */
attachments?: MessageAttachmentOptions[];
/** A poll. */
poll?: CreatePollOptions;
}

/** A file within {@link EditMessageOptions}. */
Expand Down
57 changes: 56 additions & 1 deletion src/structures/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import {
ApplicationIntegrationType,
CommandChannel,
InteractionType,
PartialEmoji,
PollLayoutType,
StickerFormat,
UserObject
} from '../constants';
Expand All @@ -11,6 +13,7 @@ import { BaseSlashCreator } from '../creator';
import { MessageInteractionContext } from './interfaces/messageInteraction';
import { User } from './user';
import { Channel } from './channel';
import { PartialBy } from '../util';

/** Represents a Discord message. */
export class Message {
Expand Down Expand Up @@ -46,6 +49,8 @@ export class Message {
readonly pinned: boolean;
/** The approximate position of the message in a thread. */
readonly position?: number;
/** The poll in the message. */
readonly poll?: PollObject;
/** The thread that was started from this message. */
readonly thread?: Channel;
/** The timestamp of the message */
Expand Down Expand Up @@ -100,7 +105,7 @@ export class Message {
participants: data.call.participants,
endedTimestamp: data.call.ended_timestamp
};
this.call = data.call;
this.poll = data.poll;
this.position = data.position;
this.timestamp = Date.parse(data.timestamp);
if (data.edited_timestamp) this.editedTimestamp = Date.parse(data.edited_timestamp);
Expand Down Expand Up @@ -266,6 +271,55 @@ export interface MessageAttachment {
flags?: number;
}

export interface CreatePollOptions {
/** The question of the poll. */
question: PollMedia;
/** The answers of the poll. `answer_id` is optional. */
answers: PartialBy<PollAnswer, 'answer_id'>[];
/** The duration (in hours) the poll will be open for */
duration?: number;
/** Whether to allow for multiple options to be selected */
allow_multiselect?: boolean;
/** The layout type of the poll */
layout_type?: PollLayoutType;
}

export interface PollObject {
/** The question of the poll. */
question: PollMedia;
/** The answers of the poll. */
answers: PollAnswer[];
/** The expiration of the poll */
expiry: string | null;
/** Whether you can select multiple options in thie poll */
allow_multiselect: boolean;
/** The layout type of the poll */
layout_type: PollLayoutType;
/** The results of the poll if finished */
results?: PollResults;
}

export interface PollResults {
is_finalized: boolean;
answer_counts: PollAnswerCount[];
}

export interface PollAnswerCount {
id: number;
count: number;
me_voted: boolean;
}

export interface PollMedia {
text?: string;
emoji?: PartialEmoji;
}

export interface PollAnswer {
answer_id: number;
poll_media: PollMedia;
}

/** Options to creating a message embed. */
export interface MessageEmbedOptions {
author?: EmbedAuthorOptions;
Expand Down Expand Up @@ -369,6 +423,7 @@ export interface MessageData {
participants: string[];
ended_timestamp?: string;
};
poll?: PollObject;
position?: number;
thread?: CommandChannel;
timestamp: string;
Expand Down
3 changes: 3 additions & 0 deletions src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,3 +177,6 @@ export interface FormattedAllowedMentions {
roles?: string[];
users?: string[];
}

/** @hidden */
export type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;

0 comments on commit 4705fc4

Please sign in to comment.