1
0
Fork 0
mirror of https://github.com/diamondburned/arikawa.git synced 2024-09-17 15:38:46 +00:00
arikawa/session/session.go

103 lines
2.1 KiB
Go
Raw Normal View History

2020-01-17 05:17:46 +00:00
// Package session abstracts around the REST API and the Gateway, managing both
// at once. It offers a handler interface similar to that in discordgo for
// Gateway events.
2020-01-15 04:43:34 +00:00
package session
import (
"log"
"github.com/diamondburned/arikawa/api"
"github.com/diamondburned/arikawa/gateway"
2020-01-17 05:23:56 +00:00
"github.com/diamondburned/arikawa/handler"
2020-01-17 02:08:03 +00:00
"github.com/pkg/errors"
2020-01-15 04:43:34 +00:00
)
2020-01-17 05:23:56 +00:00
// Session manages both the API and Gateway. As such, Session inherits all of
// API's methods, as well has the Handler used for Gateway.
2020-01-15 04:43:34 +00:00
type Session struct {
2020-01-17 02:08:03 +00:00
*api.Client
gateway *gateway.Gateway
2020-01-15 04:43:34 +00:00
2020-01-17 05:17:46 +00:00
// ErrorLog logs errors, including Gateway errors.
2020-01-15 04:43:34 +00:00
ErrorLog func(err error) // default to log.Println
2020-01-17 05:23:56 +00:00
// Command handler with inherited methods.
2020-01-17 05:17:46 +00:00
*handler.Handler
2020-01-17 05:23:56 +00:00
2020-01-17 05:17:46 +00:00
hstop chan struct{}
2020-01-15 04:43:34 +00:00
}
func New(token string) (*Session, error) {
// Initialize the session and the API interface
s := &Session{}
2020-01-17 05:17:46 +00:00
s.Handler = handler.New()
2020-01-17 02:08:03 +00:00
s.Client = api.NewClient(token)
2020-01-15 04:43:34 +00:00
// Default logger
s.ErrorLog = func(err error) {
log.Println("Arikawa/session error:", err)
}
2020-01-17 02:08:03 +00:00
// Open a gateway
g, err := gateway.NewGateway(token)
2020-01-15 04:43:34 +00:00
if err != nil {
2020-01-17 02:08:03 +00:00
return nil, errors.Wrap(err, "Failed to connect to Gateway")
2020-01-15 04:43:34 +00:00
}
2020-01-17 02:08:03 +00:00
s.gateway = g
2020-01-17 05:17:46 +00:00
s.gateway.ErrorLog = func(err error) {
s.ErrorLog(err)
}
2020-01-15 04:43:34 +00:00
return s, nil
}
2020-01-17 02:08:03 +00:00
func NewWithGateway(gw *gateway.Gateway) *Session {
2020-01-17 05:17:46 +00:00
s := &Session{
2020-01-17 02:08:03 +00:00
// Nab off gateway's token
Client: api.NewClient(gw.Identifier.Token),
ErrorLog: func(err error) {
log.Println("Arikawa/session error:", err)
},
2020-01-17 05:17:46 +00:00
Handler: handler.New(),
2020-01-17 02:08:03 +00:00
}
2020-01-17 05:17:46 +00:00
gw.ErrorLog = func(err error) {
s.ErrorLog(err)
}
return s
2020-01-17 02:08:03 +00:00
}
func (s *Session) Open() error {
if err := s.gateway.Start(); err != nil {
return errors.Wrap(err, "Failed to start gateway")
}
stop := make(chan struct{})
s.hstop = stop
go s.startHandler(stop)
return nil
}
func (s *Session) startHandler(stop <-chan struct{}) {
for {
select {
case <-stop:
return
case ev := <-s.gateway.Events:
2020-01-17 05:17:46 +00:00
s.Handler.Call(ev)
2020-01-15 04:43:34 +00:00
}
}
2020-01-17 02:08:03 +00:00
}
func (s *Session) Close() error {
// Stop the event handler
if s.hstop != nil {
close(s.hstop)
}
2020-01-15 04:43:34 +00:00
2020-01-17 02:08:03 +00:00
// Close the websocket
return s.gateway.Close()
2020-01-15 04:43:34 +00:00
}