Skip to content

Commit a587875

Browse files
author
Sebastian
authored
Add polls (#346)
* Add polls * fix AnswerID type * remove omitempty for now * add current intent requirement * add PollCreate * fix ExpirePoll endpoint route * add intents * split poll events into DM and guild * consistent wording * add answer votes paging * make Expiry a pointer * add permission * fix Results type * add PollCreateBuilder * address review * you might wanna build the builder idk * add ClearPoll instead of accepting a pointer * Update discord/poll_create_builder.go
1 parent 1c2e34f commit a587875

21 files changed

+486
-7
lines changed

discord/emoji.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,9 @@ type EmojiUpdate struct {
6666
}
6767

6868
type PartialEmoji struct {
69-
ID *snowflake.ID `json:"id"`
70-
Name *string `json:"name"`
71-
Animated bool `json:"animated"`
69+
ID *snowflake.ID `json:"id,omitempty"`
70+
Name *string `json:"name,omitempty"`
71+
Animated bool `json:"animated,omitempty"`
7272
}
7373

7474
// Reaction returns a string used for manipulating with reactions. May be empty if the Name is nil

discord/message.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ type Message struct {
115115
RoleSubscriptionData *RoleSubscriptionData `json:"role_subscription_data,omitempty"`
116116
InteractionMetadata *InteractionMetadata `json:"interaction_metadata,omitempty"`
117117
Resolved *ResolvedData `json:"resolved,omitempty"`
118+
Poll *Poll `json:"poll,omitempty"`
118119
}
119120

120121
func (m *Message) UnmarshalJSON(data []byte) error {

discord/message_create.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ type MessageCreate struct {
1818
MessageReference *MessageReference `json:"message_reference,omitempty"`
1919
Flags MessageFlags `json:"flags,omitempty"`
2020
EnforceNonce bool `json:"enforce_nonce,omitempty"`
21+
Poll *PollCreate `json:"poll,omitempty"`
2122
}
2223

2324
func (MessageCreate) interactionCallbackData() {}

discord/message_create_builder.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,18 @@ func (b *MessageCreateBuilder) SetSuppressEmbeds(suppressEmbeds bool) *MessageCr
251251
return b
252252
}
253253

254+
// SetPoll sets the Poll of the Message
255+
func (b *MessageCreateBuilder) SetPoll(poll PollCreate) *MessageCreateBuilder {
256+
b.Poll = &poll
257+
return b
258+
}
259+
260+
// ClearPoll clears the Poll of the Message
261+
func (b *MessageCreateBuilder) ClearPoll() *MessageCreateBuilder {
262+
b.Poll = nil
263+
return b
264+
}
265+
254266
// Build builds the MessageCreateBuilder to a MessageCreate struct
255267
func (b *MessageCreateBuilder) Build() MessageCreate {
256268
return b.MessageCreate

discord/permissions.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ const (
6363
PermissionCreateEvents
6464
PermissionUseExternalSounds
6565
PermissionSendVoiceMessages
66+
_
67+
_
68+
PermissionSendPolls
6669

6770
PermissionsAllText = PermissionViewChannel |
6871
PermissionSendMessages |
@@ -72,7 +75,8 @@ const (
7275
PermissionAttachFiles |
7376
PermissionReadMessageHistory |
7477
PermissionMentionEveryone |
75-
PermissionSendVoiceMessages
78+
PermissionSendVoiceMessages |
79+
PermissionSendPolls
7680

7781
PermissionsAllThread = PermissionManageThreads |
7882
PermissionCreatePublicThreads |
@@ -170,6 +174,7 @@ var permissions = map[Permissions]string{
170174
PermissionStream: "Video",
171175
PermissionViewGuildInsights: "View Server Insights",
172176
PermissionSendVoiceMessages: "Send Voice Messages",
177+
PermissionSendPolls: "Create Polls",
173178
}
174179

175180
func (p Permissions) String() string {

discord/poll.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package discord
2+
3+
import (
4+
"time"
5+
6+
"github.com/disgoorg/json"
7+
"github.com/disgoorg/snowflake/v2"
8+
)
9+
10+
type Poll struct {
11+
Question PollMedia `json:"question"`
12+
Answers []PollAnswer `json:"answers"`
13+
Expiry *time.Time `json:"expiry"`
14+
AllowMultiselect bool `json:"allow_multiselect"`
15+
LayoutType PollLayoutType `json:"layout_type"`
16+
Results *PollResults `json:"results"`
17+
}
18+
19+
type PollCreate struct {
20+
Question PollMedia `json:"question"`
21+
Answers []PollMedia `json:"-"`
22+
Duration int `json:"duration"`
23+
AllowMultiselect bool `json:"allow_multiselect"`
24+
LayoutType PollLayoutType `json:"layout_type,omitempty"`
25+
}
26+
27+
func (p PollCreate) MarshalJSON() ([]byte, error) {
28+
type pollCreate PollCreate
29+
30+
answers := make([]PollAnswer, 0, len(p.Answers))
31+
for _, answer := range p.Answers {
32+
answers = append(answers, PollAnswer{
33+
PollMedia: answer,
34+
})
35+
}
36+
return json.Marshal(struct {
37+
Answers []PollAnswer `json:"answers"`
38+
pollCreate
39+
}{
40+
Answers: answers,
41+
pollCreate: pollCreate(p),
42+
})
43+
}
44+
45+
type PollMedia struct {
46+
Text *string `json:"text"`
47+
Emoji *PartialEmoji `json:"emoji,omitempty"`
48+
}
49+
50+
type PollAnswer struct {
51+
AnswerID *int `json:"answer_id,omitempty"`
52+
PollMedia PollMedia `json:"poll_media"`
53+
}
54+
55+
type PollResults struct {
56+
IsFinalized bool `json:"is_finalized"`
57+
AnswerCounts []PollAnswerCount `json:"answer_counts"`
58+
}
59+
60+
type PollAnswerCount struct {
61+
ID snowflake.ID `json:"id"`
62+
Count int `json:"count"`
63+
MeVoted bool `json:"me_voted"`
64+
}
65+
66+
type PollLayoutType int
67+
68+
const (
69+
PollLayoutTypeDefault PollLayoutType = iota + 1
70+
)

discord/poll_create_builder.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package discord
2+
3+
// PollCreateBuilder helps create PollCreate structs easier
4+
type PollCreateBuilder struct {
5+
PollCreate
6+
}
7+
8+
// SetQuestion sets the question of the Poll
9+
func (b *PollCreateBuilder) SetQuestion(text string) *PollCreateBuilder {
10+
b.Question = PollMedia{
11+
Text: &text,
12+
}
13+
return b
14+
}
15+
16+
// SetPollAnswers sets the answers of the Poll
17+
func (b *PollCreateBuilder) SetPollAnswers(answers ...PollMedia) *PollCreateBuilder {
18+
b.Answers = answers
19+
return b
20+
}
21+
22+
// AddPollAnswer adds an answer to the Poll
23+
func (b *PollCreateBuilder) AddPollAnswer(text string, emoji *PartialEmoji) *PollCreateBuilder {
24+
b.Answers = append(b.Answers, PollMedia{
25+
Text: &text,
26+
Emoji: emoji,
27+
})
28+
return b
29+
}
30+
31+
// RemoveAnswer removes an answer from the Poll
32+
func (b *PollCreateBuilder) RemoveAnswer(i int) *PollCreateBuilder {
33+
if len(b.Answers) > i {
34+
b.Answers = append(b.Answers[:i], b.Answers[i+1:]...)
35+
}
36+
return b
37+
}
38+
39+
// ClearAnswers removes all answers of the Poll
40+
func (b *PollCreateBuilder) ClearAnswers() *PollCreateBuilder {
41+
b.Answers = []PollMedia{}
42+
return b
43+
}
44+
45+
// SetDuration sets the duration of the Poll (in hours)
46+
func (b *PollCreateBuilder) SetDuration(duration int) *PollCreateBuilder {
47+
b.Duration = duration
48+
return b
49+
}
50+
51+
// SetAllowMultiselect sets whether users will be able to vote for more than one answer of the Poll
52+
func (b *PollCreateBuilder) SetAllowMultiselect(multiselect bool) *PollCreateBuilder {
53+
b.AllowMultiselect = multiselect
54+
return b
55+
}
56+
57+
// SetLayoutType sets the layout of the Poll
58+
func (b *PollCreateBuilder) SetLayoutType(layout PollLayoutType) *PollCreateBuilder {
59+
b.LayoutType = layout
60+
return b
61+
}
62+
63+
// Build builds the PollCreateBuilder to a PollCreate struct
64+
func (b *PollCreateBuilder) Build() PollCreate {
65+
return b.PollCreate
66+
}

discord/webhook_message_create.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ type WebhookMessageCreate struct {
1515
Flags MessageFlags `json:"flags,omitempty"`
1616
ThreadName string `json:"thread_name,omitempty"`
1717
AppliedTags []snowflake.ID `json:"applied_tags,omitempty"`
18+
Poll *PollCreate `json:"poll,omitempty"`
1819
}
1920

2021
// ToBody returns the MessageCreate ready for body

discord/webhook_message_create_builder.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,18 @@ func (b *WebhookMessageCreateBuilder) SetThreadName(threadName string) *WebhookM
210210
return b
211211
}
212212

213+
// SetPoll sets the Poll of the webhook Message
214+
func (b *WebhookMessageCreateBuilder) SetPoll(poll PollCreate) *WebhookMessageCreateBuilder {
215+
b.Poll = &poll
216+
return b
217+
}
218+
219+
// ClearPoll clears the Poll of the webhook Message
220+
func (b *WebhookMessageCreateBuilder) ClearPoll() *WebhookMessageCreateBuilder {
221+
b.Poll = nil
222+
return b
223+
}
224+
213225
// Build builds the WebhookMessageCreateBuilder to a MessageCreate struct
214226
func (b *WebhookMessageCreateBuilder) Build() WebhookMessageCreate {
215227
b.WebhookMessageCreate.Components = b.Components

events/dm_message_poll_events.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package events
2+
3+
import (
4+
"github.com/disgoorg/snowflake/v2"
5+
)
6+
7+
// GenericDMMessagePollVote is called upon receiving DMMessagePollVoteAdd or DMMessagePollVoteRemove (requires gateway.IntentDirectMessagePolls)
8+
type GenericDMMessagePollVote struct {
9+
*GenericEvent
10+
UserID snowflake.ID
11+
ChannelID snowflake.ID
12+
MessageID snowflake.ID
13+
AnswerID int
14+
}
15+
16+
// DMMessagePollVoteAdd indicates that a discord.User voted on a discord.Poll in a DM (requires gateway.IntentDirectMessagePolls)
17+
type DMMessagePollVoteAdd struct {
18+
*GenericDMMessagePollVote
19+
}
20+
21+
// DMMessagePollVoteRemove indicates that a discord.User removed their vote on a discord.Poll in a DM (requires gateway.IntentDirectMessagePolls)
22+
type DMMessagePollVoteRemove struct {
23+
*GenericDMMessagePollVote
24+
}

0 commit comments

Comments
 (0)