1// Discordgo - Discord bindings for Go
2// Available at https://github.com/bwmarrin/discordgo
3
4// Copyright 2015-2016 Bruce Marriner <bruce@sqls.net>.  All rights reserved.
5// Use of this source code is governed by a BSD-style
6// license that can be found in the LICENSE file.
7
8// This file contains all structures for the discordgo package.  These
9// may be moved about later into separate files but I find it easier to have
10// them all located together.
11
12package discordgo
13
14import (
15	"encoding/json"
16	"fmt"
17	"net/http"
18	"sync"
19	"time"
20
21	"github.com/gorilla/websocket"
22)
23
24// A Session represents a connection to the Discord API.
25type Session struct {
26	sync.RWMutex
27
28	// General configurable settings.
29
30	// Authentication token for this session
31	Token string
32	MFA   bool
33
34	// Debug for printing JSON request/responses
35	Debug    bool // Deprecated, will be removed.
36	LogLevel int
37
38	// Should the session reconnect the websocket on errors.
39	ShouldReconnectOnError bool
40
41	// Should the session request compressed websocket data.
42	Compress bool
43
44	// Sharding
45	ShardID    int
46	ShardCount int
47
48	// Should state tracking be enabled.
49	// State tracking is the best way for getting the the users
50	// active guilds and the members of the guilds.
51	StateEnabled bool
52
53	// Whether or not to call event handlers synchronously.
54	// e.g false = launch event handlers in their own goroutines.
55	SyncEvents bool
56
57	// Exposed but should not be modified by User.
58
59	// Whether the Data Websocket is ready
60	DataReady bool // NOTE: Maye be deprecated soon
61
62	// Max number of REST API retries
63	MaxRestRetries int
64
65	// Status stores the currect status of the websocket connection
66	// this is being tested, may stay, may go away.
67	status int32
68
69	// Whether the Voice Websocket is ready
70	VoiceReady bool // NOTE: Deprecated.
71
72	// Whether the UDP Connection is ready
73	UDPReady bool // NOTE: Deprecated
74
75	// Stores a mapping of guild id's to VoiceConnections
76	VoiceConnections map[string]*VoiceConnection
77
78	// Managed state object, updated internally with events when
79	// StateEnabled is true.
80	State *State
81
82	// The http client used for REST requests
83	Client *http.Client
84
85	// Stores the last HeartbeatAck that was recieved (in UTC)
86	LastHeartbeatAck time.Time
87
88	// Stores the last Heartbeat sent (in UTC)
89	LastHeartbeatSent time.Time
90
91	// used to deal with rate limits
92	Ratelimiter *RateLimiter
93
94	// Event handlers
95	handlersMu   sync.RWMutex
96	handlers     map[string][]*eventHandlerInstance
97	onceHandlers map[string][]*eventHandlerInstance
98
99	// The websocket connection.
100	wsConn *websocket.Conn
101
102	// When nil, the session is not listening.
103	listening chan interface{}
104
105	// sequence tracks the current gateway api websocket sequence number
106	sequence *int64
107
108	// stores sessions current Discord Gateway
109	gateway string
110
111	// stores session ID of current Gateway connection
112	sessionID string
113
114	// used to make sure gateway websocket writes do not happen concurrently
115	wsMutex sync.Mutex
116}
117
118// UserConnection is a Connection returned from the UserConnections endpoint
119type UserConnection struct {
120	ID           string         `json:"id"`
121	Name         string         `json:"name"`
122	Type         string         `json:"type"`
123	Revoked      bool           `json:"revoked"`
124	Integrations []*Integration `json:"integrations"`
125}
126
127// Integration stores integration information
128type Integration struct {
129	ID                string             `json:"id"`
130	Name              string             `json:"name"`
131	Type              string             `json:"type"`
132	Enabled           bool               `json:"enabled"`
133	Syncing           bool               `json:"syncing"`
134	RoleID            string             `json:"role_id"`
135	ExpireBehavior    int                `json:"expire_behavior"`
136	ExpireGracePeriod int                `json:"expire_grace_period"`
137	User              *User              `json:"user"`
138	Account           IntegrationAccount `json:"account"`
139	SyncedAt          Timestamp          `json:"synced_at"`
140}
141
142// IntegrationAccount is integration account information
143// sent by the UserConnections endpoint
144type IntegrationAccount struct {
145	ID   string `json:"id"`
146	Name string `json:"name"`
147}
148
149// A VoiceRegion stores data for a specific voice region server.
150type VoiceRegion struct {
151	ID       string `json:"id"`
152	Name     string `json:"name"`
153	Hostname string `json:"sample_hostname"`
154	Port     int    `json:"sample_port"`
155}
156
157// A VoiceICE stores data for voice ICE servers.
158type VoiceICE struct {
159	TTL     string       `json:"ttl"`
160	Servers []*ICEServer `json:"servers"`
161}
162
163// A ICEServer stores data for a specific voice ICE server.
164type ICEServer struct {
165	URL        string `json:"url"`
166	Username   string `json:"username"`
167	Credential string `json:"credential"`
168}
169
170// A Invite stores all data related to a specific Discord Guild or Channel invite.
171type Invite struct {
172	Guild     *Guild    `json:"guild"`
173	Channel   *Channel  `json:"channel"`
174	Inviter   *User     `json:"inviter"`
175	Code      string    `json:"code"`
176	CreatedAt Timestamp `json:"created_at"`
177	MaxAge    int       `json:"max_age"`
178	Uses      int       `json:"uses"`
179	MaxUses   int       `json:"max_uses"`
180	Revoked   bool      `json:"revoked"`
181	Temporary bool      `json:"temporary"`
182	Unique    bool      `json:"unique"`
183
184	// will only be filled when using InviteWithCounts
185	ApproximatePresenceCount int `json:"approximate_presence_count"`
186	ApproximateMemberCount   int `json:"approximate_member_count"`
187}
188
189// ChannelType is the type of a Channel
190type ChannelType int
191
192// Block contains known ChannelType values
193const (
194	ChannelTypeGuildText ChannelType = iota
195	ChannelTypeDM
196	ChannelTypeGuildVoice
197	ChannelTypeGroupDM
198	ChannelTypeGuildCategory
199)
200
201// A Channel holds all data related to an individual Discord channel.
202type Channel struct {
203	// The ID of the channel.
204	ID string `json:"id"`
205
206	// The ID of the guild to which the channel belongs, if it is in a guild.
207	// Else, this ID is empty (e.g. DM channels).
208	GuildID string `json:"guild_id"`
209
210	// The name of the channel.
211	Name string `json:"name"`
212
213	// The topic of the channel.
214	Topic string `json:"topic"`
215
216	// The type of the channel.
217	Type ChannelType `json:"type"`
218
219	// The ID of the last message sent in the channel. This is not
220	// guaranteed to be an ID of a valid message.
221	LastMessageID string `json:"last_message_id"`
222
223	// Whether the channel is marked as NSFW.
224	NSFW bool `json:"nsfw"`
225
226	// Icon of the group DM channel.
227	Icon string `json:"icon"`
228
229	// The position of the channel, used for sorting in client.
230	Position int `json:"position"`
231
232	// The bitrate of the channel, if it is a voice channel.
233	Bitrate int `json:"bitrate"`
234
235	// The recipients of the channel. This is only populated in DM channels.
236	Recipients []*User `json:"recipients"`
237
238	// The messages in the channel. This is only present in state-cached channels,
239	// and State.MaxMessageCount must be non-zero.
240	Messages []*Message `json:"-"`
241
242	// A list of permission overwrites present for the channel.
243	PermissionOverwrites []*PermissionOverwrite `json:"permission_overwrites"`
244
245	// The user limit of the voice channel.
246	UserLimit int `json:"user_limit"`
247
248	// The ID of the parent channel, if the channel is under a category
249	ParentID string `json:"parent_id"`
250}
251
252// Mention returns a string which mentions the channel
253func (c *Channel) Mention() string {
254	return fmt.Sprintf("<#%s>", c.ID)
255}
256
257// A ChannelEdit holds Channel Field data for a channel edit.
258type ChannelEdit struct {
259	Name                 string                 `json:"name,omitempty"`
260	Topic                string                 `json:"topic,omitempty"`
261	NSFW                 bool                   `json:"nsfw,omitempty"`
262	Position             int                    `json:"position"`
263	Bitrate              int                    `json:"bitrate,omitempty"`
264	UserLimit            int                    `json:"user_limit,omitempty"`
265	PermissionOverwrites []*PermissionOverwrite `json:"permission_overwrites,omitempty"`
266	ParentID             string                 `json:"parent_id,omitempty"`
267	RateLimitPerUser     int                    `json:"rate_limit_per_user,omitempty"`
268}
269
270// A PermissionOverwrite holds permission overwrite data for a Channel
271type PermissionOverwrite struct {
272	ID    string `json:"id"`
273	Type  string `json:"type"`
274	Deny  int    `json:"deny"`
275	Allow int    `json:"allow"`
276}
277
278// Emoji struct holds data related to Emoji's
279type Emoji struct {
280	ID            string   `json:"id"`
281	Name          string   `json:"name"`
282	Roles         []string `json:"roles"`
283	Managed       bool     `json:"managed"`
284	RequireColons bool     `json:"require_colons"`
285	Animated      bool     `json:"animated"`
286}
287
288// MessageFormat returns a correctly formatted Emoji for use in Message content and embeds
289func (e *Emoji) MessageFormat() string {
290	if e.ID != "" && e.Name != "" {
291		if e.Animated {
292			return "<a:" + e.APIName() + ">"
293		}
294
295		return "<:" + e.APIName() + ">"
296	}
297
298	return e.APIName()
299}
300
301// APIName returns an correctly formatted API name for use in the MessageReactions endpoints.
302func (e *Emoji) APIName() string {
303	if e.ID != "" && e.Name != "" {
304		return e.Name + ":" + e.ID
305	}
306	if e.Name != "" {
307		return e.Name
308	}
309	return e.ID
310}
311
312// VerificationLevel type definition
313type VerificationLevel int
314
315// Constants for VerificationLevel levels from 0 to 3 inclusive
316const (
317	VerificationLevelNone VerificationLevel = iota
318	VerificationLevelLow
319	VerificationLevelMedium
320	VerificationLevelHigh
321)
322
323// ExplicitContentFilterLevel type definition
324type ExplicitContentFilterLevel int
325
326// Constants for ExplicitContentFilterLevel levels from 0 to 2 inclusive
327const (
328	ExplicitContentFilterDisabled ExplicitContentFilterLevel = iota
329	ExplicitContentFilterMembersWithoutRoles
330	ExplicitContentFilterAllMembers
331)
332
333// MfaLevel type definition
334type MfaLevel int
335
336// Constants for MfaLevel levels from 0 to 1 inclusive
337const (
338	MfaLevelNone MfaLevel = iota
339	MfaLevelElevated
340)
341
342// A Guild holds all data related to a specific Discord Guild.  Guilds are also
343// sometimes referred to as Servers in the Discord client.
344type Guild struct {
345	// The ID of the guild.
346	ID string `json:"id"`
347
348	// The name of the guild. (2–100 characters)
349	Name string `json:"name"`
350
351	// The hash of the guild's icon. Use Session.GuildIcon
352	// to retrieve the icon itself.
353	Icon string `json:"icon"`
354
355	// The voice region of the guild.
356	Region string `json:"region"`
357
358	// The ID of the AFK voice channel.
359	AfkChannelID string `json:"afk_channel_id"`
360
361	// The ID of the embed channel ID, used for embed widgets.
362	EmbedChannelID string `json:"embed_channel_id"`
363
364	// The user ID of the owner of the guild.
365	OwnerID string `json:"owner_id"`
366
367	// The time at which the current user joined the guild.
368	// This field is only present in GUILD_CREATE events and websocket
369	// update events, and thus is only present in state-cached guilds.
370	JoinedAt Timestamp `json:"joined_at"`
371
372	// The hash of the guild's splash.
373	Splash string `json:"splash"`
374
375	// The timeout, in seconds, before a user is considered AFK in voice.
376	AfkTimeout int `json:"afk_timeout"`
377
378	// The number of members in the guild.
379	// This field is only present in GUILD_CREATE events and websocket
380	// update events, and thus is only present in state-cached guilds.
381	MemberCount int `json:"member_count"`
382
383	// The verification level required for the guild.
384	VerificationLevel VerificationLevel `json:"verification_level"`
385
386	// Whether the guild has embedding enabled.
387	EmbedEnabled bool `json:"embed_enabled"`
388
389	// Whether the guild is considered large. This is
390	// determined by a member threshold in the identify packet,
391	// and is currently hard-coded at 250 members in the library.
392	Large bool `json:"large"`
393
394	// The default message notification setting for the guild.
395	// 0 == all messages, 1 == mentions only.
396	DefaultMessageNotifications int `json:"default_message_notifications"`
397
398	// A list of roles in the guild.
399	Roles []*Role `json:"roles"`
400
401	// A list of the custom emojis present in the guild.
402	Emojis []*Emoji `json:"emojis"`
403
404	// A list of the members in the guild.
405	// This field is only present in GUILD_CREATE events and websocket
406	// update events, and thus is only present in state-cached guilds.
407	Members []*Member `json:"members"`
408
409	// A list of partial presence objects for members in the guild.
410	// This field is only present in GUILD_CREATE events and websocket
411	// update events, and thus is only present in state-cached guilds.
412	Presences []*Presence `json:"presences"`
413
414	// A list of channels in the guild.
415	// This field is only present in GUILD_CREATE events and websocket
416	// update events, and thus is only present in state-cached guilds.
417	Channels []*Channel `json:"channels"`
418
419	// A list of voice states for the guild.
420	// This field is only present in GUILD_CREATE events and websocket
421	// update events, and thus is only present in state-cached guilds.
422	VoiceStates []*VoiceState `json:"voice_states"`
423
424	// Whether this guild is currently unavailable (most likely due to outage).
425	// This field is only present in GUILD_CREATE events and websocket
426	// update events, and thus is only present in state-cached guilds.
427	Unavailable bool `json:"unavailable"`
428
429	// The explicit content filter level
430	ExplicitContentFilter ExplicitContentFilterLevel `json:"explicit_content_filter"`
431
432	// The list of enabled guild features
433	Features []string `json:"features"`
434
435	// Required MFA level for the guild
436	MfaLevel MfaLevel `json:"mfa_level"`
437
438	// Whether or not the Server Widget is enabled
439	WidgetEnabled bool `json:"widget_enabled"`
440
441	// The Channel ID for the Server Widget
442	WidgetChannelID string `json:"widget_channel_id"`
443
444	// The Channel ID to which system messages are sent (eg join and leave messages)
445	SystemChannelID string `json:"system_channel_id"`
446}
447
448// A UserGuild holds a brief version of a Guild
449type UserGuild struct {
450	ID          string `json:"id"`
451	Name        string `json:"name"`
452	Icon        string `json:"icon"`
453	Owner       bool   `json:"owner"`
454	Permissions int    `json:"permissions"`
455}
456
457// A GuildParams stores all the data needed to update discord guild settings
458type GuildParams struct {
459	Name                        string             `json:"name,omitempty"`
460	Region                      string             `json:"region,omitempty"`
461	VerificationLevel           *VerificationLevel `json:"verification_level,omitempty"`
462	DefaultMessageNotifications int                `json:"default_message_notifications,omitempty"` // TODO: Separate type?
463	AfkChannelID                string             `json:"afk_channel_id,omitempty"`
464	AfkTimeout                  int                `json:"afk_timeout,omitempty"`
465	Icon                        string             `json:"icon,omitempty"`
466	OwnerID                     string             `json:"owner_id,omitempty"`
467	Splash                      string             `json:"splash,omitempty"`
468}
469
470// A Role stores information about Discord guild member roles.
471type Role struct {
472	// The ID of the role.
473	ID string `json:"id"`
474
475	// The name of the role.
476	Name string `json:"name"`
477
478	// Whether this role is managed by an integration, and
479	// thus cannot be manually added to, or taken from, members.
480	Managed bool `json:"managed"`
481
482	// Whether this role is mentionable.
483	Mentionable bool `json:"mentionable"`
484
485	// Whether this role is hoisted (shows up separately in member list).
486	Hoist bool `json:"hoist"`
487
488	// The hex color of this role.
489	Color int `json:"color"`
490
491	// The position of this role in the guild's role hierarchy.
492	Position int `json:"position"`
493
494	// The permissions of the role on the guild (doesn't include channel overrides).
495	// This is a combination of bit masks; the presence of a certain permission can
496	// be checked by performing a bitwise AND between this int and the permission.
497	Permissions int `json:"permissions"`
498}
499
500// Mention returns a string which mentions the role
501func (r *Role) Mention() string {
502	return fmt.Sprintf("<@&%s>", r.ID)
503}
504
505// Roles are a collection of Role
506type Roles []*Role
507
508func (r Roles) Len() int {
509	return len(r)
510}
511
512func (r Roles) Less(i, j int) bool {
513	return r[i].Position > r[j].Position
514}
515
516func (r Roles) Swap(i, j int) {
517	r[i], r[j] = r[j], r[i]
518}
519
520// A VoiceState stores the voice states of Guilds
521type VoiceState struct {
522	UserID    string `json:"user_id"`
523	SessionID string `json:"session_id"`
524	ChannelID string `json:"channel_id"`
525	GuildID   string `json:"guild_id"`
526	Suppress  bool   `json:"suppress"`
527	SelfMute  bool   `json:"self_mute"`
528	SelfDeaf  bool   `json:"self_deaf"`
529	Mute      bool   `json:"mute"`
530	Deaf      bool   `json:"deaf"`
531}
532
533// A Presence stores the online, offline, or idle and game status of Guild members.
534type Presence struct {
535	User   *User    `json:"user"`
536	Status Status   `json:"status"`
537	Game   *Game    `json:"game"`
538	Nick   string   `json:"nick"`
539	Roles  []string `json:"roles"`
540	Since  *int     `json:"since"`
541}
542
543// GameType is the type of "game" (see GameType* consts) in the Game struct
544type GameType int
545
546// Valid GameType values
547const (
548	GameTypeGame GameType = iota
549	GameTypeStreaming
550	GameTypeListening
551	GameTypeWatching
552)
553
554// A Game struct holds the name of the "playing .." game for a user
555type Game struct {
556	Name          string     `json:"name"`
557	Type          GameType   `json:"type"`
558	URL           string     `json:"url,omitempty"`
559	Details       string     `json:"details,omitempty"`
560	State         string     `json:"state,omitempty"`
561	TimeStamps    TimeStamps `json:"timestamps,omitempty"`
562	Assets        Assets     `json:"assets,omitempty"`
563	ApplicationID string     `json:"application_id,omitempty"`
564	Instance      int8       `json:"instance,omitempty"`
565	// TODO: Party and Secrets (unknown structure)
566}
567
568// A TimeStamps struct contains start and end times used in the rich presence "playing .." Game
569type TimeStamps struct {
570	EndTimestamp   int64 `json:"end,omitempty"`
571	StartTimestamp int64 `json:"start,omitempty"`
572}
573
574// UnmarshalJSON unmarshals JSON into TimeStamps struct
575func (t *TimeStamps) UnmarshalJSON(b []byte) error {
576	temp := struct {
577		End   float64 `json:"end,omitempty"`
578		Start float64 `json:"start,omitempty"`
579	}{}
580	err := json.Unmarshal(b, &temp)
581	if err != nil {
582		return err
583	}
584	t.EndTimestamp = int64(temp.End)
585	t.StartTimestamp = int64(temp.Start)
586	return nil
587}
588
589// An Assets struct contains assets and labels used in the rich presence "playing .." Game
590type Assets struct {
591	LargeImageID string `json:"large_image,omitempty"`
592	SmallImageID string `json:"small_image,omitempty"`
593	LargeText    string `json:"large_text,omitempty"`
594	SmallText    string `json:"small_text,omitempty"`
595}
596
597// A Member stores user information for Guild members. A guild
598// member represents a certain user's presence in a guild.
599type Member struct {
600	// The guild ID on which the member exists.
601	GuildID string `json:"guild_id"`
602
603	// The time at which the member joined the guild, in ISO8601.
604	JoinedAt Timestamp `json:"joined_at"`
605
606	// The nickname of the member, if they have one.
607	Nick string `json:"nick"`
608
609	// Whether the member is deafened at a guild level.
610	Deaf bool `json:"deaf"`
611
612	// Whether the member is muted at a guild level.
613	Mute bool `json:"mute"`
614
615	// The underlying user on which the member is based.
616	User *User `json:"user"`
617
618	// A list of IDs of the roles which are possessed by the member.
619	Roles []string `json:"roles"`
620}
621
622// Mention creates a member mention
623func (m *Member) Mention() string {
624	return "<@!" + m.User.ID + ">"
625}
626
627// A Settings stores data for a specific users Discord client settings.
628type Settings struct {
629	RenderEmbeds           bool               `json:"render_embeds"`
630	InlineEmbedMedia       bool               `json:"inline_embed_media"`
631	InlineAttachmentMedia  bool               `json:"inline_attachment_media"`
632	EnableTtsCommand       bool               `json:"enable_tts_command"`
633	MessageDisplayCompact  bool               `json:"message_display_compact"`
634	ShowCurrentGame        bool               `json:"show_current_game"`
635	ConvertEmoticons       bool               `json:"convert_emoticons"`
636	Locale                 string             `json:"locale"`
637	Theme                  string             `json:"theme"`
638	GuildPositions         []string           `json:"guild_positions"`
639	RestrictedGuilds       []string           `json:"restricted_guilds"`
640	FriendSourceFlags      *FriendSourceFlags `json:"friend_source_flags"`
641	Status                 Status             `json:"status"`
642	DetectPlatformAccounts bool               `json:"detect_platform_accounts"`
643	DeveloperMode          bool               `json:"developer_mode"`
644}
645
646// Status type definition
647type Status string
648
649// Constants for Status with the different current available status
650const (
651	StatusOnline       Status = "online"
652	StatusIdle         Status = "idle"
653	StatusDoNotDisturb Status = "dnd"
654	StatusInvisible    Status = "invisible"
655	StatusOffline      Status = "offline"
656)
657
658// FriendSourceFlags stores ... TODO :)
659type FriendSourceFlags struct {
660	All           bool `json:"all"`
661	MutualGuilds  bool `json:"mutual_guilds"`
662	MutualFriends bool `json:"mutual_friends"`
663}
664
665// A Relationship between the logged in user and Relationship.User
666type Relationship struct {
667	User *User  `json:"user"`
668	Type int    `json:"type"` // 1 = friend, 2 = blocked, 3 = incoming friend req, 4 = sent friend req
669	ID   string `json:"id"`
670}
671
672// A TooManyRequests struct holds information received from Discord
673// when receiving a HTTP 429 response.
674type TooManyRequests struct {
675	Bucket     string        `json:"bucket"`
676	Message    string        `json:"message"`
677	RetryAfter time.Duration `json:"retry_after"`
678}
679
680// A ReadState stores data on the read state of channels.
681type ReadState struct {
682	MentionCount  int    `json:"mention_count"`
683	LastMessageID string `json:"last_message_id"`
684	ID            string `json:"id"`
685}
686
687// An Ack is used to ack messages
688type Ack struct {
689	Token string `json:"token"`
690}
691
692// A GuildRole stores data for guild roles.
693type GuildRole struct {
694	Role    *Role  `json:"role"`
695	GuildID string `json:"guild_id"`
696}
697
698// A GuildBan stores data for a guild ban.
699type GuildBan struct {
700	Reason string `json:"reason"`
701	User   *User  `json:"user"`
702}
703
704// A GuildEmbed stores data for a guild embed.
705type GuildEmbed struct {
706	Enabled   bool   `json:"enabled"`
707	ChannelID string `json:"channel_id"`
708}
709
710// A GuildAuditLog stores data for a guild audit log.
711type GuildAuditLog struct {
712	Webhooks []struct {
713		ChannelID string `json:"channel_id"`
714		GuildID   string `json:"guild_id"`
715		ID        string `json:"id"`
716		Avatar    string `json:"avatar"`
717		Name      string `json:"name"`
718	} `json:"webhooks,omitempty"`
719	Users []struct {
720		Username      string `json:"username"`
721		Discriminator string `json:"discriminator"`
722		Bot           bool   `json:"bot"`
723		ID            string `json:"id"`
724		Avatar        string `json:"avatar"`
725	} `json:"users,omitempty"`
726	AuditLogEntries []struct {
727		TargetID string `json:"target_id"`
728		Changes  []struct {
729			NewValue interface{} `json:"new_value"`
730			OldValue interface{} `json:"old_value"`
731			Key      string      `json:"key"`
732		} `json:"changes,omitempty"`
733		UserID     string `json:"user_id"`
734		ID         string `json:"id"`
735		ActionType int    `json:"action_type"`
736		Options    struct {
737			DeleteMembersDay string `json:"delete_member_days"`
738			MembersRemoved   string `json:"members_removed"`
739			ChannelID        string `json:"channel_id"`
740			Count            string `json:"count"`
741			ID               string `json:"id"`
742			Type             string `json:"type"`
743			RoleName         string `json:"role_name"`
744		} `json:"options,omitempty"`
745		Reason string `json:"reason"`
746	} `json:"audit_log_entries"`
747}
748
749// Block contains Discord Audit Log Action Types
750const (
751	AuditLogActionGuildUpdate = 1
752
753	AuditLogActionChannelCreate          = 10
754	AuditLogActionChannelUpdate          = 11
755	AuditLogActionChannelDelete          = 12
756	AuditLogActionChannelOverwriteCreate = 13
757	AuditLogActionChannelOverwriteUpdate = 14
758	AuditLogActionChannelOverwriteDelete = 15
759
760	AuditLogActionMemberKick       = 20
761	AuditLogActionMemberPrune      = 21
762	AuditLogActionMemberBanAdd     = 22
763	AuditLogActionMemberBanRemove  = 23
764	AuditLogActionMemberUpdate     = 24
765	AuditLogActionMemberRoleUpdate = 25
766
767	AuditLogActionRoleCreate = 30
768	AuditLogActionRoleUpdate = 31
769	AuditLogActionRoleDelete = 32
770
771	AuditLogActionInviteCreate = 40
772	AuditLogActionInviteUpdate = 41
773	AuditLogActionInviteDelete = 42
774
775	AuditLogActionWebhookCreate = 50
776	AuditLogActionWebhookUpdate = 51
777	AuditLogActionWebhookDelete = 52
778
779	AuditLogActionEmojiCreate = 60
780	AuditLogActionEmojiUpdate = 61
781	AuditLogActionEmojiDelete = 62
782
783	AuditLogActionMessageDelete = 72
784)
785
786// A UserGuildSettingsChannelOverride stores data for a channel override for a users guild settings.
787type UserGuildSettingsChannelOverride struct {
788	Muted                bool   `json:"muted"`
789	MessageNotifications int    `json:"message_notifications"`
790	ChannelID            string `json:"channel_id"`
791}
792
793// A UserGuildSettings stores data for a users guild settings.
794type UserGuildSettings struct {
795	SupressEveryone      bool                                `json:"suppress_everyone"`
796	Muted                bool                                `json:"muted"`
797	MobilePush           bool                                `json:"mobile_push"`
798	MessageNotifications int                                 `json:"message_notifications"`
799	GuildID              string                              `json:"guild_id"`
800	ChannelOverrides     []*UserGuildSettingsChannelOverride `json:"channel_overrides"`
801}
802
803// A UserGuildSettingsEdit stores data for editing UserGuildSettings
804type UserGuildSettingsEdit struct {
805	SupressEveryone      bool                                         `json:"suppress_everyone"`
806	Muted                bool                                         `json:"muted"`
807	MobilePush           bool                                         `json:"mobile_push"`
808	MessageNotifications int                                          `json:"message_notifications"`
809	ChannelOverrides     map[string]*UserGuildSettingsChannelOverride `json:"channel_overrides"`
810}
811
812// An APIErrorMessage is an api error message returned from discord
813type APIErrorMessage struct {
814	Code    int    `json:"code"`
815	Message string `json:"message"`
816}
817
818// Webhook stores the data for a webhook.
819type Webhook struct {
820	ID        string `json:"id"`
821	GuildID   string `json:"guild_id"`
822	ChannelID string `json:"channel_id"`
823	User      *User  `json:"user"`
824	Name      string `json:"name"`
825	Avatar    string `json:"avatar"`
826	Token     string `json:"token"`
827}
828
829// WebhookParams is a struct for webhook params, used in the WebhookExecute command.
830type WebhookParams struct {
831	Content   string          `json:"content,omitempty"`
832	Username  string          `json:"username,omitempty"`
833	AvatarURL string          `json:"avatar_url,omitempty"`
834	TTS       bool            `json:"tts,omitempty"`
835	File      string          `json:"file,omitempty"`
836	Embeds    []*MessageEmbed `json:"embeds,omitempty"`
837}
838
839// MessageReaction stores the data for a message reaction.
840type MessageReaction struct {
841	UserID    string `json:"user_id"`
842	MessageID string `json:"message_id"`
843	Emoji     Emoji  `json:"emoji"`
844	ChannelID string `json:"channel_id"`
845	GuildID   string `json:"guild_id,omitempty"`
846}
847
848// GatewayBotResponse stores the data for the gateway/bot response
849type GatewayBotResponse struct {
850	URL    string `json:"url"`
851	Shards int    `json:"shards"`
852}
853
854// Constants for the different bit offsets of text channel permissions
855const (
856	PermissionReadMessages = 1 << (iota + 10)
857	PermissionSendMessages
858	PermissionSendTTSMessages
859	PermissionManageMessages
860	PermissionEmbedLinks
861	PermissionAttachFiles
862	PermissionReadMessageHistory
863	PermissionMentionEveryone
864	PermissionUseExternalEmojis
865)
866
867// Constants for the different bit offsets of voice permissions
868const (
869	PermissionVoiceConnect = 1 << (iota + 20)
870	PermissionVoiceSpeak
871	PermissionVoiceMuteMembers
872	PermissionVoiceDeafenMembers
873	PermissionVoiceMoveMembers
874	PermissionVoiceUseVAD
875)
876
877// Constants for general management.
878const (
879	PermissionChangeNickname = 1 << (iota + 26)
880	PermissionManageNicknames
881	PermissionManageRoles
882	PermissionManageWebhooks
883	PermissionManageEmojis
884)
885
886// Constants for the different bit offsets of general permissions
887const (
888	PermissionCreateInstantInvite = 1 << iota
889	PermissionKickMembers
890	PermissionBanMembers
891	PermissionAdministrator
892	PermissionManageChannels
893	PermissionManageServer
894	PermissionAddReactions
895	PermissionViewAuditLogs
896
897	PermissionAllText = PermissionReadMessages |
898		PermissionSendMessages |
899		PermissionSendTTSMessages |
900		PermissionManageMessages |
901		PermissionEmbedLinks |
902		PermissionAttachFiles |
903		PermissionReadMessageHistory |
904		PermissionMentionEveryone
905	PermissionAllVoice = PermissionVoiceConnect |
906		PermissionVoiceSpeak |
907		PermissionVoiceMuteMembers |
908		PermissionVoiceDeafenMembers |
909		PermissionVoiceMoveMembers |
910		PermissionVoiceUseVAD
911	PermissionAllChannel = PermissionAllText |
912		PermissionAllVoice |
913		PermissionCreateInstantInvite |
914		PermissionManageRoles |
915		PermissionManageChannels |
916		PermissionAddReactions |
917		PermissionViewAuditLogs
918	PermissionAll = PermissionAllChannel |
919		PermissionKickMembers |
920		PermissionBanMembers |
921		PermissionManageServer |
922		PermissionAdministrator |
923		PermissionManageWebhooks |
924		PermissionManageEmojis
925)
926
927// Block contains Discord JSON Error Response codes
928const (
929	ErrCodeUnknownAccount     = 10001
930	ErrCodeUnknownApplication = 10002
931	ErrCodeUnknownChannel     = 10003
932	ErrCodeUnknownGuild       = 10004
933	ErrCodeUnknownIntegration = 10005
934	ErrCodeUnknownInvite      = 10006
935	ErrCodeUnknownMember      = 10007
936	ErrCodeUnknownMessage     = 10008
937	ErrCodeUnknownOverwrite   = 10009
938	ErrCodeUnknownProvider    = 10010
939	ErrCodeUnknownRole        = 10011
940	ErrCodeUnknownToken       = 10012
941	ErrCodeUnknownUser        = 10013
942	ErrCodeUnknownEmoji       = 10014
943	ErrCodeUnknownWebhook     = 10015
944
945	ErrCodeBotsCannotUseEndpoint  = 20001
946	ErrCodeOnlyBotsCanUseEndpoint = 20002
947
948	ErrCodeMaximumGuildsReached     = 30001
949	ErrCodeMaximumFriendsReached    = 30002
950	ErrCodeMaximumPinsReached       = 30003
951	ErrCodeMaximumGuildRolesReached = 30005
952	ErrCodeTooManyReactions         = 30010
953
954	ErrCodeUnauthorized = 40001
955
956	ErrCodeMissingAccess                             = 50001
957	ErrCodeInvalidAccountType                        = 50002
958	ErrCodeCannotExecuteActionOnDMChannel            = 50003
959	ErrCodeEmbedCisabled                             = 50004
960	ErrCodeCannotEditFromAnotherUser                 = 50005
961	ErrCodeCannotSendEmptyMessage                    = 50006
962	ErrCodeCannotSendMessagesToThisUser              = 50007
963	ErrCodeCannotSendMessagesInVoiceChannel          = 50008
964	ErrCodeChannelVerificationLevelTooHigh           = 50009
965	ErrCodeOAuth2ApplicationDoesNotHaveBot           = 50010
966	ErrCodeOAuth2ApplicationLimitReached             = 50011
967	ErrCodeInvalidOAuthState                         = 50012
968	ErrCodeMissingPermissions                        = 50013
969	ErrCodeInvalidAuthenticationToken                = 50014
970	ErrCodeNoteTooLong                               = 50015
971	ErrCodeTooFewOrTooManyMessagesToDelete           = 50016
972	ErrCodeCanOnlyPinMessageToOriginatingChannel     = 50019
973	ErrCodeCannotExecuteActionOnSystemMessage        = 50021
974	ErrCodeMessageProvidedTooOldForBulkDelete        = 50034
975	ErrCodeInvalidFormBody                           = 50035
976	ErrCodeInviteAcceptedToGuildApplicationsBotNotIn = 50036
977
978	ErrCodeReactionBlocked = 90001
979)
980