Add support for websocket api
This commit is contained in:
parent
0850c2fe1f
commit
6023806f7b
11
go.mod
11
go.mod
@ -2,4 +2,13 @@ module go.arsenm.dev/go-lemmy
|
|||||||
|
|
||||||
go 1.19
|
go 1.19
|
||||||
|
|
||||||
require github.com/google/go-querystring v1.1.0
|
require (
|
||||||
|
github.com/google/go-querystring v1.1.0
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0
|
||||||
|
github.com/recws-org/recws v1.4.0
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/gorilla/websocket v1.4.2 // indirect
|
||||||
|
github.com/jpillora/backoff v1.0.0 // indirect
|
||||||
|
)
|
||||||
|
8
go.sum
8
go.sum
@ -2,4 +2,12 @@ github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
|
|||||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
||||||
|
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||||
|
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
|
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
|
||||||
|
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||||
|
github.com/recws-org/recws v1.4.0 h1:y9LLddtAicjejikNZXiaY9DQjIwcAQ82acd1XU6n0lU=
|
||||||
|
github.com/recws-org/recws v1.4.0/go.mod h1:7+NQkTmBdU98VSzkzq9/P7+X0xExioUVBx9OeRKQIkk=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
@ -25,3 +25,8 @@ type LemmyError struct {
|
|||||||
func (le LemmyError) Error() string {
|
func (le LemmyError) Error() string {
|
||||||
return fmt.Sprintf("%d %s: %s", le.Code, http.StatusText(le.Code), le.ErrStr)
|
return fmt.Sprintf("%d %s: %s", le.Code, http.StatusText(le.Code), le.ErrStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type LemmyWebSocketMsg struct {
|
||||||
|
Op UserOperation `json:"op"`
|
||||||
|
Data any `json:"data"`
|
||||||
|
}
|
||||||
|
76
websocket.go
Normal file
76
websocket.go
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
package lemmy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/url"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/mitchellh/mapstructure"
|
||||||
|
"github.com/recws-org/recws"
|
||||||
|
"go.arsenm.dev/go-lemmy/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
type WSClient struct {
|
||||||
|
conn *recws.RecConn
|
||||||
|
respCh chan types.LemmyWebSocketMsg
|
||||||
|
errCh chan error
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewWebSocket(baseURL string) (*WSClient, error) {
|
||||||
|
ws := &recws.RecConn{
|
||||||
|
KeepAliveTimeout: 10 * time.Second,
|
||||||
|
}
|
||||||
|
|
||||||
|
u, err := url.Parse(baseURL)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
u = u.JoinPath("/api/v3")
|
||||||
|
|
||||||
|
ws.Dial(u.String(), nil)
|
||||||
|
|
||||||
|
out := &WSClient{
|
||||||
|
conn: ws,
|
||||||
|
respCh: make(chan types.LemmyWebSocketMsg, 10),
|
||||||
|
errCh: make(chan error, 10),
|
||||||
|
}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
var msg types.LemmyWebSocketMsg
|
||||||
|
err = ws.ReadJSON(&msg)
|
||||||
|
if err != nil {
|
||||||
|
out.errCh <- err
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
out.respCh <- msg
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *WSClient) Request(op types.UserOperation, data any) error {
|
||||||
|
return c.conn.WriteJSON(types.LemmyWebSocketMsg{
|
||||||
|
Op: op,
|
||||||
|
Data: data,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *WSClient) Responses() <-chan types.LemmyWebSocketMsg {
|
||||||
|
return c.respCh
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *WSClient) Errors() <-chan error {
|
||||||
|
return c.errCh
|
||||||
|
}
|
||||||
|
|
||||||
|
func DecodeResponse(data, out any) error {
|
||||||
|
dec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
|
||||||
|
TagName: "json",
|
||||||
|
Result: out,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return dec.Decode(data)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user