github.com/diamondburned/arikawa/v2@v2.1.0/gateway/commands.go (about)

     1  package gateway
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/diamondburned/arikawa/v2/discord"
     7  	"github.com/pkg/errors"
     8  )
     9  
    10  // Rules: VOICE_STATE_UPDATE -> VoiceStateUpdateEvent
    11  
    12  // Identify structure is at identify.go
    13  
    14  // Identify sends off the Identify command with the Gateway's IdentifyData.
    15  func (g *Gateway) Identify() error {
    16  	ctx, cancel := context.WithTimeout(context.Background(), g.WSTimeout)
    17  	defer cancel()
    18  
    19  	return g.IdentifyCtx(ctx)
    20  }
    21  
    22  // IdentifyCtx sends off the Identify command with the Gateway's IdentifyData
    23  // with the given context for time out.
    24  func (g *Gateway) IdentifyCtx(ctx context.Context) error {
    25  	if err := g.Identifier.Wait(ctx); err != nil {
    26  		return errors.Wrap(err, "can't wait for identify()")
    27  	}
    28  
    29  	return g.SendCtx(ctx, IdentifyOP, g.Identifier)
    30  }
    31  
    32  type ResumeData struct {
    33  	Token     string `json:"token"`
    34  	SessionID string `json:"session_id"`
    35  	Sequence  int64  `json:"seq"`
    36  }
    37  
    38  // Resume sends to the Websocket a Resume OP, but it doesn't actually resume
    39  // from a dead connection. Start() resumes from a dead connection.
    40  func (g *Gateway) Resume() error {
    41  	ctx, cancel := context.WithTimeout(context.Background(), g.WSTimeout)
    42  	defer cancel()
    43  
    44  	return g.ResumeCtx(ctx)
    45  }
    46  
    47  // ResumeCtx sends to the Websocket a Resume OP, but it doesn't actually resume
    48  // from a dead connection. Start() resumes from a dead connection.
    49  func (g *Gateway) ResumeCtx(ctx context.Context) error {
    50  	var (
    51  		ses = g.SessionID()
    52  		seq = g.Sequence.Get()
    53  	)
    54  
    55  	if ses == "" || seq == 0 {
    56  		return ErrMissingForResume
    57  	}
    58  
    59  	return g.SendCtx(ctx, ResumeOP, ResumeData{
    60  		Token:     g.Identifier.Token,
    61  		SessionID: ses,
    62  		Sequence:  seq,
    63  	})
    64  }
    65  
    66  // HeartbeatData is the last sequence number to be sent.
    67  type HeartbeatData int
    68  
    69  func (g *Gateway) Heartbeat() error {
    70  	ctx, cancel := context.WithTimeout(context.Background(), g.WSTimeout)
    71  	defer cancel()
    72  
    73  	return g.HeartbeatCtx(ctx)
    74  }
    75  
    76  func (g *Gateway) HeartbeatCtx(ctx context.Context) error {
    77  	return g.SendCtx(ctx, HeartbeatOP, g.Sequence.Get())
    78  }
    79  
    80  type RequestGuildMembersData struct {
    81  	GuildID []discord.GuildID `json:"guild_id"`
    82  	UserIDs []discord.UserID  `json:"user_ids,omitempty"`
    83  
    84  	Query     string `json:"query"`
    85  	Limit     uint   `json:"limit"`
    86  	Presences bool   `json:"presences,omitempty"`
    87  	Nonce     string `json:"nonce,omitempty"`
    88  }
    89  
    90  func (g *Gateway) RequestGuildMembers(data RequestGuildMembersData) error {
    91  	ctx, cancel := context.WithTimeout(context.Background(), g.WSTimeout)
    92  	defer cancel()
    93  
    94  	return g.RequestGuildMembersCtx(ctx, data)
    95  }
    96  
    97  func (g *Gateway) RequestGuildMembersCtx(
    98  	ctx context.Context, data RequestGuildMembersData) error {
    99  
   100  	return g.SendCtx(ctx, RequestGuildMembersOP, data)
   101  }
   102  
   103  type UpdateVoiceStateData struct {
   104  	GuildID   discord.GuildID   `json:"guild_id"`
   105  	ChannelID discord.ChannelID `json:"channel_id"` // nullable
   106  	SelfMute  bool              `json:"self_mute"`
   107  	SelfDeaf  bool              `json:"self_deaf"`
   108  }
   109  
   110  func (g *Gateway) UpdateVoiceState(data UpdateVoiceStateData) error {
   111  	ctx, cancel := context.WithTimeout(context.Background(), g.WSTimeout)
   112  	defer cancel()
   113  
   114  	return g.UpdateVoiceStateCtx(ctx, data)
   115  }
   116  
   117  func (g *Gateway) UpdateVoiceStateCtx(ctx context.Context, data UpdateVoiceStateData) error {
   118  	return g.SendCtx(ctx, VoiceStateUpdateOP, data)
   119  }
   120  
   121  // UpdateStatusData is sent by this client to indicate a presence or status
   122  // update.
   123  type UpdateStatusData struct {
   124  	Since discord.UnixMsTimestamp `json:"since"` // 0 if not idle
   125  
   126  	// Activities can be null or an empty slice.
   127  	Activities []discord.Activity `json:"activities"`
   128  
   129  	Status Status `json:"status"`
   130  	AFK    bool   `json:"afk"`
   131  }
   132  
   133  func (g *Gateway) UpdateStatus(data UpdateStatusData) error {
   134  	ctx, cancel := context.WithTimeout(context.Background(), g.WSTimeout)
   135  	defer cancel()
   136  
   137  	return g.UpdateStatusCtx(ctx, data)
   138  }
   139  
   140  func (g *Gateway) UpdateStatusCtx(ctx context.Context, data UpdateStatusData) error {
   141  	return g.SendCtx(ctx, StatusUpdateOP, data)
   142  }
   143  
   144  // Undocumented
   145  type GuildSubscribeData struct {
   146  	Typing     bool            `json:"typing"`
   147  	Threads    bool            `json:"threads"`
   148  	Activities bool            `json:"activities"`
   149  	GuildID    discord.GuildID `json:"guild_id"`
   150  
   151  	// Channels is not documented. It's used to fetch the right members sidebar.
   152  	Channels map[discord.ChannelID][][2]int `json:"channels,omitempty"`
   153  }
   154  
   155  func (g *Gateway) GuildSubscribe(data GuildSubscribeData) error {
   156  	ctx, cancel := context.WithTimeout(context.Background(), g.WSTimeout)
   157  	defer cancel()
   158  
   159  	return g.GuildSubscribeCtx(ctx, data)
   160  }
   161  
   162  func (g *Gateway) GuildSubscribeCtx(ctx context.Context, data GuildSubscribeData) error {
   163  	return g.SendCtx(ctx, GuildSubscriptionsOP, data)
   164  }