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 Soundboard #283

Merged
merged 55 commits into from
Sep 21, 2024
Merged
Show file tree
Hide file tree
Changes from 54 commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
acadcd4
Add GuildVoiceChannelEffectSend
Jun 28, 2023
1bef49c
Add Soundboard
Jun 28, 2023
1b5d51d
add event to ListenerAdapter
Jun 28, 2023
2c1c929
Merge branch 'patch/voice-effect-event' into patch/soundboard
Jun 28, 2023
5fa89c9
add soundboard sound events
Jun 28, 2023
cc81f22
rename file
Jun 28, 2023
ecd8086
rename interface
Jun 28, 2023
99920e6
add sound fetching
Jun 28, 2023
a7d8b88
add check for gateway
Jun 28, 2023
abefae7
add docs for GuildVoiceChannelEffectSend
Jun 28, 2023
21a233a
rename SoundboardAnimationType to SoundboardEffectAnimationType
Jun 28, 2023
58b233e
Merge branch 'patch/voice-effect-event' into patch/soundboard
Jun 28, 2023
c5d2a69
bruh
Jun 28, 2023
5b8f4d5
Merge branch 'patch/voice-effect-event' into patch/soundboard
Jun 28, 2023
1e324fd
change param to varargs
Jun 28, 2023
bce8b96
remove pointless else
Jun 28, 2023
d1256c5
add CDNEndpoint.Path()
Jun 28, 2023
ca70e41
Merge branch 'master' into patch/soundboard
Jun 28, 2023
e05894b
shorten impl name
Jun 30, 2023
5db0713
Merge branch 'master' into patch/soundboard
Sep 2, 2023
9197f63
add audit log events
Sep 2, 2023
8d01c39
Merge branch 'master' into patch/soundboard
May 16, 2024
540af44
updates
May 16, 2024
48ee79e
add caches
May 16, 2024
83fb472
Merge branch 'master' into patch/soundboard
May 16, 2024
c1c843d
remove SoundOverridePath
May 16, 2024
806a095
Merge branch 'patch/voice-effect-event' into patch/soundboard
May 16, 2024
e724aa6
Merge branch 'master' into patch/voice-effect-event
May 16, 2024
734ef47
Merge branch 'patch/voice-effect-event' into patch/soundboard
May 16, 2024
c3695a6
updates
Jul 27, 2024
598fe31
remove UserID from SoundboardSound
Jul 30, 2024
3902c58
Merge branch 'refs/heads/master' into patch/soundboard
sebm253 Aug 15, 2024
16682b6
updates
sebm253 Aug 15, 2024
dd6709b
Merge branch 'master' into patch/voice-effect-event
sebm253 Aug 15, 2024
4662bbf
Merge branch 'patch/voice-effect-event' into patch/soundboard
sebm253 Aug 15, 2024
2082aa8
add URL()
sebm253 Aug 15, 2024
d2253dd
add required intent + fix docs
sebm253 Aug 16, 2024
ae06f00
SoundboardEffectAnimationType -> VoiceChannelEffectAnimationType
sebm253 Aug 16, 2024
2590d62
Merge branch 'patch/voice-effect-event' into patch/soundboard
sebm253 Aug 16, 2024
7957f48
oh man
sebm253 Aug 21, 2024
5d5e919
Revert "oh man"
sebm253 Aug 23, 2024
df95c4b
change SoundID type to int64 with ,string
sebm253 Aug 23, 2024
843e2b9
add event umarshaler
sebm253 Aug 24, 2024
c981e9a
Merge branch 'patch/voice-effect-event' into patch/soundboard
sebm253 Aug 24, 2024
b8daf5c
Merge branch 'master' into patch/soundboard
sebm253 Aug 24, 2024
dbc3bb9
damn this shit is broken
sebm253 Aug 24, 2024
49d9570
add GuildFeatureMoreSoundboard
sebm253 Aug 31, 2024
e0fafc9
add missing cache getter
sebm253 Aug 31, 2024
05d0079
Merge branch 'master' into patch/soundboard
sebm253 Sep 21, 2024
88f0566
add request func to client interface
sebm253 Sep 21, 2024
1df7005
Merge branch 'master' into patch/soundboard
sebm253 Sep 21, 2024
76178b1
Merge branch 'master' into patch/soundboard
sebm253 Sep 21, 2024
d66a8d7
fix endpoint method
sebm253 Sep 21, 2024
71d6d64
Update discord/soundboard.go
sebm253 Sep 21, 2024
39a71ec
Apply suggestions from code review
sebm253 Sep 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions bot/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ type Client interface {
// limit : The number of discord.Member(s) to return.
RequestMembersWithQuery(ctx context.Context, guildID snowflake.ID, presence bool, nonce string, query string, limit int) error

// RequestSoundboardSounds a gateway.MessageDataRequestSoundboardSounds to the specific gateway.Gateway and requests the SoundboardSounds of the specified guilds.
RequestSoundboardSounds(ctx context.Context, guildIDs ...snowflake.ID) error

// SetPresence sends new presence data to the gateway.Gateway.
SetPresence(ctx context.Context, opts ...gateway.PresenceOpt) error

Expand Down Expand Up @@ -277,6 +280,15 @@ func (c *clientImpl) RequestMembersWithQuery(ctx context.Context, guildID snowfl
})
}

func (c *clientImpl) RequestSoundboardSounds(ctx context.Context, guildIDs ...snowflake.ID) error {
if !c.HasGateway() {
return discord.ErrNoGateway
}
return c.gateway.Send(ctx, gateway.OpcodeRequestSoundboardSounds, gateway.MessageDataRequestSoundboardSounds{
GuildIDs: guildIDs,
})
}

func (c *clientImpl) SetPresence(ctx context.Context, opts ...gateway.PresenceOpt) error {
if !c.HasGateway() {
return discord.ErrNoGateway
Expand Down
38 changes: 26 additions & 12 deletions cache/cache_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,19 @@ import (
// DefaultConfig returns a Config with sensible defaults.
func DefaultConfig() *Config {
return &Config{
GuildCachePolicy: PolicyAll[discord.Guild],
ChannelCachePolicy: PolicyAll[discord.GuildChannel],
StageInstanceCachePolicy: PolicyAll[discord.StageInstance],
GuildScheduledEventCachePolicy: PolicyAll[discord.GuildScheduledEvent],
RoleCachePolicy: PolicyAll[discord.Role],
MemberCachePolicy: PolicyAll[discord.Member],
ThreadMemberCachePolicy: PolicyAll[discord.ThreadMember],
PresenceCachePolicy: PolicyAll[discord.Presence],
VoiceStateCachePolicy: PolicyAll[discord.VoiceState],
MessageCachePolicy: PolicyAll[discord.Message],
EmojiCachePolicy: PolicyAll[discord.Emoji],
StickerCachePolicy: PolicyAll[discord.Sticker],
GuildCachePolicy: PolicyAll[discord.Guild],
ChannelCachePolicy: PolicyAll[discord.GuildChannel],
StageInstanceCachePolicy: PolicyAll[discord.StageInstance],
GuildScheduledEventCachePolicy: PolicyAll[discord.GuildScheduledEvent],
GuildSoundboardSoundCachePolicy: PolicyAll[discord.SoundboardSound],
RoleCachePolicy: PolicyAll[discord.Role],
MemberCachePolicy: PolicyAll[discord.Member],
ThreadMemberCachePolicy: PolicyAll[discord.ThreadMember],
PresenceCachePolicy: PolicyAll[discord.Presence],
VoiceStateCachePolicy: PolicyAll[discord.VoiceState],
MessageCachePolicy: PolicyAll[discord.Message],
EmojiCachePolicy: PolicyAll[discord.Emoji],
StickerCachePolicy: PolicyAll[discord.Sticker],
}
}

Expand All @@ -42,6 +43,9 @@ type Config struct {
GuildScheduledEventCache GuildScheduledEventCache
GuildScheduledEventCachePolicy Policy[discord.GuildScheduledEvent]

GuildSoundboardSoundCache GuildSoundboardSoundCache
GuildSoundboardSoundCachePolicy Policy[discord.SoundboardSound]

RoleCache RoleCache
RoleCachePolicy Policy[discord.Role]

Expand Down Expand Up @@ -90,6 +94,9 @@ func (c *Config) Apply(opts []ConfigOpt) {
if c.GuildScheduledEventCache == nil {
c.GuildScheduledEventCache = NewGuildScheduledEventCache(NewGroupedCache[discord.GuildScheduledEvent](c.CacheFlags, FlagGuildScheduledEvents, c.GuildScheduledEventCachePolicy))
}
if c.GuildSoundboardSoundCache == nil {
c.GuildSoundboardSoundCache = NewGuildSoundboardSoundCache(NewGroupedCache[discord.SoundboardSound](c.CacheFlags, FlagGuildSoundboardSounds, c.GuildSoundboardSoundCachePolicy))
}
if c.RoleCache == nil {
c.RoleCache = NewRoleCache(NewGroupedCache[discord.Role](c.CacheFlags, FlagRoles, c.RoleCachePolicy))
}
Expand Down Expand Up @@ -179,6 +186,13 @@ func WithGuildScheduledEventCache(guildScheduledEventCache GuildScheduledEventCa
}
}

// WithGuildSoundboardSoundCache sets the GuildSoundboardSoundCache of the Config.
func WithGuildSoundboardSoundCache(guildSoundboardSoundCache GuildSoundboardSoundCache) ConfigOpt {
return func(config *Config) {
config.GuildSoundboardSoundCache = guildSoundboardSoundCache
}
}

// WithRoleCachePolicy sets the Policy[discord.Role] of the Config.
func WithRoleCachePolicy(policy Policy[discord.Role]) ConfigOpt {
return func(config *Config) {
Expand Down
4 changes: 3 additions & 1 deletion cache/cache_flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const (
FlagStickers
FlagVoiceStates
FlagStageInstances
FlagGuildSoundboardSounds

FlagsNone Flags = 0
FlagsAll = FlagGuilds |
Expand All @@ -32,7 +33,8 @@ const (
FlagEmojis |
FlagStickers |
FlagVoiceStates |
FlagStageInstances
FlagStageInstances |
FlagGuildSoundboardSounds
)

// Add allows you to add multiple bits together, producing a new bit
Expand Down
111 changes: 84 additions & 27 deletions cache/caches.go
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,59 @@ func (c *guildScheduledEventCacheImpl) RemoveGuildScheduledEventsByGuildID(guild
c.cache.GroupRemove(guildID)
}

type GuildSoundboardSoundCache interface {
GuildSoundboardSoundCache() GroupedCache[discord.SoundboardSound]
GuildSoundboardSound(guildID snowflake.ID, soundID snowflake.ID) (discord.SoundboardSound, bool)
GuildSoundboardSoundsForEach(guildID snowflake.ID, fn func(sound discord.SoundboardSound))
GuildSoundboardSoundsAllLen() int
GuildSoundboardSoundsLen(guildID snowflake.ID) int
AddGuildSoundboardSound(sound discord.SoundboardSound)
RemoveGuildSoundboardSound(guildID snowflake.ID, sound snowflake.ID) (discord.SoundboardSound, bool)
RemoveGuildSoundboardSoundsByGuildID(guildID snowflake.ID)
}

func NewGuildSoundboardSoundCache(cache GroupedCache[discord.SoundboardSound]) GuildSoundboardSoundCache {
return &guildSoundboardSoundCacheImpl{
cache: cache,
}
}

type guildSoundboardSoundCacheImpl struct {
cache GroupedCache[discord.SoundboardSound]
}

func (c *guildSoundboardSoundCacheImpl) GuildSoundboardSoundCache() GroupedCache[discord.SoundboardSound] {
return c.cache
}

func (c *guildSoundboardSoundCacheImpl) GuildSoundboardSound(guildID snowflake.ID, soundID snowflake.ID) (discord.SoundboardSound, bool) {
return c.cache.Get(guildID, soundID)
}

func (c *guildSoundboardSoundCacheImpl) GuildSoundboardSoundsForEach(guildID snowflake.ID, fn func(sound discord.SoundboardSound)) {
c.cache.GroupForEach(guildID, fn)
}

func (c *guildSoundboardSoundCacheImpl) GuildSoundboardSoundsAllLen() int {
return c.cache.Len()
}

func (c *guildSoundboardSoundCacheImpl) GuildSoundboardSoundsLen(guildID snowflake.ID) int {
return c.cache.GroupLen(guildID)
}

func (c *guildSoundboardSoundCacheImpl) AddGuildSoundboardSound(sound discord.SoundboardSound) {
c.cache.Put(*sound.GuildID, sound.SoundID, sound)
}

func (c *guildSoundboardSoundCacheImpl) RemoveGuildSoundboardSound(guildID snowflake.ID, soundID snowflake.ID) (discord.SoundboardSound, bool) {
return c.cache.Remove(guildID, soundID)
}

func (c *guildSoundboardSoundCacheImpl) RemoveGuildSoundboardSoundsByGuildID(guildID snowflake.ID) {
c.cache.GroupRemove(guildID)
}

type RoleCache interface {
RoleCache() GroupedCache[discord.Role]

Expand Down Expand Up @@ -749,6 +802,7 @@ type Caches interface {
ChannelCache
StageInstanceCache
GuildScheduledEventCache
GuildSoundboardSoundCache
RoleCache
MemberCache
ThreadMemberCache
Expand Down Expand Up @@ -830,38 +884,40 @@ func New(opts ...ConfigOpt) Caches {
config.Apply(opts)

return &cachesImpl{
config: *config,
selfUserCache: config.SelfUserCache,
guildCache: config.GuildCache,
channelCache: config.ChannelCache,
stageInstanceCache: config.StageInstanceCache,
guildScheduledEventCache: config.GuildScheduledEventCache,
roleCache: config.RoleCache,
memberCache: config.MemberCache,
threadMemberCache: config.ThreadMemberCache,
presenceCache: config.PresenceCache,
voiceStateCache: config.VoiceStateCache,
messageCache: config.MessageCache,
emojiCache: config.EmojiCache,
stickerCache: config.StickerCache,
config: *config,
selfUserCache: config.SelfUserCache,
guildCache: config.GuildCache,
channelCache: config.ChannelCache,
stageInstanceCache: config.StageInstanceCache,
guildScheduledEventCache: config.GuildScheduledEventCache,
guildSoundboardSoundCache: config.GuildSoundboardSoundCache,
roleCache: config.RoleCache,
memberCache: config.MemberCache,
threadMemberCache: config.ThreadMemberCache,
presenceCache: config.PresenceCache,
voiceStateCache: config.VoiceStateCache,
messageCache: config.MessageCache,
emojiCache: config.EmojiCache,
stickerCache: config.StickerCache,
}
}

// these type aliases are needed to allow having the GuildCache, ChannelCache, etc. as methods on the cachesImpl struct
type (
guildCache = GuildCache
channelCache = ChannelCache
stageInstanceCache = StageInstanceCache
guildScheduledEventCache = GuildScheduledEventCache
roleCache = RoleCache
memberCache = MemberCache
threadMemberCache = ThreadMemberCache
presenceCache = PresenceCache
voiceStateCache = VoiceStateCache
messageCache = MessageCache
emojiCache = EmojiCache
stickerCache = StickerCache
selfUserCache = SelfUserCache
guildCache = GuildCache
channelCache = ChannelCache
stageInstanceCache = StageInstanceCache
guildScheduledEventCache = GuildScheduledEventCache
guildSoundboardSoundCache = GuildSoundboardSoundCache
roleCache = RoleCache
memberCache = MemberCache
threadMemberCache = ThreadMemberCache
presenceCache = PresenceCache
voiceStateCache = VoiceStateCache
messageCache = MessageCache
emojiCache = EmojiCache
stickerCache = StickerCache
selfUserCache = SelfUserCache
)

type cachesImpl struct {
Expand All @@ -871,6 +927,7 @@ type cachesImpl struct {
channelCache
stageInstanceCache
guildScheduledEventCache
guildSoundboardSoundCache
roleCache
memberCache
threadMemberCache
Expand Down
6 changes: 6 additions & 0 deletions discord/audit_log.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,12 @@ const (
AuditLogApplicationCommandPermissionUpdate AuditLogEvent = 121
)

const (
AuditLogSoundboardSoundCreate AuditLogEvent = iota + 130
AuditLogSoundboardSoundUpdate
AuditLogSoundboardSoundDelete
)

const (
AuditLogAutoModerationRuleCreate AuditLogEvent = iota + 140
AuditLogAutoModerationRuleUpdate
Expand Down
2 changes: 2 additions & 0 deletions discord/cdn_endpoints.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ var (
CustomSticker = NewCDN("/stickers/{sticker.id}", FileFormatPNG, FileFormatLottie, FileFormatGIF)

AttachmentFile = NewCDN("/attachments/{channel.id}/{attachment.id}/{file.name}", FileFormatNone)

SoundboardSoundFile = NewCDN("/soundboard-sounds/{sound.id}", FileFormatNone)
)

// FileFormat is the type of file on Discord's CDN (https://discord.com/developers/docs/reference#image-formatting-image-formats)
Expand Down
3 changes: 3 additions & 0 deletions discord/guild.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ const (
GuildFeatureInvitesDisabled GuildFeature = "INVITES_DISABLED"
GuildFeatureInviteSplash GuildFeature = "INVITE_SPLASH"
GuildFeatureMemberVerificationGateEnabled GuildFeature = "MEMBER_VERIFICATION_GATE_ENABLED"
GuildFeatureMoreSoundboard GuildFeature = "MORE_SOUNDBOARD"
GuildFeatureMoreStickers GuildFeature = "MORE_STICKERS"
GuildFeatureNews GuildFeature = "NEWS"
GuildFeaturePartnered GuildFeature = "PARTNERED"
Expand All @@ -119,6 +120,7 @@ const (
GuildFeatureRoleIcons GuildFeature = "ROLE_ICONS"
GuildFeatureRoleSubscriptionsAvailableForPurchase GuildFeature = "ROLE_SUBSCRIPTIONS_AVAILABLE_FOR_PURCHASE"
GuildFeatureRoleSubscriptionsEnabled GuildFeature = "ROLE_SUBSCRIPTIONS_ENABLED"
GuildFeatureSoundboard GuildFeature = "SOUNDBOARD"
GuildFeatureTicketedEventsEnabled GuildFeature = "TICKETED_EVENTS_ENABLED"
GuildFeatureVanityURL GuildFeature = "VANITY_URL"
GuildFeatureVerified GuildFeature = "VERIFIED"
Expand Down Expand Up @@ -224,6 +226,7 @@ type GatewayGuild struct {
Presences []Presence `json:"presences"`
StageInstances []StageInstance `json:"stage_instances"`
GuildScheduledEvents []GuildScheduledEvent `json:"guild_scheduled_events"`
SoundboardSounds []SoundboardSound `json:"soundboard_sounds"`
}

func (g *GatewayGuild) UnmarshalJSON(data []byte) error {
Expand Down
59 changes: 59 additions & 0 deletions discord/sound.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package discord

import (
"encoding/base64"
"fmt"
"io"

"github.com/disgoorg/json"
)

type SoundType string

const (
SoundTypeMP3 SoundType = "audio/mpeg"
topi314 marked this conversation as resolved.
Show resolved Hide resolved
SoundTypeOGG SoundType = "audio/ogg"
SoundTypeWAV SoundType = "audio/wav"
SoundTypeUnknown = SoundTypeMP3
)

func (t SoundType) GetMIME() string {
sebm253 marked this conversation as resolved.
Show resolved Hide resolved
return string(t)
}

func (t SoundType) GetHeader() string {
sebm253 marked this conversation as resolved.
Show resolved Hide resolved
return "data:" + string(t) + ";base64"
}

var _ json.Marshaler = (*Sound)(nil)
var _ fmt.Stringer = (*Sound)(nil)

func NewSound(soundType SoundType, reader io.Reader) (*Sound, error) {
data, err := io.ReadAll(reader)
if err != nil {
return nil, err
}
return NewSoundRaw(soundType, data), nil
}

func NewSoundRaw(soundType SoundType, src []byte) *Sound {
data := make([]byte, base64.StdEncoding.EncodedLen(len(src)))
base64.StdEncoding.Encode(data, src)
return &Sound{Type: soundType, Data: data}
}

type Sound struct {
Type SoundType
Data []byte
}

func (s Sound) MarshalJSON() ([]byte, error) {
return json.Marshal(s.String())
}

func (s Sound) String() string {
if len(s.Data) == 0 {
return ""
}
return s.Type.GetHeader() + "," + string(s.Data)
sebm253 marked this conversation as resolved.
Show resolved Hide resolved
}
Loading
Loading