Skip to content
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

Add polls #346

Merged
merged 18 commits into from Apr 22, 2024
6 changes: 3 additions & 3 deletions discord/emoji.go
Expand Up @@ -66,9 +66,9 @@ type EmojiUpdate struct {
}

type PartialEmoji struct {
ID *snowflake.ID `json:"id"`
Name *string `json:"name"`
Animated bool `json:"animated"`
ID *snowflake.ID `json:"id,omitempty"`
Name *string `json:"name,omitempty"`
Animated bool `json:"animated,omitempty"`
}

// Reaction returns a string used for manipulating with reactions. May be empty if the Name is nil
Expand Down
1 change: 1 addition & 0 deletions discord/message.go
Expand Up @@ -114,6 +114,7 @@ type Message struct {
Position *int `json:"position,omitempty"`
RoleSubscriptionData *RoleSubscriptionData `json:"role_subscription_data,omitempty"`
Resolved *ResolvedData `json:"resolved,omitempty"`
Poll *Poll `json:"poll,omitempty"`
}

func (m *Message) UnmarshalJSON(data []byte) error {
Expand Down
1 change: 1 addition & 0 deletions discord/message_create.go
Expand Up @@ -18,6 +18,7 @@ type MessageCreate struct {
MessageReference *MessageReference `json:"message_reference,omitempty"`
Flags MessageFlags `json:"flags,omitempty"`
EnforceNonce bool `json:"enforce_nonce,omitempty"`
Poll PollCreate `json:"poll,omitempty"`
sebm253 marked this conversation as resolved.
Show resolved Hide resolved
}

func (MessageCreate) interactionCallbackData() {}
Expand Down
6 changes: 6 additions & 0 deletions discord/message_create_builder.go
Expand Up @@ -251,6 +251,12 @@ func (b *MessageCreateBuilder) SetSuppressEmbeds(suppressEmbeds bool) *MessageCr
return b
}

// SetPoll sets the Poll of the Message
func (b *MessageCreateBuilder) SetPoll(poll PollCreate) *MessageCreateBuilder {
sebm253 marked this conversation as resolved.
Show resolved Hide resolved
b.Poll = poll
return b
}

// Build builds the MessageCreateBuilder to a MessageCreate struct
func (b *MessageCreateBuilder) Build() MessageCreate {
return b.MessageCreate
Expand Down
7 changes: 6 additions & 1 deletion discord/permissions.go
Expand Up @@ -63,6 +63,9 @@ const (
PermissionCreateEvents
PermissionUseExternalSounds
PermissionSendVoiceMessages
_
_
PermissionSendPolls

PermissionsAllText = PermissionViewChannel |
PermissionSendMessages |
Expand All @@ -72,7 +75,8 @@ const (
PermissionAttachFiles |
PermissionReadMessageHistory |
PermissionMentionEveryone |
PermissionSendVoiceMessages
PermissionSendVoiceMessages |
PermissionSendPolls

PermissionsAllThread = PermissionManageThreads |
PermissionCreatePublicThreads |
Expand Down Expand Up @@ -170,6 +174,7 @@ var permissions = map[Permissions]string{
PermissionStream: "Video",
PermissionViewGuildInsights: "View Server Insights",
PermissionSendVoiceMessages: "Send Voice Messages",
PermissionSendPolls: "Create Polls",
}

func (p Permissions) String() string {
Expand Down
51 changes: 51 additions & 0 deletions discord/poll.go
@@ -0,0 +1,51 @@
package discord

import (
"time"

"github.com/disgoorg/snowflake/v2"
)

type Poll struct {
Question PollMedia `json:"question"`
Answers []PollAnswer `json:"answers"`
Expiry *time.Time `json:"expiry"`
AllowMultiselect bool `json:"allow_multiselect"`
LayoutType PollLayoutType `json:"layout_type"`
Results []PollResults `json:"results"`
sebm253 marked this conversation as resolved.
Show resolved Hide resolved
}

type PollCreate struct {
Question PollMedia `json:"question"`
Answers []PollAnswer `json:"answers"`
Duration int `json:"duration"`
AllowMultiselect bool `json:"allow_multiselect"`
LayoutType PollLayoutType `json:"layout_type,omitempty"`
}

type PollMedia struct {
Text *string `json:"text"`
Emoji *PartialEmoji `json:"emoji,omitempty"`
}

type PollAnswer struct {
AnswerID *int `json:"answer_id,omitempty"`
PollMedia PollMedia `json:"poll_media"`
}

type PollResults struct {
IsFinalized bool `json:"is_finalized"`
AnswerCounts []PollAnswerCount `json:"answer_counts"`
}

type PollAnswerCount struct {
ID snowflake.ID `json:"id"`
Count int `json:"count"`
MeVoted bool `json:"me_voted"`
}

type PollLayoutType int

const (
PollLayoutTypeDefault PollLayoutType = iota + 1
)
1 change: 1 addition & 0 deletions discord/webhook_message_create.go
Expand Up @@ -15,6 +15,7 @@ type WebhookMessageCreate struct {
Flags MessageFlags `json:"flags,omitempty"`
ThreadName string `json:"thread_name,omitempty"`
AppliedTags []snowflake.ID `json:"applied_tags,omitempty"`
Poll PollCreate `json:"poll,omitempty"`
sebm253 marked this conversation as resolved.
Show resolved Hide resolved
}

// ToBody returns the MessageCreate ready for body
Expand Down
6 changes: 6 additions & 0 deletions discord/webhook_message_create_builder.go
Expand Up @@ -210,6 +210,12 @@ func (b *WebhookMessageCreateBuilder) SetThreadName(threadName string) *WebhookM
return b
}

// SetPoll sets the Poll of the webhook Message
func (b *WebhookMessageCreateBuilder) SetPoll(poll PollCreate) *WebhookMessageCreateBuilder {
sebm253 marked this conversation as resolved.
Show resolved Hide resolved
b.Poll = poll
return b
}

// Build builds the WebhookMessageCreateBuilder to a MessageCreate struct
func (b *WebhookMessageCreateBuilder) Build() WebhookMessageCreate {
b.WebhookMessageCreate.Components = b.Components
Expand Down
24 changes: 24 additions & 0 deletions events/dm_message_poll_events.go
@@ -0,0 +1,24 @@
package events

import (
"github.com/disgoorg/snowflake/v2"
)

// GenericDMMessagePollVote is called upon receiving DMMessagePollVoteAdd or DMMessagePollVoteRemove (requires gateway.IntentDirectMessagePolls)
type GenericDMMessagePollVote struct {
*GenericEvent
UserID snowflake.ID
ChannelID snowflake.ID
MessageID snowflake.ID
AnswerID int
}

// DMMessagePollVoteAdd indicates that a discord.User voted on a discord.Poll in a DM (requires gateway.IntentDirectMessagePolls)
type DMMessagePollVoteAdd struct {
*GenericDMMessagePollVote
}

// DMMessagePollVoteRemove indicates that a discord.User removed their vote on a discord.Poll in a DM (requires gateway.IntentDirectMessagePolls)
type DMMessagePollVoteRemove struct {
*GenericDMMessagePollVote
}
31 changes: 31 additions & 0 deletions events/guild_message_poll_events.go
@@ -0,0 +1,31 @@
package events

import (
"github.com/disgoorg/disgo/discord"
"github.com/disgoorg/snowflake/v2"
)

// GenericGuildMessagePollVote is called upon receiving GuildMessagePollVoteAdd or GuildMessagePollVoteRemove (requires gateway.IntentGuildMessagePolls)
type GenericGuildMessagePollVote struct {
topi314 marked this conversation as resolved.
Show resolved Hide resolved
*GenericEvent
UserID snowflake.ID
ChannelID snowflake.ID
MessageID snowflake.ID
GuildID snowflake.ID
AnswerID int
}

// Guild returns the discord.Guild where the GenericGuildMessagePollVote happened
func (e *GenericGuildMessagePollVote) Guild() (discord.Guild, bool) {
return e.Client().Caches().Guild(e.GuildID)
}

// GuildMessagePollVoteAdd indicates that a discord.User voted on a discord.Poll in a discord.Guild (requires gateway.IntentGuildMessagePolls)
type GuildMessagePollVoteAdd struct {
*GenericGuildMessagePollVote
}

// GuildMessagePollVoteRemove indicates that a discord.User removed their vote on a discord.Poll in a discord.Guild (requires gateway.IntentGuildMessagePolls)
type GuildMessagePollVoteRemove struct {
*GenericGuildMessagePollVote
}
38 changes: 38 additions & 0 deletions events/listener_adapter.go
Expand Up @@ -147,6 +147,18 @@ type ListenerAdapter struct {
OnMessageUpdate func(event *MessageUpdate)
OnMessageDelete func(event *MessageDelete)

// Message Poll Events
sebm253 marked this conversation as resolved.
Show resolved Hide resolved
OnMessagePollVoteAdd func(event *MessagePollVoteAdd)
OnMessagePollVoteRemove func(event *MessagePollVoteRemove)

// DM Message Poll Events
OnDMMessagePollVoteAdd func(event *DMMessagePollVoteAdd)
OnDMMessagePollVoteRemove func(event *DMMessagePollVoteRemove)

// Guild Message Poll Events
OnGuildMessagePollVoteAdd func(event *GuildMessagePollVoteAdd)
OnGuildMessagePollVoteRemove func(event *GuildMessagePollVoteRemove)

// Message Reaction Events
OnMessageReactionAdd func(event *MessageReactionAdd)
OnMessageReactionRemove func(event *MessageReactionRemove)
Expand Down Expand Up @@ -574,6 +586,32 @@ func (l *ListenerAdapter) OnEvent(event bot.Event) {
listener(e)
}

// Message Poll Events
case *MessagePollVoteAdd:
if listener := l.OnMessagePollVoteAdd; listener != nil {
listener(e)
}
case *MessagePollVoteRemove:
if listener := l.OnMessagePollVoteRemove; listener != nil {
listener(e)
}
case *DMMessagePollVoteAdd:
if listener := l.OnDMMessagePollVoteAdd; listener != nil {
listener(e)
}
case *DMMessagePollVoteRemove:
if listener := l.OnDMMessagePollVoteRemove; listener != nil {
listener(e)
}
case *GuildMessagePollVoteAdd:
if listener := l.OnGuildMessagePollVoteAdd; listener != nil {
listener(e)
}
case *GuildMessagePollVoteRemove:
if listener := l.OnGuildMessagePollVoteRemove; listener != nil {
listener(e)
}

// Message Reaction Events
case *MessageReactionAdd:
if listener := l.OnMessageReactionAdd; listener != nil {
Expand Down
34 changes: 34 additions & 0 deletions events/message_poll_events.go
@@ -0,0 +1,34 @@
package events

import (
"github.com/disgoorg/disgo/discord"
"github.com/disgoorg/snowflake/v2"
)

// GenericMessagePollVote is a generic poll vote event (requires gateway.IntentGuildMessagePolls or gateway.IntentDirectMessagePolls)
sebm253 marked this conversation as resolved.
Show resolved Hide resolved
type GenericMessagePollVote struct {
topi314 marked this conversation as resolved.
Show resolved Hide resolved
*GenericEvent
UserID snowflake.ID
ChannelID snowflake.ID
MessageID snowflake.ID
GuildID *snowflake.ID
AnswerID int
}

// Guild returns the discord.Guild where the GenericMessagePoll happened or empty if it happened in DMs
func (e *GenericMessagePollVote) Guild() (discord.Guild, bool) {
if e.GuildID == nil {
return discord.Guild{}, false
}
return e.Client().Caches().Guild(*e.GuildID)
}

// MessagePollVoteAdd indicates that a discord.User voted on a discord.Poll (requires gateway.IntentGuildMessagePolls or gateway.IntentDirectMessagePolls)
type MessagePollVoteAdd struct {
*GenericMessagePollVote
}

// MessagePollVoteRemove indicates that a discord.User removed their vote on a discord.Poll (requires gateway.IntentGuildMessagePolls or gateway.IntentDirectMessagePolls)
type MessagePollVoteRemove struct {
*GenericMessagePollVote
}
2 changes: 2 additions & 0 deletions gateway/gateway_event_type.go
Expand Up @@ -59,6 +59,8 @@ const (
EventTypeMessageUpdate EventType = "MESSAGE_UPDATE"
EventTypeMessageDelete EventType = "MESSAGE_DELETE"
EventTypeMessageDeleteBulk EventType = "MESSAGE_DELETE_BULK"
EventTypeMessagePollVoteAdd EventType = "MESSAGE_POLL_VOTE_ADD"
EventTypeMessagePollVoteRemove EventType = "MESSAGE_POLL_VOTE_REMOVE"
EventTypeMessageReactionAdd EventType = "MESSAGE_REACTION_ADD"
EventTypeMessageReactionRemove EventType = "MESSAGE_REACTION_REMOVE"
EventTypeMessageReactionRemoveAll EventType = "MESSAGE_REACTION_REMOVE_ALL"
Expand Down
22 changes: 22 additions & 0 deletions gateway/gateway_events.go
Expand Up @@ -507,6 +507,28 @@ type EventMessageDeleteBulk struct {
func (EventMessageDeleteBulk) messageData() {}
func (EventMessageDeleteBulk) eventData() {}

type EventMessagePollVoteAdd struct {
UserID snowflake.ID `json:"user_id"`
ChannelID snowflake.ID `json:"channel_id"`
MessageID snowflake.ID `json:"message_id"`
GuildID *snowflake.ID `json:"guild_id"`
AnswerID int `json:"answer_id"`
}

func (EventMessagePollVoteAdd) messageData() {}
func (EventMessagePollVoteAdd) eventData() {}

type EventMessagePollVoteRemove struct {
UserID snowflake.ID `json:"user_id"`
ChannelID snowflake.ID `json:"channel_id"`
MessageID snowflake.ID `json:"message_id"`
GuildID *snowflake.ID `json:"guild_id"`
AnswerID int `json:"answer_id"`
}

func (EventMessagePollVoteRemove) messageData() {}
func (EventMessagePollVoteRemove) eventData() {}

type EventPresenceUpdate struct {
discord.Presence
}
Expand Down
14 changes: 11 additions & 3 deletions gateway/gateway_intents.go
Expand Up @@ -29,6 +29,10 @@ const (
_
IntentAutoModerationConfiguration
IntentAutoModerationExecution
_
_
IntentGuildMessagePolls
IntentDirectMessagePolls
sebm253 marked this conversation as resolved.
Show resolved Hide resolved

IntentsGuild = IntentGuilds |
IntentGuildMembers |
Expand All @@ -42,11 +46,13 @@ const (
IntentGuildMessages |
IntentGuildMessageReactions |
IntentGuildMessageTyping |
IntentGuildScheduledEvents
IntentGuildScheduledEvents |
IntentGuildMessagePolls

IntentsDirectMessage = IntentDirectMessages |
IntentDirectMessageReactions |
IntentDirectMessageTyping
IntentDirectMessageTyping |
IntentDirectMessagePolls

IntentsNonPrivileged = IntentGuilds |
IntentGuildModeration |
Expand All @@ -63,7 +69,9 @@ const (
IntentDirectMessageTyping |
IntentGuildScheduledEvents |
IntentAutoModerationConfiguration |
IntentAutoModerationExecution
IntentAutoModerationExecution |
IntentGuildMessagePolls |
IntentDirectMessagePolls

IntentsPrivileged = IntentGuildMembers |
IntentGuildPresences | IntentMessageContent
Expand Down
3 changes: 3 additions & 0 deletions handlers/all_handlers.go
Expand Up @@ -101,6 +101,9 @@ var allEventHandlers = []bot.GatewayEventHandler{
bot.NewGatewayEventHandler(gateway.EventTypeMessageDelete, gatewayHandlerMessageDelete),
bot.NewGatewayEventHandler(gateway.EventTypeMessageDeleteBulk, gatewayHandlerMessageDeleteBulk),

bot.NewGatewayEventHandler(gateway.EventTypeMessagePollVoteAdd, gatewayHandlerMessagePollVoteAdd),
bot.NewGatewayEventHandler(gateway.EventTypeMessagePollVoteRemove, gatewayHandlerMessagePollVoteRemove),

bot.NewGatewayEventHandler(gateway.EventTypeMessageReactionAdd, gatewayHandlerMessageReactionAdd),
bot.NewGatewayEventHandler(gateway.EventTypeMessageReactionRemove, gatewayHandlerMessageReactionRemove),
bot.NewGatewayEventHandler(gateway.EventTypeMessageReactionRemoveAll, gatewayHandlerMessageReactionRemoveAll),
Expand Down