github.com/diamondburned/arikawa@v1.3.14/gateway/commands.go (about)

     1  package gateway
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/diamondburned/arikawa/discord"
     7  	"github.com/pkg/errors"
     8  )
     9  
    10  // Rules: VOICE_STATE_UPDATE -> VoiceStateUpdateEvent
    11  
    12  // Identify structure is at identify.go
    13  
    14  func (g *Gateway) Identify() error {
    15  	ctx, cancel := context.WithTimeout(context.Background(), g.WSTimeout)
    16  	defer cancel()
    17  
    18  	return g.IdentifyCtx(ctx)
    19  }
    20  
    21  func (g *Gateway) IdentifyCtx(ctx context.Context) error {
    22  	ctx, cancel := context.WithTimeout(ctx, g.WSTimeout)
    23  	defer cancel()
    24  
    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(
   118  	ctx context.Context, data UpdateVoiceStateData) error {
   119  
   120  	return g.SendCtx(ctx, VoiceStateUpdateOP, data)
   121  }
   122  
   123  type UpdateStatusData struct {
   124  	Since discord.UnixMsTimestamp `json:"since"` // 0 if not idle
   125  
   126  	// Both fields are nullable.
   127  	Game       *discord.Activity   `json:"game,omitempty"`
   128  	Activities *[]discord.Activity `json:"activities,omitempty"`
   129  
   130  	Status discord.Status `json:"status"`
   131  	AFK    bool           `json:"afk"`
   132  }
   133  
   134  func (g *Gateway) UpdateStatus(data UpdateStatusData) error {
   135  	ctx, cancel := context.WithTimeout(context.Background(), g.WSTimeout)
   136  	defer cancel()
   137  
   138  	return g.UpdateStatusCtx(ctx, data)
   139  }
   140  
   141  func (g *Gateway) UpdateStatusCtx(ctx context.Context, data UpdateStatusData) error {
   142  	return g.SendCtx(ctx, StatusUpdateOP, data)
   143  }
   144  
   145  // Undocumented
   146  type GuildSubscribeData struct {
   147  	Typing     bool            `json:"typing"`
   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  }