From f8429046df2b5a4ed9d40d3f47a24c89941d28e9 Mon Sep 17 00:00:00 2001 From: mlnrDev Date: Thu, 21 Mar 2024 22:11:20 +0100 Subject: [PATCH 01/18] Add polls --- discord/message.go | 1 + discord/message_create.go | 1 + discord/message_create_builder.go | 6 ++++ discord/poll.go | 43 +++++++++++++++++++++++ discord/webhook_message_create.go | 1 + discord/webhook_message_create_builder.go | 6 ++++ events/listener_adapter.go | 14 ++++++++ events/message_events.go | 20 +++++++++++ gateway/gateway_event_type.go | 2 ++ gateway/gateway_events.go | 22 ++++++++++++ handlers/all_handlers.go | 3 ++ handlers/message_poll_handler.go | 33 +++++++++++++++++ rest/channels.go | 20 +++++++++++ rest/rest_endpoints.go | 3 ++ 14 files changed, 175 insertions(+) create mode 100644 discord/poll.go create mode 100644 handlers/message_poll_handler.go diff --git a/discord/message.go b/discord/message.go index e7a0ff7c8..9dd021751 100644 --- a/discord/message.go +++ b/discord/message.go @@ -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 { diff --git a/discord/message_create.go b/discord/message_create.go index 8e192cb7a..9c8f8d056 100644 --- a/discord/message_create.go +++ b/discord/message_create.go @@ -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 Poll `json:"poll,omitempty"` } func (MessageCreate) interactionCallbackData() {} diff --git a/discord/message_create_builder.go b/discord/message_create_builder.go index bba78c692..d53facaf2 100644 --- a/discord/message_create_builder.go +++ b/discord/message_create_builder.go @@ -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 Poll) *MessageCreateBuilder { + b.Poll = poll + return b +} + // Build builds the MessageCreateBuilder to a MessageCreate struct func (b *MessageCreateBuilder) Build() MessageCreate { return b.MessageCreate diff --git a/discord/poll.go b/discord/poll.go new file mode 100644 index 000000000..0126ed1fe --- /dev/null +++ b/discord/poll.go @@ -0,0 +1,43 @@ +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"` +} + +type PollMedia struct { + Text *string `json:"text"` + Emoji *PartialEmoji `json:"emoji"` +} + +type PollAnswer struct { + AnswerID *snowflake.ID `json:"answer_id"` + 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 +) diff --git a/discord/webhook_message_create.go b/discord/webhook_message_create.go index 05b2d8165..468297dfb 100644 --- a/discord/webhook_message_create.go +++ b/discord/webhook_message_create.go @@ -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 Poll `json:"poll,omitempty"` } // ToBody returns the MessageCreate ready for body diff --git a/discord/webhook_message_create_builder.go b/discord/webhook_message_create_builder.go index e82bbb958..82d31ee8a 100644 --- a/discord/webhook_message_create_builder.go +++ b/discord/webhook_message_create_builder.go @@ -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 Poll) *WebhookMessageCreateBuilder { + b.Poll = poll + return b +} + // Build builds the WebhookMessageCreateBuilder to a MessageCreate struct func (b *WebhookMessageCreateBuilder) Build() WebhookMessageCreate { b.WebhookMessageCreate.Components = b.Components diff --git a/events/listener_adapter.go b/events/listener_adapter.go index 9f38bc815..7ec9498b2 100644 --- a/events/listener_adapter.go +++ b/events/listener_adapter.go @@ -147,6 +147,10 @@ type ListenerAdapter struct { OnMessageUpdate func(event *MessageUpdate) OnMessageDelete func(event *MessageDelete) + // Message Poll Events + OnMessagePollVoteAdd func(event *MessagePollVoteAdd) + OnMessagePollVoteRemove func(event *MessagePollVoteRemove) + // Message Reaction Events OnMessageReactionAdd func(event *MessageReactionAdd) OnMessageReactionRemove func(event *MessageReactionRemove) @@ -574,6 +578,16 @@ 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) + } + // Message Reaction Events case *MessageReactionAdd: if listener := l.OnMessageReactionAdd; listener != nil { diff --git a/events/message_events.go b/events/message_events.go index c021dd6b9..df71cd973 100644 --- a/events/message_events.go +++ b/events/message_events.go @@ -43,3 +43,23 @@ type MessageUpdate struct { type MessageDelete struct { *GenericMessage } + +// GenericMessagePoll is a generic poll event +type GenericMessagePoll struct { + *GenericEvent + UserID snowflake.ID + ChannelID snowflake.ID + MessageID snowflake.ID + GuildID *snowflake.ID + AnswerID snowflake.ID +} + +// MessagePollVoteAdd indicates that a discord.User voted on a discord.Poll +type MessagePollVoteAdd struct { + *GenericMessagePoll +} + +// MessagePollVoteRemove indicates that a discord.User removed their vote on a discord.Poll +type MessagePollVoteRemove struct { + *GenericMessagePoll +} diff --git a/gateway/gateway_event_type.go b/gateway/gateway_event_type.go index 0cb54fd01..1b4e28b40 100644 --- a/gateway/gateway_event_type.go +++ b/gateway/gateway_event_type.go @@ -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" diff --git a/gateway/gateway_events.go b/gateway/gateway_events.go index a2f717d58..b4a691f2c 100644 --- a/gateway/gateway_events.go +++ b/gateway/gateway_events.go @@ -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 snowflake.ID `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 snowflake.ID `json:"answer_id"` +} + +func (EventMessagePollVoteRemove) messageData() {} +func (EventMessagePollVoteRemove) eventData() {} + type EventPresenceUpdate struct { discord.Presence } diff --git a/handlers/all_handlers.go b/handlers/all_handlers.go index 51a6466a1..81ea0234f 100644 --- a/handlers/all_handlers.go +++ b/handlers/all_handlers.go @@ -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), diff --git a/handlers/message_poll_handler.go b/handlers/message_poll_handler.go new file mode 100644 index 000000000..f65358027 --- /dev/null +++ b/handlers/message_poll_handler.go @@ -0,0 +1,33 @@ +package handlers + +import ( + "github.com/disgoorg/disgo/bot" + "github.com/disgoorg/disgo/events" + "github.com/disgoorg/disgo/gateway" +) + +func gatewayHandlerMessagePollVoteAdd(client bot.Client, sequenceNumber int, shardID int, event gateway.EventMessagePollVoteAdd) { + client.EventManager().DispatchEvent(&events.MessagePollVoteAdd{ + GenericMessagePoll: &events.GenericMessagePoll{ + GenericEvent: events.NewGenericEvent(client, sequenceNumber, shardID), + UserID: event.UserID, + ChannelID: event.ChannelID, + MessageID: event.MessageID, + GuildID: event.GuildID, + AnswerID: event.AnswerID, + }, + }) +} + +func gatewayHandlerMessagePollVoteRemove(client bot.Client, sequenceNumber int, shardID int, event gateway.EventMessagePollVoteRemove) { + client.EventManager().DispatchEvent(&events.MessagePollVoteRemove{ + GenericMessagePoll: &events.GenericMessagePoll{ + GenericEvent: events.NewGenericEvent(client, sequenceNumber, shardID), + UserID: event.UserID, + ChannelID: event.ChannelID, + MessageID: event.MessageID, + GuildID: event.GuildID, + AnswerID: event.AnswerID, + }, + }) +} diff --git a/rest/channels.go b/rest/channels.go index 3afd45565..c123984f8 100644 --- a/rest/channels.go +++ b/rest/channels.go @@ -47,6 +47,9 @@ type Channels interface { PinMessage(channelID snowflake.ID, messageID snowflake.ID, opts ...RequestOpt) error UnpinMessage(channelID snowflake.ID, messageID snowflake.ID, opts ...RequestOpt) error Follow(channelID snowflake.ID, targetChannelID snowflake.ID, opts ...RequestOpt) (*discord.FollowedChannel, error) + + GetPollAnswerVotes(channelID snowflake.ID, messageID snowflake.ID, answerID snowflake.ID, after snowflake.ID, limit int, opts ...RequestOpt) ([]discord.User, error) + ExpirePoll(channelID snowflake.ID, messageID snowflake.ID, opts ...RequestOpt) (*discord.Message, error) } type channelImpl struct { @@ -222,3 +225,20 @@ func (s *channelImpl) Follow(channelID snowflake.ID, targetChannelID snowflake.I err = s.client.Do(FollowChannel.Compile(nil, channelID), discord.FollowChannel{ChannelID: targetChannelID}, &followedChannel, opts...) return } + +func (s *channelImpl) GetPollAnswerVotes(channelID snowflake.ID, messageID snowflake.ID, answerID snowflake.ID, after snowflake.ID, limit int, opts ...RequestOpt) (users []discord.User, err error) { + values := discord.QueryValues{} + if after != 0 { + values["after"] = after + } + if limit != 0 { + values["limit"] = limit + } + err = s.client.Do(GetPollAnswerVotes.Compile(values, channelID, messageID, answerID), nil, &users, opts...) + return +} + +func (s *channelImpl) ExpirePoll(channelID snowflake.ID, messageID snowflake.ID, opts ...RequestOpt) (message *discord.Message, err error) { + err = s.client.Do(ExpirePoll.Compile(nil, channelID, messageID), nil, &message, opts...) + return +} diff --git a/rest/rest_endpoints.go b/rest/rest_endpoints.go index fb1d689a2..e8e640dd9 100644 --- a/rest/rest_endpoints.go +++ b/rest/rest_endpoints.go @@ -170,6 +170,9 @@ var ( SendTyping = NewEndpoint(http.MethodPost, "/channels/{channel.id}/typing") FollowChannel = NewEndpoint(http.MethodPost, "/channels/{channel.id}/followers") + + GetPollAnswerVotes = NewEndpoint(http.MethodGet, "/channels/{channel.id}/polls/{message.id}/answers/{answer.id}") + ExpirePoll = NewEndpoint(http.MethodPost, "/channels/{channel.id}/poll/{message.id}/expire") ) // Threads From 05382f14f4a252aa5a618c85ac084458e2d29cdb Mon Sep 17 00:00:00 2001 From: mlnrDev Date: Thu, 21 Mar 2024 22:25:12 +0100 Subject: [PATCH 02/18] fix AnswerID type --- discord/poll.go | 6 +++--- events/message_events.go | 2 +- gateway/gateway_events.go | 4 ++-- rest/channels.go | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/discord/poll.go b/discord/poll.go index 0126ed1fe..5647dda0e 100644 --- a/discord/poll.go +++ b/discord/poll.go @@ -12,7 +12,7 @@ type Poll struct { Expiry time.Time `json:"expiry"` AllowMultiselect bool `json:"allow_multiselect"` LayoutType PollLayoutType `json:"layout_type"` - Results []PollResults `json:"results"` + Results []PollResults `json:"results,omitempty"` } type PollMedia struct { @@ -21,8 +21,8 @@ type PollMedia struct { } type PollAnswer struct { - AnswerID *snowflake.ID `json:"answer_id"` - PollMedia PollMedia `json:"poll_media"` + AnswerID *int `json:"answer_id"` + PollMedia PollMedia `json:"poll_media"` } type PollResults struct { diff --git a/events/message_events.go b/events/message_events.go index df71cd973..489cc3376 100644 --- a/events/message_events.go +++ b/events/message_events.go @@ -51,7 +51,7 @@ type GenericMessagePoll struct { ChannelID snowflake.ID MessageID snowflake.ID GuildID *snowflake.ID - AnswerID snowflake.ID + AnswerID int } // MessagePollVoteAdd indicates that a discord.User voted on a discord.Poll diff --git a/gateway/gateway_events.go b/gateway/gateway_events.go index b4a691f2c..bfdf410d4 100644 --- a/gateway/gateway_events.go +++ b/gateway/gateway_events.go @@ -512,7 +512,7 @@ type EventMessagePollVoteAdd struct { ChannelID snowflake.ID `json:"channel_id"` MessageID snowflake.ID `json:"message_id"` GuildID *snowflake.ID `json:"guild_id"` - AnswerID snowflake.ID `json:"answer_id"` + AnswerID int `json:"answer_id"` } func (EventMessagePollVoteAdd) messageData() {} @@ -523,7 +523,7 @@ type EventMessagePollVoteRemove struct { ChannelID snowflake.ID `json:"channel_id"` MessageID snowflake.ID `json:"message_id"` GuildID *snowflake.ID `json:"guild_id"` - AnswerID snowflake.ID `json:"answer_id"` + AnswerID int `json:"answer_id"` } func (EventMessagePollVoteRemove) messageData() {} diff --git a/rest/channels.go b/rest/channels.go index c123984f8..d93758ab5 100644 --- a/rest/channels.go +++ b/rest/channels.go @@ -48,7 +48,7 @@ type Channels interface { UnpinMessage(channelID snowflake.ID, messageID snowflake.ID, opts ...RequestOpt) error Follow(channelID snowflake.ID, targetChannelID snowflake.ID, opts ...RequestOpt) (*discord.FollowedChannel, error) - GetPollAnswerVotes(channelID snowflake.ID, messageID snowflake.ID, answerID snowflake.ID, after snowflake.ID, limit int, opts ...RequestOpt) ([]discord.User, error) + GetPollAnswerVotes(channelID snowflake.ID, messageID snowflake.ID, answerID int, after snowflake.ID, limit int, opts ...RequestOpt) ([]discord.User, error) ExpirePoll(channelID snowflake.ID, messageID snowflake.ID, opts ...RequestOpt) (*discord.Message, error) } @@ -226,7 +226,7 @@ func (s *channelImpl) Follow(channelID snowflake.ID, targetChannelID snowflake.I return } -func (s *channelImpl) GetPollAnswerVotes(channelID snowflake.ID, messageID snowflake.ID, answerID snowflake.ID, after snowflake.ID, limit int, opts ...RequestOpt) (users []discord.User, err error) { +func (s *channelImpl) GetPollAnswerVotes(channelID snowflake.ID, messageID snowflake.ID, answerID int, after snowflake.ID, limit int, opts ...RequestOpt) (users []discord.User, err error) { values := discord.QueryValues{} if after != 0 { values["after"] = after From 43f612643b07cf81ac5bf5169404ef4512207cab Mon Sep 17 00:00:00 2001 From: mlnrDev Date: Thu, 21 Mar 2024 22:25:58 +0100 Subject: [PATCH 03/18] remove omitempty for now --- discord/poll.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/discord/poll.go b/discord/poll.go index 5647dda0e..8d0c77932 100644 --- a/discord/poll.go +++ b/discord/poll.go @@ -12,7 +12,7 @@ type Poll struct { Expiry time.Time `json:"expiry"` AllowMultiselect bool `json:"allow_multiselect"` LayoutType PollLayoutType `json:"layout_type"` - Results []PollResults `json:"results,omitempty"` + Results []PollResults `json:"results"` } type PollMedia struct { From a04c409a93927c84680e070b8f9e4fb542df96ec Mon Sep 17 00:00:00 2001 From: mlnrDev Date: Thu, 21 Mar 2024 22:37:19 +0100 Subject: [PATCH 04/18] add current intent requirement --- events/message_events.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/events/message_events.go b/events/message_events.go index 489cc3376..00db0927c 100644 --- a/events/message_events.go +++ b/events/message_events.go @@ -44,7 +44,7 @@ type MessageDelete struct { *GenericMessage } -// GenericMessagePoll is a generic poll event +// GenericMessagePoll is a generic poll event (requires gateway.IntentGuildMessageReactions or gateway.IntentDirectMessageReactions) type GenericMessagePoll struct { *GenericEvent UserID snowflake.ID @@ -54,12 +54,12 @@ type GenericMessagePoll struct { AnswerID int } -// MessagePollVoteAdd indicates that a discord.User voted on a discord.Poll +// MessagePollVoteAdd indicates that a discord.User voted on a discord.Poll (requires gateway.IntentGuildMessageReactions or gateway.IntentDirectMessageReactions) type MessagePollVoteAdd struct { *GenericMessagePoll } -// MessagePollVoteRemove indicates that a discord.User removed their vote on a discord.Poll +// MessagePollVoteRemove indicates that a discord.User removed their vote on a discord.Poll (requires gateway.IntentGuildMessageReactions or gateway.IntentDirectMessageReactions) type MessagePollVoteRemove struct { *GenericMessagePoll } From e2d7f3a10776212bb1f054b65dc8c941ef7e4092 Mon Sep 17 00:00:00 2001 From: mlnrDev Date: Fri, 22 Mar 2024 22:32:09 +0100 Subject: [PATCH 05/18] add PollCreate --- discord/emoji.go | 6 +++--- discord/message_create.go | 2 +- discord/message_create_builder.go | 2 +- discord/poll.go | 12 ++++++++++-- discord/webhook_message_create.go | 2 +- discord/webhook_message_create_builder.go | 2 +- 6 files changed, 17 insertions(+), 9 deletions(-) diff --git a/discord/emoji.go b/discord/emoji.go index 94d7fcefd..896efd112 100644 --- a/discord/emoji.go +++ b/discord/emoji.go @@ -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 diff --git a/discord/message_create.go b/discord/message_create.go index 9c8f8d056..0527ca150 100644 --- a/discord/message_create.go +++ b/discord/message_create.go @@ -18,7 +18,7 @@ type MessageCreate struct { MessageReference *MessageReference `json:"message_reference,omitempty"` Flags MessageFlags `json:"flags,omitempty"` EnforceNonce bool `json:"enforce_nonce,omitempty"` - Poll Poll `json:"poll,omitempty"` + Poll PollCreate `json:"poll,omitempty"` } func (MessageCreate) interactionCallbackData() {} diff --git a/discord/message_create_builder.go b/discord/message_create_builder.go index d53facaf2..ed570fe9a 100644 --- a/discord/message_create_builder.go +++ b/discord/message_create_builder.go @@ -252,7 +252,7 @@ func (b *MessageCreateBuilder) SetSuppressEmbeds(suppressEmbeds bool) *MessageCr } // SetPoll sets the Poll of the Message -func (b *MessageCreateBuilder) SetPoll(poll Poll) *MessageCreateBuilder { +func (b *MessageCreateBuilder) SetPoll(poll PollCreate) *MessageCreateBuilder { b.Poll = poll return b } diff --git a/discord/poll.go b/discord/poll.go index 8d0c77932..5319d4157 100644 --- a/discord/poll.go +++ b/discord/poll.go @@ -15,13 +15,21 @@ type Poll struct { Results []PollResults `json:"results"` } +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"` + Emoji *PartialEmoji `json:"emoji,omitempty"` } type PollAnswer struct { - AnswerID *int `json:"answer_id"` + AnswerID *int `json:"answer_id,omitempty"` PollMedia PollMedia `json:"poll_media"` } diff --git a/discord/webhook_message_create.go b/discord/webhook_message_create.go index 468297dfb..40ded2c8e 100644 --- a/discord/webhook_message_create.go +++ b/discord/webhook_message_create.go @@ -15,7 +15,7 @@ type WebhookMessageCreate struct { Flags MessageFlags `json:"flags,omitempty"` ThreadName string `json:"thread_name,omitempty"` AppliedTags []snowflake.ID `json:"applied_tags,omitempty"` - Poll Poll `json:"poll,omitempty"` + Poll PollCreate `json:"poll,omitempty"` } // ToBody returns the MessageCreate ready for body diff --git a/discord/webhook_message_create_builder.go b/discord/webhook_message_create_builder.go index 82d31ee8a..0a93a49e0 100644 --- a/discord/webhook_message_create_builder.go +++ b/discord/webhook_message_create_builder.go @@ -211,7 +211,7 @@ func (b *WebhookMessageCreateBuilder) SetThreadName(threadName string) *WebhookM } // SetPoll sets the Poll of the webhook Message -func (b *WebhookMessageCreateBuilder) SetPoll(poll Poll) *WebhookMessageCreateBuilder { +func (b *WebhookMessageCreateBuilder) SetPoll(poll PollCreate) *WebhookMessageCreateBuilder { b.Poll = poll return b } From d2d286be8311ebaf2e7dbdf83fb80639368848c3 Mon Sep 17 00:00:00 2001 From: mlnrDev Date: Wed, 10 Apr 2024 19:22:44 +0200 Subject: [PATCH 06/18] fix ExpirePoll endpoint route --- rest/rest_endpoints.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest/rest_endpoints.go b/rest/rest_endpoints.go index e8e640dd9..86e90538a 100644 --- a/rest/rest_endpoints.go +++ b/rest/rest_endpoints.go @@ -172,7 +172,7 @@ var ( FollowChannel = NewEndpoint(http.MethodPost, "/channels/{channel.id}/followers") GetPollAnswerVotes = NewEndpoint(http.MethodGet, "/channels/{channel.id}/polls/{message.id}/answers/{answer.id}") - ExpirePoll = NewEndpoint(http.MethodPost, "/channels/{channel.id}/poll/{message.id}/expire") + ExpirePoll = NewEndpoint(http.MethodPost, "/channels/{channel.id}/polls/{message.id}/expire") ) // Threads From 8a73887d20e9ab554e392ece8d9a00118152a379 Mon Sep 17 00:00:00 2001 From: mlnrDev Date: Sat, 13 Apr 2024 12:37:00 +0200 Subject: [PATCH 07/18] add intents --- gateway/gateway_intents.go | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/gateway/gateway_intents.go b/gateway/gateway_intents.go index f9033c80e..121cf0e4c 100644 --- a/gateway/gateway_intents.go +++ b/gateway/gateway_intents.go @@ -29,6 +29,10 @@ const ( _ IntentAutoModerationConfiguration IntentAutoModerationExecution + _ + _ + IntentGuildMessagePolls + IntentDirectMessagePolls IntentsGuild = IntentGuilds | IntentGuildMembers | @@ -42,11 +46,13 @@ const ( IntentGuildMessages | IntentGuildMessageReactions | IntentGuildMessageTyping | - IntentGuildScheduledEvents + IntentGuildScheduledEvents | + IntentGuildMessagePolls IntentsDirectMessage = IntentDirectMessages | IntentDirectMessageReactions | - IntentDirectMessageTyping + IntentDirectMessageTyping | + IntentDirectMessagePolls IntentsNonPrivileged = IntentGuilds | IntentGuildModeration | @@ -63,7 +69,9 @@ const ( IntentDirectMessageTyping | IntentGuildScheduledEvents | IntentAutoModerationConfiguration | - IntentAutoModerationExecution + IntentAutoModerationExecution | + IntentGuildMessagePolls | + IntentDirectMessagePolls IntentsPrivileged = IntentGuildMembers | IntentGuildPresences | IntentMessageContent From e25946c3f5af81b19c00c2d899495fdc34974a62 Mon Sep 17 00:00:00 2001 From: mlnrDev Date: Sat, 13 Apr 2024 13:47:36 +0200 Subject: [PATCH 08/18] split poll events into DM and guild --- events/dm_message_poll_events.go | 24 ++++++++++++ events/guild_message_poll_events.go | 31 +++++++++++++++ events/listener_adapter.go | 24 ++++++++++++ events/message_events.go | 20 ---------- events/message_poll_events.go | 34 +++++++++++++++++ handlers/message_poll_handler.go | 58 +++++++++++++++++++++++++++-- 6 files changed, 167 insertions(+), 24 deletions(-) create mode 100644 events/dm_message_poll_events.go create mode 100644 events/guild_message_poll_events.go create mode 100644 events/message_poll_events.go diff --git a/events/dm_message_poll_events.go b/events/dm_message_poll_events.go new file mode 100644 index 000000000..49d5f5971 --- /dev/null +++ b/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 the 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 +} diff --git a/events/guild_message_poll_events.go b/events/guild_message_poll_events.go new file mode 100644 index 000000000..b50c8a235 --- /dev/null +++ b/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 the gateway.IntentGuildMessagePolls) +type GenericGuildMessagePollVote struct { + *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 +} diff --git a/events/listener_adapter.go b/events/listener_adapter.go index 7ec9498b2..62e30c213 100644 --- a/events/listener_adapter.go +++ b/events/listener_adapter.go @@ -151,6 +151,14 @@ type ListenerAdapter struct { 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) @@ -587,6 +595,22 @@ func (l *ListenerAdapter) OnEvent(event bot.Event) { 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: diff --git a/events/message_events.go b/events/message_events.go index 00db0927c..c021dd6b9 100644 --- a/events/message_events.go +++ b/events/message_events.go @@ -43,23 +43,3 @@ type MessageUpdate struct { type MessageDelete struct { *GenericMessage } - -// GenericMessagePoll is a generic poll event (requires gateway.IntentGuildMessageReactions or gateway.IntentDirectMessageReactions) -type GenericMessagePoll struct { - *GenericEvent - UserID snowflake.ID - ChannelID snowflake.ID - MessageID snowflake.ID - GuildID *snowflake.ID - AnswerID int -} - -// MessagePollVoteAdd indicates that a discord.User voted on a discord.Poll (requires gateway.IntentGuildMessageReactions or gateway.IntentDirectMessageReactions) -type MessagePollVoteAdd struct { - *GenericMessagePoll -} - -// MessagePollVoteRemove indicates that a discord.User removed their vote on a discord.Poll (requires gateway.IntentGuildMessageReactions or gateway.IntentDirectMessageReactions) -type MessagePollVoteRemove struct { - *GenericMessagePoll -} diff --git a/events/message_poll_events.go b/events/message_poll_events.go new file mode 100644 index 000000000..d2f840a4c --- /dev/null +++ b/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) +type GenericMessagePollVote struct { + *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 +} diff --git a/handlers/message_poll_handler.go b/handlers/message_poll_handler.go index f65358027..affdecc0a 100644 --- a/handlers/message_poll_handler.go +++ b/handlers/message_poll_handler.go @@ -7,9 +7,11 @@ import ( ) func gatewayHandlerMessagePollVoteAdd(client bot.Client, sequenceNumber int, shardID int, event gateway.EventMessagePollVoteAdd) { + genericEvent := events.NewGenericEvent(client, sequenceNumber, shardID) + client.EventManager().DispatchEvent(&events.MessagePollVoteAdd{ - GenericMessagePoll: &events.GenericMessagePoll{ - GenericEvent: events.NewGenericEvent(client, sequenceNumber, shardID), + GenericMessagePollVote: &events.GenericMessagePollVote{ + GenericEvent: genericEvent, UserID: event.UserID, ChannelID: event.ChannelID, MessageID: event.MessageID, @@ -17,12 +19,37 @@ func gatewayHandlerMessagePollVoteAdd(client bot.Client, sequenceNumber int, sha AnswerID: event.AnswerID, }, }) + + if event.GuildID == nil { + client.EventManager().DispatchEvent(&events.DMMessagePollVoteAdd{ + GenericDMMessagePollVote: &events.GenericDMMessagePollVote{ + GenericEvent: genericEvent, + UserID: event.UserID, + ChannelID: event.ChannelID, + MessageID: event.MessageID, + AnswerID: event.AnswerID, + }, + }) + } else { + client.EventManager().DispatchEvent(&events.GuildMessagePollVoteAdd{ + GenericGuildMessagePollVote: &events.GenericGuildMessagePollVote{ + GenericEvent: genericEvent, + UserID: event.UserID, + ChannelID: event.ChannelID, + MessageID: event.MessageID, + GuildID: *event.GuildID, + AnswerID: event.AnswerID, + }, + }) + } } func gatewayHandlerMessagePollVoteRemove(client bot.Client, sequenceNumber int, shardID int, event gateway.EventMessagePollVoteRemove) { + genericEvent := events.NewGenericEvent(client, sequenceNumber, shardID) + client.EventManager().DispatchEvent(&events.MessagePollVoteRemove{ - GenericMessagePoll: &events.GenericMessagePoll{ - GenericEvent: events.NewGenericEvent(client, sequenceNumber, shardID), + GenericMessagePollVote: &events.GenericMessagePollVote{ + GenericEvent: genericEvent, UserID: event.UserID, ChannelID: event.ChannelID, MessageID: event.MessageID, @@ -30,4 +57,27 @@ func gatewayHandlerMessagePollVoteRemove(client bot.Client, sequenceNumber int, AnswerID: event.AnswerID, }, }) + + if event.GuildID == nil { + client.EventManager().DispatchEvent(&events.DMMessagePollVoteRemove{ + GenericDMMessagePollVote: &events.GenericDMMessagePollVote{ + GenericEvent: genericEvent, + UserID: event.UserID, + ChannelID: event.ChannelID, + MessageID: event.MessageID, + AnswerID: event.AnswerID, + }, + }) + } else { + client.EventManager().DispatchEvent(&events.GuildMessagePollVoteRemove{ + GenericGuildMessagePollVote: &events.GenericGuildMessagePollVote{ + GenericEvent: genericEvent, + UserID: event.UserID, + ChannelID: event.ChannelID, + MessageID: event.MessageID, + GuildID: *event.GuildID, + AnswerID: event.AnswerID, + }, + }) + } } From 34798480219af81c0939e0a1c00ee9e7d047c6fa Mon Sep 17 00:00:00 2001 From: mlnrDev Date: Sat, 13 Apr 2024 13:51:39 +0200 Subject: [PATCH 09/18] consistent wording --- events/dm_message_poll_events.go | 2 +- events/guild_message_poll_events.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/events/dm_message_poll_events.go b/events/dm_message_poll_events.go index 49d5f5971..a80db4a6a 100644 --- a/events/dm_message_poll_events.go +++ b/events/dm_message_poll_events.go @@ -4,7 +4,7 @@ import ( "github.com/disgoorg/snowflake/v2" ) -// GenericDMMessagePollVote is called upon receiving DMMessagePollVoteAdd or DMMessagePollVoteRemove (requires the gateway.IntentDirectMessagePolls) +// GenericDMMessagePollVote is called upon receiving DMMessagePollVoteAdd or DMMessagePollVoteRemove (requires gateway.IntentDirectMessagePolls) type GenericDMMessagePollVote struct { *GenericEvent UserID snowflake.ID diff --git a/events/guild_message_poll_events.go b/events/guild_message_poll_events.go index b50c8a235..591a6981a 100644 --- a/events/guild_message_poll_events.go +++ b/events/guild_message_poll_events.go @@ -5,7 +5,7 @@ import ( "github.com/disgoorg/snowflake/v2" ) -// GenericGuildMessagePollVote is called upon receiving GuildMessagePollVoteAdd or GuildMessagePollVoteRemove (requires the gateway.IntentGuildMessagePolls) +// GenericGuildMessagePollVote is called upon receiving GuildMessagePollVoteAdd or GuildMessagePollVoteRemove (requires gateway.IntentGuildMessagePolls) type GenericGuildMessagePollVote struct { *GenericEvent UserID snowflake.ID From c7e441c80e6aa89221290d9ee520e83161390b81 Mon Sep 17 00:00:00 2001 From: mlnrDev Date: Mon, 15 Apr 2024 23:56:05 +0200 Subject: [PATCH 10/18] add answer votes paging --- rest/channels.go | 10 ++++++++++ rest/page.go | 25 +++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/rest/channels.go b/rest/channels.go index d93758ab5..c189adf63 100644 --- a/rest/channels.go +++ b/rest/channels.go @@ -49,6 +49,7 @@ type Channels interface { Follow(channelID snowflake.ID, targetChannelID snowflake.ID, opts ...RequestOpt) (*discord.FollowedChannel, error) GetPollAnswerVotes(channelID snowflake.ID, messageID snowflake.ID, answerID int, after snowflake.ID, limit int, opts ...RequestOpt) ([]discord.User, error) + GetPollAnswerVotesPage(channelID snowflake.ID, messageID snowflake.ID, answerID int, startID snowflake.ID, limit int, opts ...RequestOpt) PollAnswerVotesPage ExpirePoll(channelID snowflake.ID, messageID snowflake.ID, opts ...RequestOpt) (*discord.Message, error) } @@ -238,6 +239,15 @@ func (s *channelImpl) GetPollAnswerVotes(channelID snowflake.ID, messageID snowf return } +func (s *channelImpl) GetPollAnswerVotesPage(channelID snowflake.ID, messageID snowflake.ID, answerID int, startID snowflake.ID, limit int, opts ...RequestOpt) PollAnswerVotesPage { + return PollAnswerVotesPage{ + getItems: func(after snowflake.ID) ([]discord.User, error) { + return s.GetPollAnswerVotes(channelID, messageID, answerID, after, limit, opts...) + }, + ID: startID, + } +} + func (s *channelImpl) ExpirePoll(channelID snowflake.ID, messageID snowflake.ID, opts ...RequestOpt) (message *discord.Message, err error) { err = s.client.Do(ExpirePoll.Compile(nil, channelID, messageID), nil, &message, opts...) return diff --git a/rest/page.go b/rest/page.go index a3d7b76be..6065b1793 100644 --- a/rest/page.go +++ b/rest/page.go @@ -117,3 +117,28 @@ func (p *ThreadMemberPage) Next() bool { } return p.Err == nil } + +type PollAnswerVotesPage struct { + getItems func(after snowflake.ID) ([]discord.User, error) + + Items []discord.User + Err error + + ID snowflake.ID +} + +func (p *PollAnswerVotesPage) Next() bool { + if p.Err != nil { + return false + } + + if len(p.Items) > 0 { + p.ID = p.Items[0].ID + } + + p.Items, p.Err = p.getItems(p.ID) + if p.Err == nil && len(p.Items) == 0 { + p.Err = ErrNoMorePages + } + return p.Err == nil +} From d2c169db5b7c0d2066f138e6bdedbb2babb96ca4 Mon Sep 17 00:00:00 2001 From: mlnrDev Date: Tue, 16 Apr 2024 00:08:38 +0200 Subject: [PATCH 11/18] make Expiry a pointer --- discord/poll.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/discord/poll.go b/discord/poll.go index 5319d4157..dc67a9ea6 100644 --- a/discord/poll.go +++ b/discord/poll.go @@ -9,7 +9,7 @@ import ( type Poll struct { Question PollMedia `json:"question"` Answers []PollAnswer `json:"answers"` - Expiry time.Time `json:"expiry"` + Expiry *time.Time `json:"expiry"` AllowMultiselect bool `json:"allow_multiselect"` LayoutType PollLayoutType `json:"layout_type"` Results []PollResults `json:"results"` From d771026837df15f73114cf8f86988c08088f7155 Mon Sep 17 00:00:00 2001 From: mlnrDev Date: Wed, 17 Apr 2024 23:48:00 +0200 Subject: [PATCH 12/18] add permission --- discord/permissions.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/discord/permissions.go b/discord/permissions.go index 7eaafd4fe..96c18a93d 100644 --- a/discord/permissions.go +++ b/discord/permissions.go @@ -63,6 +63,9 @@ const ( PermissionCreateEvents PermissionUseExternalSounds PermissionSendVoiceMessages + _ + _ + PermissionSendPolls PermissionsAllText = PermissionViewChannel | PermissionSendMessages | @@ -72,7 +75,8 @@ const ( PermissionAttachFiles | PermissionReadMessageHistory | PermissionMentionEveryone | - PermissionSendVoiceMessages + PermissionSendVoiceMessages | + PermissionSendPolls PermissionsAllThread = PermissionManageThreads | PermissionCreatePublicThreads | @@ -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 { From b666515d2d7b1c51089544249072245d311b5849 Mon Sep 17 00:00:00 2001 From: mlnrDev Date: Wed, 17 Apr 2024 23:55:18 +0200 Subject: [PATCH 13/18] fix Results type --- discord/poll.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/discord/poll.go b/discord/poll.go index dc67a9ea6..36695c630 100644 --- a/discord/poll.go +++ b/discord/poll.go @@ -12,7 +12,7 @@ type Poll struct { Expiry *time.Time `json:"expiry"` AllowMultiselect bool `json:"allow_multiselect"` LayoutType PollLayoutType `json:"layout_type"` - Results []PollResults `json:"results"` + Results *PollResults `json:"results"` } type PollCreate struct { From c51764ac789e160832ae823cb7cc060a10d62c93 Mon Sep 17 00:00:00 2001 From: mlnrDev Date: Mon, 22 Apr 2024 18:50:40 +0200 Subject: [PATCH 14/18] add PollCreateBuilder --- discord/poll.go | 21 +++++++++++- discord/poll_create_builder.go | 61 ++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 discord/poll_create_builder.go diff --git a/discord/poll.go b/discord/poll.go index 36695c630..03f1e019a 100644 --- a/discord/poll.go +++ b/discord/poll.go @@ -3,6 +3,7 @@ package discord import ( "time" + "github.com/disgoorg/json" "github.com/disgoorg/snowflake/v2" ) @@ -17,12 +18,30 @@ type Poll struct { type PollCreate struct { Question PollMedia `json:"question"` - Answers []PollAnswer `json:"answers"` + Answers []PollMedia `json:"-"` Duration int `json:"duration"` AllowMultiselect bool `json:"allow_multiselect"` LayoutType PollLayoutType `json:"layout_type,omitempty"` } +func (p PollCreate) MarshalJSON() ([]byte, error) { + type pollCreate PollCreate + + answers := make([]PollAnswer, 0, len(p.Answers)) + for _, answer := range p.Answers { + answers = append(answers, PollAnswer{ + PollMedia: answer, + }) + } + return json.Marshal(struct { + Answers []PollAnswer `json:"answers"` + pollCreate + }{ + Answers: answers, + pollCreate: pollCreate(p), + }) +} + type PollMedia struct { Text *string `json:"text"` Emoji *PartialEmoji `json:"emoji,omitempty"` diff --git a/discord/poll_create_builder.go b/discord/poll_create_builder.go new file mode 100644 index 000000000..c6f8ecc07 --- /dev/null +++ b/discord/poll_create_builder.go @@ -0,0 +1,61 @@ +package discord + +// PollCreateBuilder helps create PollCreate structs easier +type PollCreateBuilder struct { + PollCreate +} + +// SetQuestion sets the question of the Poll +func (b *PollCreateBuilder) SetQuestion(text string) *PollCreateBuilder { + b.Question = PollMedia{ + Text: &text, + } + return b +} + +// SetPollAnswers sets the answers of the Poll +func (b *PollCreateBuilder) SetPollAnswers(answers ...PollMedia) *PollCreateBuilder { + b.Answers = answers + return b +} + +// AddPollAnswer adds an answer to the Poll +func (b *PollCreateBuilder) AddPollAnswer(text string, emoji *PartialEmoji) *PollCreateBuilder { + b.Answers = append(b.Answers, PollMedia{ + Text: &text, + Emoji: emoji, + }) + return b +} + +// RemoveAnswer removes an answer from the Poll +func (b *PollCreateBuilder) RemoveAnswer(i int) *PollCreateBuilder { + if len(b.Answers) > i { + b.Answers = append(b.Answers[:i], b.Answers[i+1:]...) + } + return b +} + +// ClearAnswers removes all answers of the Poll +func (b *PollCreateBuilder) ClearAnswers() *PollCreateBuilder { + b.Answers = []PollMedia{} + return b +} + +// SetDuration sets the duration of the Poll (in seconds) +func (b *PollCreateBuilder) SetDuration(duration int) *PollCreateBuilder { + b.Duration = duration + return b +} + +// SetAllowMultiselect sets whether users will be able to vote for more than one answer of the Poll +func (b *PollCreateBuilder) SetAllowMultiselect(multiselect bool) *PollCreateBuilder { + b.AllowMultiselect = multiselect + return b +} + +// SetLayoutType sets the layout of the Poll +func (b *PollCreateBuilder) SetLayoutType(layout PollLayoutType) *PollCreateBuilder { + b.LayoutType = layout + return b +} From 6f85c0fc89e3e25151dc87bd191273c3545a0f25 Mon Sep 17 00:00:00 2001 From: mlnrDev Date: Mon, 22 Apr 2024 19:03:56 +0200 Subject: [PATCH 15/18] address review --- discord/message_create.go | 2 +- discord/message_create_builder.go | 2 +- discord/webhook_message_create.go | 2 +- discord/webhook_message_create_builder.go | 2 +- events/guild_message_poll_events.go | 5 +++++ events/message_poll_events.go | 8 ++++---- gateway/gateway_intents.go | 3 +++ 7 files changed, 16 insertions(+), 8 deletions(-) diff --git a/discord/message_create.go b/discord/message_create.go index 0527ca150..e21cc4cba 100644 --- a/discord/message_create.go +++ b/discord/message_create.go @@ -18,7 +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"` + Poll *PollCreate `json:"poll,omitempty"` } func (MessageCreate) interactionCallbackData() {} diff --git a/discord/message_create_builder.go b/discord/message_create_builder.go index ed570fe9a..f4e486344 100644 --- a/discord/message_create_builder.go +++ b/discord/message_create_builder.go @@ -252,7 +252,7 @@ func (b *MessageCreateBuilder) SetSuppressEmbeds(suppressEmbeds bool) *MessageCr } // SetPoll sets the Poll of the Message -func (b *MessageCreateBuilder) SetPoll(poll PollCreate) *MessageCreateBuilder { +func (b *MessageCreateBuilder) SetPoll(poll *PollCreate) *MessageCreateBuilder { b.Poll = poll return b } diff --git a/discord/webhook_message_create.go b/discord/webhook_message_create.go index 40ded2c8e..f84e4ea8d 100644 --- a/discord/webhook_message_create.go +++ b/discord/webhook_message_create.go @@ -15,7 +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"` + Poll *PollCreate `json:"poll,omitempty"` } // ToBody returns the MessageCreate ready for body diff --git a/discord/webhook_message_create_builder.go b/discord/webhook_message_create_builder.go index 0a93a49e0..30a4231e0 100644 --- a/discord/webhook_message_create_builder.go +++ b/discord/webhook_message_create_builder.go @@ -211,7 +211,7 @@ func (b *WebhookMessageCreateBuilder) SetThreadName(threadName string) *WebhookM } // SetPoll sets the Poll of the webhook Message -func (b *WebhookMessageCreateBuilder) SetPoll(poll PollCreate) *WebhookMessageCreateBuilder { +func (b *WebhookMessageCreateBuilder) SetPoll(poll *PollCreate) *WebhookMessageCreateBuilder { b.Poll = poll return b } diff --git a/events/guild_message_poll_events.go b/events/guild_message_poll_events.go index 591a6981a..9c9829ceb 100644 --- a/events/guild_message_poll_events.go +++ b/events/guild_message_poll_events.go @@ -20,6 +20,11 @@ func (e *GenericGuildMessagePollVote) Guild() (discord.Guild, bool) { return e.Client().Caches().Guild(e.GuildID) } +// Channel returns the discord.GuildMessageChannel where the GenericGuildMessagePollVote happened +func (e *GenericGuildMessagePollVote) Channel() (discord.GuildMessageChannel, bool) { + return e.Client().Caches().GuildMessageChannel(e.ChannelID) +} + // GuildMessagePollVoteAdd indicates that a discord.User voted on a discord.Poll in a discord.Guild (requires gateway.IntentGuildMessagePolls) type GuildMessagePollVoteAdd struct { *GenericGuildMessagePollVote diff --git a/events/message_poll_events.go b/events/message_poll_events.go index d2f840a4c..e6dd72757 100644 --- a/events/message_poll_events.go +++ b/events/message_poll_events.go @@ -5,7 +5,7 @@ import ( "github.com/disgoorg/snowflake/v2" ) -// GenericMessagePollVote is a generic poll vote event (requires gateway.IntentGuildMessagePolls or gateway.IntentDirectMessagePolls) +// GenericMessagePollVote is a generic poll vote event (requires gateway.IntentGuildMessagePolls and/or gateway.IntentDirectMessagePolls) type GenericMessagePollVote struct { *GenericEvent UserID snowflake.ID @@ -15,7 +15,7 @@ type GenericMessagePollVote struct { AnswerID int } -// Guild returns the discord.Guild where the GenericMessagePoll happened or empty if it happened in DMs +// Guild returns the discord.Guild where the GenericMessagePollVote happened or empty if it happened in DMs func (e *GenericMessagePollVote) Guild() (discord.Guild, bool) { if e.GuildID == nil { return discord.Guild{}, false @@ -23,12 +23,12 @@ func (e *GenericMessagePollVote) Guild() (discord.Guild, bool) { return e.Client().Caches().Guild(*e.GuildID) } -// MessagePollVoteAdd indicates that a discord.User voted on a discord.Poll (requires gateway.IntentGuildMessagePolls or gateway.IntentDirectMessagePolls) +// MessagePollVoteAdd indicates that a discord.User voted on a discord.Poll (requires gateway.IntentGuildMessagePolls and/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) +// MessagePollVoteRemove indicates that a discord.User removed their vote on a discord.Poll (requires gateway.IntentGuildMessagePolls and/or gateway.IntentDirectMessagePolls) type MessagePollVoteRemove struct { *GenericMessagePollVote } diff --git a/gateway/gateway_intents.go b/gateway/gateway_intents.go index 121cf0e4c..68f6c4ec2 100644 --- a/gateway/gateway_intents.go +++ b/gateway/gateway_intents.go @@ -54,6 +54,9 @@ const ( IntentDirectMessageTyping | IntentDirectMessagePolls + IntentsMessagePolls = IntentGuildMessagePolls | + IntentDirectMessagePolls + IntentsNonPrivileged = IntentGuilds | IntentGuildModeration | IntentGuildEmojisAndStickers | From fef1c94334549083b6e84d8f0d9dcb3e1ad3ef7c Mon Sep 17 00:00:00 2001 From: mlnrDev Date: Mon, 22 Apr 2024 19:07:55 +0200 Subject: [PATCH 16/18] you might wanna build the builder idk --- discord/poll_create_builder.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/discord/poll_create_builder.go b/discord/poll_create_builder.go index c6f8ecc07..7ef7af533 100644 --- a/discord/poll_create_builder.go +++ b/discord/poll_create_builder.go @@ -59,3 +59,8 @@ func (b *PollCreateBuilder) SetLayoutType(layout PollLayoutType) *PollCreateBuil b.LayoutType = layout return b } + +// Build builds the PollCreateBuilder to a PollCreate struct +func (b *PollCreateBuilder) Build() PollCreate { + return b.PollCreate +} From fce3f55041438c9cc474e443560cfdd1110e115a Mon Sep 17 00:00:00 2001 From: mlnrDev Date: Mon, 22 Apr 2024 19:11:24 +0200 Subject: [PATCH 17/18] add ClearPoll instead of accepting a pointer --- discord/message_create_builder.go | 10 ++++++++-- discord/webhook_message_create_builder.go | 10 ++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/discord/message_create_builder.go b/discord/message_create_builder.go index f4e486344..cf1178c17 100644 --- a/discord/message_create_builder.go +++ b/discord/message_create_builder.go @@ -252,8 +252,14 @@ func (b *MessageCreateBuilder) SetSuppressEmbeds(suppressEmbeds bool) *MessageCr } // SetPoll sets the Poll of the Message -func (b *MessageCreateBuilder) SetPoll(poll *PollCreate) *MessageCreateBuilder { - b.Poll = poll +func (b *MessageCreateBuilder) SetPoll(poll PollCreate) *MessageCreateBuilder { + b.Poll = &poll + return b +} + +// ClearPoll clears the Poll of the Message +func (b *MessageCreateBuilder) ClearPoll() *MessageCreateBuilder { + b.Poll = nil return b } diff --git a/discord/webhook_message_create_builder.go b/discord/webhook_message_create_builder.go index 30a4231e0..4c8666959 100644 --- a/discord/webhook_message_create_builder.go +++ b/discord/webhook_message_create_builder.go @@ -211,8 +211,14 @@ func (b *WebhookMessageCreateBuilder) SetThreadName(threadName string) *WebhookM } // SetPoll sets the Poll of the webhook Message -func (b *WebhookMessageCreateBuilder) SetPoll(poll *PollCreate) *WebhookMessageCreateBuilder { - b.Poll = poll +func (b *WebhookMessageCreateBuilder) SetPoll(poll PollCreate) *WebhookMessageCreateBuilder { + b.Poll = &poll + return b +} + +// ClearPoll clears the Poll of the webhook Message +func (b *WebhookMessageCreateBuilder) ClearPoll() *WebhookMessageCreateBuilder { + b.Poll = nil return b } From c812a4fe5165dd5833ba17e8d3436ef8c0538a65 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Mon, 22 Apr 2024 19:16:56 +0200 Subject: [PATCH 18/18] Update discord/poll_create_builder.go --- discord/poll_create_builder.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/discord/poll_create_builder.go b/discord/poll_create_builder.go index 7ef7af533..3b436ecbf 100644 --- a/discord/poll_create_builder.go +++ b/discord/poll_create_builder.go @@ -42,7 +42,7 @@ func (b *PollCreateBuilder) ClearAnswers() *PollCreateBuilder { return b } -// SetDuration sets the duration of the Poll (in seconds) +// SetDuration sets the duration of the Poll (in hours) func (b *PollCreateBuilder) SetDuration(duration int) *PollCreateBuilder { b.Duration = duration return b