1
0
Fork 0
mirror of https://github.com/diamondburned/arikawa.git synced 2024-09-12 13:16:42 +00:00
arikawa/gateway/commands.go
diamondburned 6ef093eb98 Gateway: Refactor, v8 user struct updates
This commit refactored several structures from package discord to be in
package gateway. Those structures are mostly presence ones, which per
official documentation has a lot more to do with the Gateway API than
the REST API or anything else.

This commit also renamed several global variables to have a more
consistent and obvious name.

As of v8, the user API has had a lot of minor and some major changes,
especially regarding its Ready event API. The most significant change is
the addition of the ReadySupplemental event as well as several changes
to the Ready field itself.

All of these changes above are breaking, and they have already broken
the state package. These breaking changes will be addressed in other
packages by the next commit.
2020-11-28 17:22:03 -08:00

164 lines
4.5 KiB
Go

package gateway
import (
"context"
"github.com/diamondburned/arikawa/v2/discord"
"github.com/pkg/errors"
)
// Rules: VOICE_STATE_UPDATE -> VoiceStateUpdateEvent
// Identify structure is at identify.go
// Identify sends off the Identify command with the Gateway's IdentifyData.
func (g *Gateway) Identify() error {
ctx, cancel := context.WithTimeout(context.Background(), g.WSTimeout)
defer cancel()
return g.IdentifyCtx(ctx)
}
// IdentifyCtx sends off the Identify command with the Gateway's IdentifyData
// with the given context for time out.
func (g *Gateway) IdentifyCtx(ctx context.Context) error {
if err := g.Identifier.Wait(ctx); err != nil {
return errors.Wrap(err, "can't wait for identify()")
}
return g.SendCtx(ctx, IdentifyOP, g.Identifier)
}
type ResumeData struct {
Token string `json:"token"`
SessionID string `json:"session_id"`
Sequence int64 `json:"seq"`
}
// Resume sends to the Websocket a Resume OP, but it doesn't actually resume
// from a dead connection. Start() resumes from a dead connection.
func (g *Gateway) Resume() error {
ctx, cancel := context.WithTimeout(context.Background(), g.WSTimeout)
defer cancel()
return g.ResumeCtx(ctx)
}
// ResumeCtx sends to the Websocket a Resume OP, but it doesn't actually resume
// from a dead connection. Start() resumes from a dead connection.
func (g *Gateway) ResumeCtx(ctx context.Context) error {
var (
ses = g.SessionID
seq = g.Sequence.Get()
)
if ses == "" || seq == 0 {
return ErrMissingForResume
}
return g.SendCtx(ctx, ResumeOP, ResumeData{
Token: g.Identifier.Token,
SessionID: ses,
Sequence: seq,
})
}
// HeartbeatData is the last sequence number to be sent.
type HeartbeatData int
func (g *Gateway) Heartbeat() error {
ctx, cancel := context.WithTimeout(context.Background(), g.WSTimeout)
defer cancel()
return g.HeartbeatCtx(ctx)
}
func (g *Gateway) HeartbeatCtx(ctx context.Context) error {
return g.SendCtx(ctx, HeartbeatOP, g.Sequence.Get())
}
type RequestGuildMembersData struct {
GuildID []discord.GuildID `json:"guild_id"`
UserIDs []discord.UserID `json:"user_ids,omitempty"`
Query string `json:"query"`
Limit uint `json:"limit"`
Presences bool `json:"presences,omitempty"`
Nonce string `json:"nonce,omitempty"`
}
func (g *Gateway) RequestGuildMembers(data RequestGuildMembersData) error {
ctx, cancel := context.WithTimeout(context.Background(), g.WSTimeout)
defer cancel()
return g.RequestGuildMembersCtx(ctx, data)
}
func (g *Gateway) RequestGuildMembersCtx(
ctx context.Context, data RequestGuildMembersData) error {
return g.SendCtx(ctx, RequestGuildMembersOP, data)
}
type UpdateVoiceStateData struct {
GuildID discord.GuildID `json:"guild_id"`
ChannelID discord.ChannelID `json:"channel_id"` // nullable
SelfMute bool `json:"self_mute"`
SelfDeaf bool `json:"self_deaf"`
}
func (g *Gateway) UpdateVoiceState(data UpdateVoiceStateData) error {
ctx, cancel := context.WithTimeout(context.Background(), g.WSTimeout)
defer cancel()
return g.UpdateVoiceStateCtx(ctx, data)
}
func (g *Gateway) UpdateVoiceStateCtx(ctx context.Context, data UpdateVoiceStateData) error {
return g.SendCtx(ctx, VoiceStateUpdateOP, data)
}
// UpdateStatusData is sent by this client to indicate a presence or status
// update.
type UpdateStatusData struct {
Since discord.UnixMsTimestamp `json:"since"` // 0 if not idle
// Activities can either be null, an empty slice, or be omitted.
Activities *[]discord.Activity `json:"activities,omitempty"`
Status Status `json:"status"`
AFK bool `json:"afk"`
}
func (g *Gateway) UpdateStatus(data UpdateStatusData) error {
ctx, cancel := context.WithTimeout(context.Background(), g.WSTimeout)
defer cancel()
return g.UpdateStatusCtx(ctx, data)
}
func (g *Gateway) UpdateStatusCtx(ctx context.Context, data UpdateStatusData) error {
return g.SendCtx(ctx, StatusUpdateOP, data)
}
// Undocumented
type GuildSubscribeData struct {
Typing bool `json:"typing"`
Activities bool `json:"activities"`
GuildID discord.GuildID `json:"guild_id"`
// Channels is not documented. It's used to fetch the right members sidebar.
Channels map[discord.ChannelID][][2]int `json:"channels,omitempty"`
}
func (g *Gateway) GuildSubscribe(data GuildSubscribeData) error {
ctx, cancel := context.WithTimeout(context.Background(), g.WSTimeout)
defer cancel()
return g.GuildSubscribeCtx(ctx, data)
}
func (g *Gateway) GuildSubscribeCtx(ctx context.Context, data GuildSubscribeData) error {
return g.SendCtx(ctx, GuildSubscriptionsOP, data)
}