diff --git a/discord/activity.go b/discord/activity.go index 9f6e66d7..4027556b 100644 --- a/discord/activity.go +++ b/discord/activity.go @@ -1,6 +1,11 @@ package discord -import "github.com/disgoorg/snowflake/v2" +import ( + "time" + + "github.com/disgoorg/disgo/json" + "github.com/disgoorg/snowflake/v2" +) // ActivityType represents the status of a user, one of Game, Streaming, Listening, Watching, Custom or Competing type ActivityType int @@ -21,7 +26,7 @@ type Activity struct { Name string `json:"name"` Type ActivityType `json:"type"` URL *string `json:"url"` - CreatedAt int64 `json:"created_at"` + CreatedAt time.Time `json:"created_at"` Timestamps *ActivityTimestamps `json:"timestamps,omitempty"` ApplicationID snowflake.ID `json:"application_id,omitempty"` Details *string `json:"details,omitempty"` @@ -35,6 +40,31 @@ type Activity struct { Buttons []string `json:"buttons"` } +func (a *Activity) UnmarshalJSON(data []byte) error { + type activity Activity + var v struct { + CreatedAt int64 `json:"created_at"` + activity + } + if err := json.Unmarshal(data, &v); err != nil { + return err + } + *a = Activity(v.activity) + a.CreatedAt = time.UnixMilli(v.CreatedAt) + return nil +} + +func (a Activity) MarshalJSON() ([]byte, error) { + type activity Activity + return json.Marshal(struct { + CreatedAt int64 `json:"created_at"` + activity + }{ + CreatedAt: a.CreatedAt.UnixMilli(), + activity: (activity)(a), + }) +} + // ActivityFlags add additional information to an activity type ActivityFlags int @@ -59,8 +89,31 @@ type ActivityButton struct { // ActivityTimestamps represents when a user started and ended their activity type ActivityTimestamps struct { - Start int64 `json:"start,omitempty"` - End int64 `json:"end,omitempty"` + Start time.Time + End time.Time +} + +func (a *ActivityTimestamps) UnmarshalJSON(data []byte) error { + var v struct { + Start int64 `json:"start"` + End int64 `json:"end"` + } + if err := json.Unmarshal(data, &v); err != nil { + return err + } + a.Start = time.UnixMilli(v.Start) + a.End = time.UnixMilli(v.End) + return nil +} + +func (a ActivityTimestamps) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Start int64 `json:"start,omitempty"` + End int64 `json:"end,omitempty"` + }{ + Start: a.Start.UnixMilli(), + End: a.End.UnixMilli(), + }) } // ActivityEmoji is an Emoji object for an Activity diff --git a/discord/application.go b/discord/application.go index f898b817..03443bac 100644 --- a/discord/application.go +++ b/discord/application.go @@ -48,6 +48,10 @@ func (a Application) CoverURL(opts ...CDNOpt) *string { return &url } +func (a Application) CreatedAt() time.Time { + return a.ID.Time() +} + type PartialApplication struct { ID snowflake.ID `json:"id"` Flags ApplicationFlags `json:"flags"` @@ -221,6 +225,10 @@ func (t Team) IconURL(opts ...CDNOpt) *string { return &url } +func (t Team) CreatedAt() time.Time { + return t.ID.Time() +} + type TeamMember struct { MembershipState MembershipState `json:"membership_state"` Permissions []TeamPermissions `json:"permissions"` diff --git a/discord/application_command.go b/discord/application_command.go index 7f58a9e2..46835719 100644 --- a/discord/application_command.go +++ b/discord/application_command.go @@ -2,6 +2,7 @@ package discord import ( "fmt" + "time" "github.com/disgoorg/disgo/json" "github.com/disgoorg/snowflake/v2" @@ -27,6 +28,7 @@ type ApplicationCommand interface { DefaultMemberPermissions() Permissions DMPermission() bool Version() snowflake.ID + CreatedAt() time.Time applicationCommand() } @@ -174,6 +176,10 @@ func (c SlashCommand) Version() snowflake.ID { return c.version } +func (c SlashCommand) CreatedAt() time.Time { + return c.id.Time() +} + func (SlashCommand) applicationCommand() {} var _ ApplicationCommand = (*UserCommand)(nil) @@ -262,6 +268,10 @@ func (c UserCommand) Version() snowflake.ID { return c.version } +func (c UserCommand) CreatedAt() time.Time { + return c.id.Time() +} + func (UserCommand) applicationCommand() {} var _ ApplicationCommand = (*MessageCommand)(nil) @@ -350,4 +360,8 @@ func (c MessageCommand) Version() snowflake.ID { return c.version } +func (c MessageCommand) CreatedAt() time.Time { + return c.id.Time() +} + func (MessageCommand) applicationCommand() {} diff --git a/discord/attachment.go b/discord/attachment.go index 3946f396..ecec042f 100644 --- a/discord/attachment.go +++ b/discord/attachment.go @@ -1,6 +1,10 @@ package discord -import "github.com/disgoorg/snowflake/v2" +import ( + "time" + + "github.com/disgoorg/snowflake/v2" +) //Attachment is used for files sent in a Message type Attachment struct { @@ -16,6 +20,10 @@ type Attachment struct { Ephemeral bool `json:"ephemeral,omitempty"` } +func (a Attachment) CreatedAt() time.Time { + return a.ID.Time() +} + type AttachmentUpdate interface { attachmentUpdate() } diff --git a/discord/auto_moderation.go b/discord/auto_moderation.go index 5f526268..fd10058f 100644 --- a/discord/auto_moderation.go +++ b/discord/auto_moderation.go @@ -1,6 +1,10 @@ package discord -import "github.com/disgoorg/snowflake/v2" +import ( + "time" + + "github.com/disgoorg/snowflake/v2" +) type AutoModerationEventType int @@ -62,6 +66,10 @@ type AutoModerationRule struct { ExemptChannels []snowflake.ID `json:"exempt_channels"` } +func (r AutoModerationRule) CreatedAt() time.Time { + return r.ID.Time() +} + type AutoModerationRuleCreate struct { Name string `json:"name"` EventType AutoModerationEventType `json:"event_type"` diff --git a/discord/channel.go b/discord/channel.go index a76ff785..eeb757f6 100644 --- a/discord/channel.go +++ b/discord/channel.go @@ -87,6 +87,9 @@ type Channel interface { // Name returns the name of the Channel. Name() string + // CreatedAt returns the creation time of the Channel. + CreatedAt() time.Time + channel() } @@ -349,6 +352,10 @@ func (c GuildTextChannel) DefaultAutoArchiveDuration() AutoArchiveDuration { return c.defaultAutoArchiveDuration } +func (c GuildTextChannel) CreatedAt() time.Time { + return c.id.Time() +} + func (GuildTextChannel) channel() {} func (GuildTextChannel) guildChannel() {} func (GuildTextChannel) messageChannel() {} @@ -413,6 +420,10 @@ func (c DMChannel) LastPinTimestamp() *time.Time { return c.lastPinTimestamp } +func (c DMChannel) CreatedAt() time.Time { + return c.id.Time() +} + func (DMChannel) channel() {} func (DMChannel) messageChannel() {} @@ -557,6 +568,10 @@ func (c GuildVoiceChannel) RateLimitPerUser() int { return c.rateLimitPerUser } +func (c GuildVoiceChannel) CreatedAt() time.Time { + return c.id.Time() +} + func (GuildVoiceChannel) channel() {} func (GuildVoiceChannel) messageChannel() {} func (GuildVoiceChannel) guildChannel() {} @@ -638,6 +653,10 @@ func (c GuildCategoryChannel) ParentID() *snowflake.ID { return nil } +func (c GuildCategoryChannel) CreatedAt() time.Time { + return c.id.Time() +} + func (GuildCategoryChannel) channel() {} func (GuildCategoryChannel) guildChannel() {} @@ -762,6 +781,10 @@ func (c GuildNewsChannel) ParentID() *snowflake.ID { return c.parentID } +func (c GuildNewsChannel) CreatedAt() time.Time { + return c.id.Time() +} + func (GuildNewsChannel) channel() {} func (GuildNewsChannel) guildChannel() {} func (GuildNewsChannel) messageChannel() {} @@ -898,6 +921,10 @@ func (c GuildThread) DefaultAutoArchiveDuration() AutoArchiveDuration { return 0 } +func (c GuildThread) CreatedAt() time.Time { + return c.id.Time() +} + func (GuildThread) channel() {} func (GuildThread) guildChannel() {} func (GuildThread) messageChannel() {} @@ -995,6 +1022,10 @@ func (c GuildStageVoiceChannel) ParentID() *snowflake.ID { return c.parentID } +func (c GuildStageVoiceChannel) CreatedAt() time.Time { + return c.id.Time() +} + func (GuildStageVoiceChannel) channel() {} func (GuildStageVoiceChannel) guildChannel() {} func (GuildStageVoiceChannel) guildAudioChannel() {} @@ -1085,6 +1116,10 @@ func (c GuildForumChannel) ParentID() *snowflake.ID { return c.parentID } +func (c GuildForumChannel) CreatedAt() time.Time { + return c.id.Time() +} + func (GuildForumChannel) channel() {} func (GuildForumChannel) guildChannel() {} diff --git a/discord/emoji.go b/discord/emoji.go index e56b6142..d92b2e0c 100644 --- a/discord/emoji.go +++ b/discord/emoji.go @@ -1,6 +1,8 @@ package discord import ( + "time" + "github.com/disgoorg/snowflake/v2" ) @@ -35,6 +37,13 @@ func (e Emoji) URL(opts ...CDNOpt) string { return formatAssetURL(CustomEmoji, opts, e.ID) } +func (e Emoji) CreatedAt() time.Time { + if e.ID == 0 { + return time.Time{} + } + return e.ID.Time() +} + type EmojiCreate struct { Name string `json:"name"` Image Icon `json:"image"` diff --git a/discord/guild.go b/discord/guild.go index 5d743e3a..65999e17 100644 --- a/discord/guild.go +++ b/discord/guild.go @@ -171,6 +171,10 @@ func (g Guild) BannerURL(opts ...CDNOpt) *string { return &url } +func (g Guild) CreatedAt() time.Time { + return g.ID.Time() +} + type RestGuild struct { Guild Stickers []Sticker `json:"stickers"` diff --git a/discord/guild_scheduled_event.go b/discord/guild_scheduled_event.go index 91cdaf16..48f609b3 100644 --- a/discord/guild_scheduled_event.go +++ b/discord/guild_scheduled_event.go @@ -25,6 +25,10 @@ type GuildScheduledEvent struct { UserCount int `json:"user_count"` } +func (e GuildScheduledEvent) CreatedAt() time.Time { + return e.ID.Time() +} + type GuildScheduledEventCreate struct { ChannelID snowflake.ID `json:"channel_id,omitempty"` EntityMetaData *EntityMetaData `json:"entity_metadata,omitempty"` diff --git a/discord/integration.go b/discord/integration.go index 9f32db83..50db1972 100644 --- a/discord/integration.go +++ b/discord/integration.go @@ -2,6 +2,7 @@ package discord import ( "fmt" + "time" "github.com/disgoorg/disgo/json" "github.com/disgoorg/snowflake/v2" @@ -38,6 +39,7 @@ type Integration interface { json.Marshaler Type() IntegrationType ID() snowflake.ID + CreatedAt() time.Time } type UnmarshalIntegration struct { @@ -121,6 +123,10 @@ func (i TwitchIntegration) ID() snowflake.ID { return i.IntegrationID } +func (i TwitchIntegration) CreatedAt() time.Time { + return i.IntegrationID.Time() +} + type YouTubeIntegration struct { IntegrationID snowflake.ID `json:"id"` Name string `json:"name"` @@ -155,6 +161,10 @@ func (i YouTubeIntegration) ID() snowflake.ID { return i.IntegrationID } +func (i YouTubeIntegration) CreatedAt() time.Time { + return i.IntegrationID.Time() +} + type BotIntegration struct { IntegrationID snowflake.ID `json:"id"` Name string `json:"name"` @@ -181,3 +191,7 @@ func (BotIntegration) Type() IntegrationType { func (i BotIntegration) ID() snowflake.ID { return i.IntegrationID } + +func (i BotIntegration) CreatedAt() time.Time { + return i.IntegrationID.Time() +} diff --git a/discord/interaction_base.go b/discord/interaction_base.go index 4ffe823a..bf83c132 100644 --- a/discord/interaction_base.go +++ b/discord/interaction_base.go @@ -1,6 +1,8 @@ package discord import ( + "time" + "github.com/disgoorg/disgo/json" "github.com/disgoorg/snowflake/v2" ) @@ -17,6 +19,7 @@ type BaseInteraction interface { Member() *ResolvedMember User() User AppPermissions() *Permissions + CreatedAt() time.Time } type baseInteractionImpl struct { @@ -105,3 +108,7 @@ func (i baseInteractionImpl) User() User { func (i baseInteractionImpl) AppPermissions() *Permissions { return i.appPermissions } + +func (i baseInteractionImpl) CreatedAt() time.Time { + return i.id.Time() +} diff --git a/discord/interaction_ping.go b/discord/interaction_ping.go index 8e48f2a9..ab79aa1f 100644 --- a/discord/interaction_ping.go +++ b/discord/interaction_ping.go @@ -1,6 +1,8 @@ package discord import ( + "time" + "github.com/disgoorg/disgo/json" "github.com/disgoorg/snowflake/v2" ) @@ -58,6 +60,10 @@ func (i PingInteraction) Version() int { return i.version } +func (i PingInteraction) CreatedAt() time.Time { + return i.id.Time() +} + func (PingInteraction) GuildID() *snowflake.ID { return nil } diff --git a/discord/member.go b/discord/member.go index 0e3fb514..356ac9bb 100644 --- a/discord/member.go +++ b/discord/member.go @@ -60,6 +60,10 @@ func (m Member) AvatarURL(opts ...CDNOpt) *string { return &url } +func (m Member) CreatedAt() time.Time { + return m.User.CreatedAt() +} + // MemberAdd is used to add a member via the oauth2 access token to a guild type MemberAdd struct { AccessToken string `json:"access_token"` diff --git a/discord/role.go b/discord/role.go index 1cf14cf6..ce2e4c03 100644 --- a/discord/role.go +++ b/discord/role.go @@ -1,6 +1,8 @@ package discord import ( + "time" + "github.com/disgoorg/disgo/json" "github.com/disgoorg/snowflake/v2" ) @@ -38,6 +40,10 @@ func (r Role) IconURL(opts ...CDNOpt) *string { return &url } +func (r Role) CreatedAt() time.Time { + return r.ID.Time() +} + // RoleTag are tags a Role has type RoleTag struct { BotID *snowflake.ID `json:"bot_id,omitempty"` diff --git a/discord/stage_instance.go b/discord/stage_instance.go index d8412f8c..9f9fca6d 100644 --- a/discord/stage_instance.go +++ b/discord/stage_instance.go @@ -1,6 +1,10 @@ package discord -import "github.com/disgoorg/snowflake/v2" +import ( + "time" + + "github.com/disgoorg/snowflake/v2" +) type StagePrivacyLevel int @@ -18,6 +22,10 @@ type StageInstance struct { DiscoverableDisabled bool `json:"discoverable_disabled"` } +func (e StageInstance) CreatedAt() time.Time { + return e.ID.Time() +} + type StageInstanceCreate struct { ChannelID snowflake.ID `json:"channel_id"` Topic string `json:"topic,omitempty"` diff --git a/discord/sticker.go b/discord/sticker.go index fe0837ce..4afa2832 100644 --- a/discord/sticker.go +++ b/discord/sticker.go @@ -1,6 +1,8 @@ package discord import ( + "time" + "github.com/disgoorg/snowflake/v2" ) @@ -27,6 +29,10 @@ func (s Sticker) URL(opts ...CDNOpt) string { return formatAssetURL(CustomSticker, append(opts, WithFormat(format)), s.ID) } +func (s Sticker) CreatedAt() time.Time { + return s.ID.Time() +} + type StickerType int const ( diff --git a/discord/user.go b/discord/user.go index 84aeb61f..6cf14776 100644 --- a/discord/user.go +++ b/discord/user.go @@ -2,6 +2,7 @@ package discord import ( "strconv" + "time" "github.com/disgoorg/disgo/json" "github.com/disgoorg/snowflake/v2" @@ -96,6 +97,10 @@ func (u User) BannerURL(opts ...CDNOpt) *string { return &url } +func (u User) CreatedAt() time.Time { + return u.ID.Time() +} + // OAuth2User represents a full User returned by the oauth2 endpoints type OAuth2User struct { User diff --git a/discord/webhook.go b/discord/webhook.go index ed53ae82..6d21e1b1 100644 --- a/discord/webhook.go +++ b/discord/webhook.go @@ -2,6 +2,7 @@ package discord import ( "fmt" + "time" "github.com/disgoorg/disgo/json" "github.com/disgoorg/snowflake/v2" @@ -25,6 +26,7 @@ type Webhook interface { Name() string Avatar() *string AvatarURL(opts ...CDNOpt) *string + CreatedAt() time.Time webhook() } @@ -155,6 +157,10 @@ func (w IncomingWebhook) URL() string { return WebhookURL(w.ID(), w.Token) } +func (w IncomingWebhook) CreatedAt() time.Time { + return w.id.Time() +} + func (IncomingWebhook) webhook() {} var _ Webhook = (*ChannelFollowerWebhook)(nil) @@ -237,6 +243,10 @@ func (w ChannelFollowerWebhook) DefaultAvatarURL(opts ...CDNOpt) string { return formatAssetURL(DefaultUserAvatar, opts, 0) } +func (w ChannelFollowerWebhook) CreatedAt() time.Time { + return w.id.Time() +} + func (ChannelFollowerWebhook) webhook() {} var _ Webhook = (*ApplicationWebhook)(nil) @@ -314,6 +324,10 @@ func (w ApplicationWebhook) DefaultAvatarURL(opts ...CDNOpt) string { return formatAssetURL(DefaultUserAvatar, opts, 0) } +func (w ApplicationWebhook) CreatedAt() time.Time { + return w.id.Time() +} + func (ApplicationWebhook) webhook() {} type WebhookSourceGuild struct {