2020-01-02 19:53:08 +00:00
package discord
2020-10-29 20:25:03 +00:00
import (
2024-07-13 19:36:33 +00:00
"fmt"
2020-10-29 20:25:03 +00:00
"strconv"
2021-01-10 19:07:04 +00:00
"strings"
2021-05-20 22:47:44 +00:00
"time"
2021-05-30 05:02:55 +00:00
2021-06-02 02:53:19 +00:00
"github.com/diamondburned/arikawa/v3/utils/json"
2022-09-21 20:17:26 +00:00
"github.com/diamondburned/arikawa/v3/utils/json/option"
2020-10-29 20:25:03 +00:00
)
2022-09-23 07:00:04 +00:00
// ChannelFlags are the channel flags combined as a bitfield.
type ChannelFlags uint64
const (
_ ChannelFlags = 1 << iota
// PinnedThread means this thread is pinned to the top of its parent
// GuildForum channel.
PinnedThread
_
_
// ThreadRequireTag is whether a tag is required to be specified when
// creating a thread in a GuildForum channel. Tags are specified in the
// AppliedTags field.
ThreadRequireTag
)
2021-05-29 19:09:41 +00:00
// Channel represents a guild or DM channel within Discord.
//
2020-05-23 16:01:08 +00:00
// https://discord.com/developers/docs/resources/channel#channel-object
2020-01-02 19:53:08 +00:00
type Channel struct {
2020-05-23 16:01:08 +00:00
// ID is the id of this channel.
2020-11-22 14:48:36 +00:00
ID ChannelID ` json:"id" `
// GuildID is the id of the guild.
2021-08-08 20:19:15 +00:00
//
// This field may be missing for some channel objects received over gateway
// guild dispatches.
2020-11-22 14:48:36 +00:00
GuildID GuildID ` json:"guild_id,omitempty" `
2020-05-23 16:01:08 +00:00
// Type is the type of channel.
2020-11-21 17:40:54 +00:00
Type ChannelType ` json:"type,omitempty" `
2020-11-22 14:48:36 +00:00
// NSFW specifies whether the channel is nsfw.
NSFW bool ` json:"nsfw,omitempty" `
2020-01-02 19:53:08 +00:00
2020-05-23 16:01:08 +00:00
// Position is the sorting position of the channel.
Position int ` json:"position,omitempty" `
2021-08-08 20:19:15 +00:00
// Overwrites are the explicit permission overrides for members
// and roles.
Overwrites [ ] Overwrite ` json:"permission_overwrites,omitempty" `
2020-01-02 19:53:08 +00:00
2020-05-23 16:01:08 +00:00
// Name is the name of the channel (2-100 characters).
Name string ` json:"name,omitempty" `
// Topic is the channel topic (0-1024 characters).
Topic string ` json:"topic,omitempty" `
2020-01-02 19:53:08 +00:00
2020-05-23 16:01:08 +00:00
// LastMessageID is the id of the last message sent in this channel (may
// not point to an existing or valid message).
2020-11-22 14:48:36 +00:00
LastMessageID MessageID ` json:"last_message_id,omitempty" `
2020-01-02 19:53:08 +00:00
2020-05-23 16:01:08 +00:00
// VoiceBitrate is the bitrate (in bits) of the voice channel.
VoiceBitrate uint ` json:"bitrate,omitempty" `
// VoiceUserLimit is the user limit of the voice channel.
VoiceUserLimit uint ` json:"user_limit,omitempty" `
2020-01-02 19:53:08 +00:00
2022-09-23 07:00:04 +00:00
// Flags is a bitmask that contains if a thread is pinned, for example.
Flags ChannelFlags ` json:"flags,omitempty" `
2020-05-23 16:01:08 +00:00
// UserRateLimit is the amount of seconds a user has to wait before sending
// another message (0-21600). Bots, as well as users with the permission
// manage_messages or manage_channel, are unaffected.
UserRateLimit Seconds ` json:"rate_limit_per_user,omitempty" `
2020-01-02 19:53:08 +00:00
2020-05-23 16:01:08 +00:00
// DMRecipients are the recipients of the DM.
DMRecipients [ ] User ` json:"recipients,omitempty" `
// Icon is the icon hash.
Icon Hash ` json:"icon,omitempty" `
2021-08-08 20:19:15 +00:00
// OwnerID is the id of the DM or thread creator.
OwnerID UserID ` json:"owner_id,omitempty" `
2020-05-23 16:01:08 +00:00
// AppID is the application id of the group DM creator if it is
// bot-created.
2020-11-22 14:48:36 +00:00
AppID AppID ` json:"application_id,omitempty" `
2021-08-08 20:19:15 +00:00
// ParentID for guild channels: id of the parent category for a channel
// (each parent category can contain up to 50 channels), for threads: the
// id of the text channel this thread was created.
ParentID ChannelID ` json:"parent_id,omitempty" `
2020-01-02 19:53:08 +00:00
2020-05-23 16:01:08 +00:00
// LastPinTime is when the last pinned message was pinned.
2020-01-02 19:53:08 +00:00
LastPinTime Timestamp ` json:"last_pin_timestamp,omitempty" `
2021-05-29 18:22:57 +00:00
2021-05-30 21:14:41 +00:00
// RTCRegionID is the voice region id for the voice channel.
2021-05-30 05:02:55 +00:00
RTCRegionID string ` json:"rtc_region,omitempty" `
2021-05-29 18:22:57 +00:00
// VideoQualityMode is the camera video quality mode of the voice channel.
VideoQualityMode VideoQualityMode ` json:"video_quality_mode,omitempty" `
2021-08-08 20:19:15 +00:00
// MessageCount is an approximate count of messages in a thread. However,
// counting stops at 50.
MessageCount int ` json:"message_count,omitempty" `
// MemberCount is an approximate count of users in a thread. However,
// counting stops at 50.
MemberCount int ` json:"member_count,omitempty" `
// ThreadMetadata contains thread-specific fields not needed by other
// channels.
ThreadMetadata * ThreadMetadata ` json:"thread_metadata,omitempty" `
// ThreadMember is the thread member object for the current user, if they
// have joined the thread, only included on certain API endpoints.
ThreadMember * ThreadMember ` json:"thread_member,omitempty" `
// DefaultAutoArchiveDuration is the default duration for newly created
// threads, in minutes, to automatically archive the thread after recent
// activity.
DefaultAutoArchiveDuration ArchiveDuration ` json:"default_auto_archive_duration,omitempty" `
// SelfPermissions are the computed permissions for the invoking user in
// the channel, including overwrites, only included when part of the
// resolved data received on a slash command interaction.
SelfPermissions Permissions ` json:"permissions,omitempty,string" `
2022-09-21 20:17:26 +00:00
// AvailableTags is the set of tags that can be used in a GuildForum
// channel.
AvailableTags [ ] Tag ` json:"available_tags,omitempty" `
// AppliedTags are the IDs of the set of tags that have been applied to a
// thread in a GuildForum channel.
AppliedTags [ ] TagID ` json:"applied_tags,omitempty" `
// DefaultReactionEmoji is the emoji to show in the add reaction button on a
// thread in a GuildForum channel
DefaultReactionEmoji * ForumReaction ` json:"default_reaction_emoji,omitempty" `
2023-01-31 08:09:20 +00:00
// DefaultThreadRateLimitPerUser is the initial rate_limit_per_user to set on newly created threads in a channel. this field is copied to the thread at creation time and does not live update.
DefaultThreadRateLimitPerUser int ` json:"default_thread_rate_limit_per_user,omitempty" `
// DefaultSoftOrder is the default sort order type used to order posts in GUILD_FORUM channels. Defaults to null, which indicates a preferred sort order hasn't been set by a channel admin.
DefaultSoftOrder * SortOrderType ` json:"default_sort_order,omitempty" `
// DefaultForumLayout is the default forum layout view used to display posts in GUILD_FORUM channels. Defaults to 0, which indicates a layout view has not been set by a channel admin.
DefaultForumLayout ForumLayoutType ` json:"default_forum_layout,omitempty" `
2021-05-29 18:22:57 +00:00
}
func ( ch * Channel ) UnmarshalJSON ( data [ ] byte ) error {
2021-05-30 05:02:55 +00:00
type RawChannel Channel
2021-06-12 08:26:01 +00:00
if err := json . Unmarshal ( data , ( * RawChannel ) ( ch ) ) ; err != nil {
2021-05-29 18:22:57 +00:00
return err
}
// In the docs, Discord states that if VideoQualityMode is omitted, it is
// actually 1 aka. AutoVideoQuality, and they just didn't bother to send
// it.
// Refer to:
// https://discord.com/developers/docs/resources/channel#channel-object-channel-structure
if ch . VideoQualityMode == 0 {
ch . VideoQualityMode = 1
}
return nil
}
2021-05-20 22:47:44 +00:00
// CreatedAt returns a time object representing when the channel was created.
func ( ch Channel ) CreatedAt ( ) time . Time {
return ch . ID . Time ( )
}
2020-05-23 16:01:08 +00:00
// Mention returns a mention of the channel.
2020-01-24 05:45:47 +00:00
func ( ch Channel ) Mention ( ) string {
2020-09-24 18:43:20 +00:00
return ch . ID . Mention ( )
2020-01-24 05:45:47 +00:00
}
2024-07-13 19:36:33 +00:00
// URL generates a Discord client URL to the channel. If the channel doesn't
// have a GuildID, it will generate a URL with the guild "@me".
func ( c Channel ) URL ( ) string {
var guildID = "@me"
if c . GuildID . IsValid ( ) {
guildID = c . GuildID . String ( )
}
return fmt . Sprintf (
"https://discord.com/channels/%s/%s" ,
guildID , c . ID . String ( ) ,
)
}
2020-05-23 16:01:08 +00:00
// IconURL returns the URL to the channel icon in the PNG format.
// An empty string is returned if there's no icon.
2020-03-05 23:49:44 +00:00
func ( ch Channel ) IconURL ( ) string {
2020-05-23 16:01:08 +00:00
return ch . IconURLWithType ( PNGImage )
}
// IconURLWithType returns the URL to the channel icon using the passed
// ImageType. An empty string is returned if there's no icon.
//
// Supported ImageTypes: PNG, JPEG, WebP
func ( ch Channel ) IconURLWithType ( t ImageType ) string {
2020-03-05 23:49:44 +00:00
if ch . Icon == "" {
return ""
}
return "https://cdn.discordapp.com/channel-icons/" +
2020-05-23 16:01:08 +00:00
ch . ID . String ( ) + "/" + t . format ( ch . Icon )
2020-03-05 23:49:44 +00:00
}
2021-10-10 22:44:31 +00:00
// ChannelType describes the type of the channel.
//
2020-05-23 16:01:08 +00:00
// https://discord.com/developers/docs/resources/channel#channel-object-channel-types
2021-10-10 22:44:31 +00:00
type ChannelType uint16
2021-05-21 06:12:53 +00:00
const (
2020-05-23 16:01:08 +00:00
// GuildText is a text channel within a server.
2021-05-21 06:12:53 +00:00
GuildText ChannelType = iota
2020-05-23 16:01:08 +00:00
// DirectMessage is a direct message between users.
2021-05-21 06:12:53 +00:00
DirectMessage
2020-05-23 16:01:08 +00:00
// GuildVoice is a voice channel within a server.
2021-05-21 06:12:53 +00:00
GuildVoice
2020-05-23 16:01:08 +00:00
// GroupDM is a direct message between multiple users.
2021-05-21 06:12:53 +00:00
GroupDM
2020-05-23 16:01:08 +00:00
// GuildCategory is an organizational category that contains up to 50
// channels.
2021-05-21 06:12:53 +00:00
GuildCategory
2023-01-31 08:13:50 +00:00
// GuildAnnouncement is a channel that users can follow and crosspost into
// their own server.
GuildAnnouncement
2020-05-23 16:01:08 +00:00
// GuildStore is a channel in which game developers can sell their game on
// Discord.
2021-05-21 06:12:53 +00:00
GuildStore
2021-05-29 19:09:41 +00:00
_
_
_
2023-01-31 08:13:50 +00:00
// GuildAnnouncementThread is a temporary sub-channel within a GUILD_NEWS channel
GuildAnnouncementThread
2021-05-29 19:09:41 +00:00
// GuildPublicThread is a temporary sub-channel within a GUILD_TEXT
// channel.
GuildPublicThread
// GuildPrivateThread isa temporary sub-channel within a GUILD_TEXT channel
// that is only viewable by those invited and those with the MANAGE_THREADS
// permission.
GuildPrivateThread
// GuildStageVoice is a voice channel for hosting events with an audience.
GuildStageVoice
2022-09-19 21:55:54 +00:00
// GuildDirectory is the channel in a hub containing the listed servers.
GuildDirectory
// GuildForum is a channel that can only contain threads.
GuildForum
2020-01-02 19:53:08 +00:00
)
2023-01-31 08:13:50 +00:00
// GuildNews aliases to GuildAnnouncement.
//
// Deprecated: use GuildAnnouncement instead.
const GuildNews = GuildAnnouncement
// GuildNewsThread aliases to GuildAnnouncementThread.
//
// Deprecated: use GuildAnnouncementThread instead.
const GuildNewsThread = GuildAnnouncementThread
2020-05-23 16:01:08 +00:00
// https://discord.com/developers/docs/resources/channel#overwrite-object
2020-01-02 19:53:08 +00:00
type Overwrite struct {
2020-05-23 16:01:08 +00:00
// ID is the role or user id.
2020-08-18 00:10:43 +00:00
ID Snowflake ` json:"id" `
2020-10-28 21:49:30 +00:00
// Type indicates the entity overwritten: role or member.
2020-10-28 22:34:14 +00:00
Type OverwriteType ` json:"type" `
2020-05-23 16:01:08 +00:00
// Allow is a permission bit set for granted permissions.
2020-08-18 00:10:43 +00:00
Allow Permissions ` json:"allow,string" `
2020-05-23 16:01:08 +00:00
// Deny is a permission bit set for denied permissions.
2020-08-18 00:10:43 +00:00
Deny Permissions ` json:"deny,string" `
}
2020-10-28 21:49:30 +00:00
// OverwriteType is an enumerated type to indicate the entity being overwritten:
// role or member
2020-10-28 21:08:29 +00:00
type OverwriteType uint8
2020-01-02 19:53:08 +00:00
const (
2020-05-23 16:01:08 +00:00
// OverwriteRole is an overwrite for a role.
2020-10-28 21:08:29 +00:00
OverwriteRole OverwriteType = iota
2020-05-23 16:01:08 +00:00
// OverwriteMember is an overwrite for a member.
2020-10-28 21:08:29 +00:00
OverwriteMember
2020-01-02 19:53:08 +00:00
)
2020-10-29 20:25:03 +00:00
2020-10-30 20:41:04 +00:00
// UnmarshalJSON unmarshalls both a string-quoted number and a regular number
2020-10-29 20:25:03 +00:00
// into OverwriteType. We need to do this because Discord is so bad that they
// can't even handle 1s and 0s properly.
func ( otype * OverwriteType ) UnmarshalJSON ( b [ ] byte ) error {
2021-01-10 19:07:04 +00:00
s := strings . Trim ( string ( b ) , ` " ` )
// It has been observed that discord still uses the "legacy" string
// overwrite types in at least the guild create event.
// Therefore this string check.
switch s {
case "role" :
* otype = OverwriteRole
return nil
case "member" :
* otype = OverwriteMember
return nil
}
2020-10-29 20:25:03 +00:00
2021-01-10 19:07:04 +00:00
u , err := strconv . ParseUint ( s , 10 , 8 )
2020-10-29 20:25:03 +00:00
if err != nil {
return err
}
* otype = OverwriteType ( u )
return nil
}
2021-05-29 18:22:57 +00:00
type VideoQualityMode uint8
// https://discord.com/developers/docs/resources/channel#channel-object-video-quality-modes
const (
AutoVideoQuality VideoQualityMode = iota + 1
FullVideoQuality
)
2021-08-08 20:19:15 +00:00
// ThreadMetadata contains a number of thread-specific channel fields that are
// not needed by other channel types.
//
// https://discord.com/developers/docs/resources/channel#thread-metadata-object
type ThreadMetadata struct {
// Archived specifies whether the thread is archived.
Archived bool ` json:"archived" `
// AutoArchiveDuration is the duration in minutes to automatically archive
// the thread after recent activity.
AutoArchiveDuration ArchiveDuration ` json:"auto_archive_duration" `
// ArchiveTimestamp timestamp when the thread's archive status was last
// changed, used for calculating recent activity.
ArchiveTimestamp Timestamp ` json:"archive_timestamp" `
// Locked specifies whether the thread is locked; when a thread is locked,
// only users with MANAGE_THREADS can unarchive it.
2021-08-17 05:37:33 +00:00
Locked bool ` json:"locked" `
// Invitable specifies whether non-moderators can add other
// non-moderators to a thread; only available on private threads.
Invitable bool ` json:"invitable,omitempty" `
2024-01-02 00:40:31 +00:00
// CreateTimestamp is the timestamp when the thread was created; only
// populated for threads created after 2022-01-09.
CreateTimestamp * Timestamp ` json:"thread_metadata,omitempty" `
2021-08-08 20:19:15 +00:00
}
type ThreadMember struct {
// ID is the id of the thread.
//
// This field will be omitted on the member sent within each thread in the
// guild create event.
ID ChannelID ` json:"id,omitempty" `
// UserID is the id of the user.
//
// This field will be omitted on the member sent within each thread in the
// guild create event.
UserID UserID ` json:"user_id,omitempty" `
// Member is the member, only included in Thread Members Update Events.
Member * Member ` json:"member,omitempty" `
// Presence is the presence, only included in Thread Members Update Events.
Presence * Presence ` json:"presence,omitempty" `
// JoinTimestamp is the time the current user last joined the thread.
JoinTimestamp Timestamp ` json:"join_timestamp" `
// Flags are any user-thread settings.
Flags ThreadMemberFlags ` json:"flags" `
}
// ThreadMemberFlags are the flags of a ThreadMember.
// Currently, none are documented.
type ThreadMemberFlags uint64
2022-09-21 20:17:26 +00:00
// Tag represents a tag that is able to be applied to a thread in a GuildForum
// channel.
type Tag struct {
ID TagID ` json:"id,omitempty" `
Name string ` json:"name" `
Moderated bool ` json:"moderated" `
ForumReaction
}
// ForumReaction is used in several forum-related structures. It is officially
// named the "Default Reaction" object.
type ForumReaction struct {
// EmojiID is set when there is a custom emoji used.
// Only one of EmojiID and EmojiName can be set
EmojiID EmojiID ` json:"emoji_id" `
// EmojiName is set when the emoji is a normal unicode emoji.
// Only one of EmojiID and EmojiName can be set
EmojiName option . String ` json:"emoji_name" `
}
2023-01-31 08:09:20 +00:00
// https://discord.com/developers/docs/resources/channel#channel-object-sort-order-types
type SortOrderType uint8
const (
// Sort forum posts by activity.
SortOrderTypeLatestActivity SortOrderType = iota
// Sort forum posts by creation time (from most recent to oldest)
SoftOrderTypeCreationDate
)
// https://discord.com/developers/docs/resources/channel#channel-object-forum-layout-types
type ForumLayoutType uint8
const (
// No default has been set for forum channel.
ForumLayoutTypeNotSet ForumLayoutType = iota
// Display posts as a list.
ForumLayoutTypeListView
// Display posts as a collection of tiles.
ForumLayoutTypeGalleryView
)