-
Notifications
You must be signed in to change notification settings - Fork 91
Implement polls #933
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Implement polls #933
Conversation
|
Would love to see this feature merged after a review, conflicts resolved and fixes |
i can take a look, but i'll be on vacation for a week first |
Small world, I'm on vacation rn for a week Have a good week. I can upgrade my bot in a significant way with it. |
Currently this is only partial and we might add something like a PollMessage or Poll class to core
|
Now ready |
13b3d10 to
2a306cd
Compare
They seem to be here by accident, I already removed them for good in #944.
All other kord enums use camel case naming.
lukellmann
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also missing Permission.SendPolls, Intent.GuildMessagePolls, Intent.DirectMessagePolls
| val values: Optional<List<String>> = Optional.Missing(), | ||
| val components: Optional<List<DiscordComponent>> = Optional.Missing() | ||
| val components: Optional<List<DiscordComponent>> = Optional.Missing(), | ||
| val poll: Optional<DiscordPoll> = Optional.Missing() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| val poll: Optional<DiscordPoll> = Optional.Missing() |
InteractionCallbackData models https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-object-interaction-data, there is no poll object there (it would be included in DiscordInteraction.message (for components on a poll message, if supported at some point) or InteractionCallbackData.resolved.messages (for message commands etc.) instead)
| /** | ||
| * Behavior of a Poll message. | ||
| */ | ||
| public interface PollBehavior : MessageBehavior { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i don't think it's a good idea to have Poll/PollBehavior extend Message/MessageBehavior - a poll is part of a message, not a message itself; it doesn't have a message type; ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am quite sure poll message can't contain anything but the poll
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that might be true for now, but who knows about the future. conceptually a poll is part of a message.
| /** | ||
| * Requests to create a poll. | ||
| * | ||
| * @throws [RestRequestException] if something went wrong during the request. | ||
| */ | ||
| @OptIn(KordUnsafe::class) | ||
| public suspend inline fun PollParentChannelBehavior.createPoll(block: PollBuilder.() -> Unit): Poll { | ||
| contract { | ||
| callsInPlace(block, InvocationKind.EXACTLY_ONCE) | ||
| } | ||
|
|
||
| return createMessage { poll(block) } as Poll | ||
| } No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need this function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also iirc the poll function is unsafe, also this returns a poll object
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also iirc the poll function is unsafe, also this returns a poll object
see my other comment about that annotation
| * | ||
| * @see createPoll | ||
| */ | ||
| public interface PollParentChannelBehavior : MessageChannelBehavior |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are there MessageChannelBehaviors that can't have polls? or what is the reason for this interface?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
announcement channels, I think, not sure but there was one
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i can create one in an announcement channel, that can't be it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i've checked again i can create polls in all types of channels that would be a MessageChannelBehavior in kord: GUILD_TEXT, DM, GUILD_VOICE, GROUP_DM, GUILD_ANNOUNCEMENT, ANNOUNCEMENT_THREAD, PUBLIC_THREAD, PRIVATE_THREAD, GUILD_STAGE_VOICE
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gdude2002 what channel did you say it wouldn't work in
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
News channels, but it seems they've fixed it now.
| val thread: Optional<DiscordChannel> = Optional.Missing(), | ||
| val position: OptionalInt = OptionalInt.Missing | ||
| val position: OptionalInt = OptionalInt.Missing, | ||
| val poll: Optional<DiscordPoll> = Optional.Missing() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should also be added to DiscordPartialMessage to be safe
|
|
||
| override fun toRequest(): CreatablePoll = CreatablePoll( | ||
| question ?: error("Please set a question"), | ||
| answers, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| answers, | |
| answers.toList(), |
defensive copy
| public fun answer(title: String, emojiUnicode: String? = null, id: Int = answers.size) { | ||
| require(answers.size < 10) { "Cannot add more than 10 answers" } | ||
| answers.add( | ||
| DiscordPoll.Answer( | ||
| answerId = id, | ||
| pollMedia = DiscordPoll.Media( | ||
| Optional(title), | ||
| Optional(emojiUnicode?.let { DiscordPartialEmoji(name = it) }).coerceToMissing() | ||
| ) | ||
| ) | ||
| ) | ||
| } | ||
|
|
||
| /** | ||
| * Adds an answer with [title] and [emoji]. | ||
| * | ||
| * @param id the answer id | ||
| */ | ||
| public fun answer(title: String, emoji: Snowflake? = null, id: Int = answers.size) { | ||
| require(answers.size < 10) { "Cannot add more than 10 answers" } | ||
| answers.add( | ||
| DiscordPoll.Answer( | ||
| answerId = id, | ||
| pollMedia = DiscordPoll.Media( | ||
| Optional(title), | ||
| Optional(emoji?.let { DiscordPartialEmoji(id = it) }).coerceToMissing() | ||
| ) | ||
| ) | ||
| ) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is the id required to be sent? that is is the answer_id field optional on poll creation? this makes me think it might be:
Only sent as part of responses from Discord's API/Gateway.
| * | ||
| * @param id the answer id | ||
| */ | ||
| public fun answer(title: String, emojiUnicode: String? = null, id: Int = answers.size) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could emoji be used for the parameter name instead?
| "MESSAGE_POLL_VOTE_ADD" -> MessagePollVoteAdd(decode(MessagePollEventData.serializer()), sequence) | ||
| "MESSAGE_POLL_VOTE_REMOVE" -> MessagePollVoteRemove(decode(MessagePollEventData.serializer()), sequence) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i'd keep these above the deprecated events
| public data class MessagePollVoteAdd(val data: MessagePollEventData, override val sequence: Int?) : DispatchEvent() | ||
| public data class MessagePollVoteRemove(val data: MessagePollEventData, override val sequence: Int?) : DispatchEvent() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these should also be exposed in core
|
also relevant: discord/discord-api-docs#7090 |
|
Any progress? |
|
|
Actually we said that you wanted to finish this haha |
Oh, yeah I forgot about that and have been busy otherwise 😅 |
No description provided.