1
0
Fork 0
mirror of https://github.com/diamondburned/cchat-discord.git synced 2024-11-01 20:34:27 +00:00
cchat-discord/internal/discord/state/state.go

100 lines
2.2 KiB
Go
Raw Normal View History

2020-09-08 04:44:09 +00:00
// Package state provides a shared state instance for other packages to use.
package state
import (
"context"
"log"
"github.com/diamondburned/arikawa/discord"
2020-10-07 01:53:15 +00:00
"github.com/diamondburned/arikawa/session"
2020-09-08 04:44:09 +00:00
"github.com/diamondburned/arikawa/state"
"github.com/diamondburned/arikawa/utils/httputil/httpdriver"
2020-10-07 01:53:15 +00:00
"github.com/diamondburned/cchat"
2020-12-19 05:46:12 +00:00
"github.com/diamondburned/cchat-discord/internal/discord/state/nonce"
2020-09-08 04:44:09 +00:00
"github.com/diamondburned/ningen"
"github.com/pkg/errors"
)
type Instance struct {
*ningen.State
2020-12-19 05:46:12 +00:00
Nonces *nonce.Map
// UserID is a constant user ID. It is guaranteed to be valid.
2020-09-08 04:44:09 +00:00
UserID discord.UserID
}
2020-12-19 05:46:12 +00:00
var _ cchat.SessionSaver = (*Instance)(nil)
2020-10-07 01:53:15 +00:00
// ErrInvalidSession is returned if SessionRestore is given a bad session.
var ErrInvalidSession = errors.New("invalid session")
func NewFromData(data map[string]string) (*Instance, error) {
tk, ok := data["token"]
if !ok {
return nil, ErrInvalidSession
}
return NewFromToken(tk)
}
2020-09-08 04:44:09 +00:00
func NewFromToken(token string) (*Instance, error) {
s, err := state.New(token)
if err != nil {
return nil, err
}
return New(s)
}
2020-10-07 01:53:15 +00:00
func Login(email, password, mfa string) (*Instance, error) {
session, err := session.Login(email, password, mfa)
if err != nil {
return nil, err
}
state, _ := state.NewFromSession(session, state.NewDefaultStore(nil))
return New(state)
}
2020-09-08 04:44:09 +00:00
func New(s *state.State) (*Instance, error) {
// Prefetch user.
u, err := s.Me()
if err != nil {
2020-12-19 05:46:12 +00:00
return nil, errors.Wrap(err, "failed to get current user")
2020-09-08 04:44:09 +00:00
}
n, err := ningen.FromState(s)
if err != nil {
2020-12-19 05:46:12 +00:00
return nil, errors.Wrap(err, "failed to create a state wrapper")
2020-09-08 04:44:09 +00:00
}
n.Client.OnRequest = append(n.Client.OnRequest, func(r httpdriver.Request) error {
log.Println("[Discord] Request", r.GetPath())
return nil
})
if err := n.Open(); err != nil {
return nil, err
}
return &Instance{
UserID: u.ID,
State: n,
2020-12-19 05:46:12 +00:00
Nonces: new(nonce.Map),
2020-09-08 04:44:09 +00:00
}, nil
}
// StateOnly returns a shallow copy of *State with an already-expired context.
func (s *Instance) StateOnly() *state.State {
ctx, cancel := context.WithCancel(context.Background())
cancel()
return s.WithContext(ctx)
}
2020-10-07 01:53:15 +00:00
func (s *Instance) SaveSession() map[string]string {
return map[string]string{
"token": s.Token,
}
}