mirror of
https://github.com/diamondburned/arikawa.git
synced 2024-09-12 13:16:42 +00:00
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.
164 lines
4.5 KiB
Go
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)
|
|
}
|