forked from Mirrors/gomuks
80 lines
1.8 KiB
Go
80 lines
1.8 KiB
Go
package beeper
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"net/url"
|
|
"time"
|
|
|
|
"maunium.net/go/mautrix"
|
|
)
|
|
|
|
var cli = &http.Client{Timeout: 30 * time.Second}
|
|
|
|
func newRequest(token, method, path string) *http.Request {
|
|
req := &http.Request{
|
|
URL: &url.URL{
|
|
Scheme: "https",
|
|
Host: "api.beeper.com",
|
|
Path: path,
|
|
},
|
|
Method: method,
|
|
Header: http.Header{
|
|
"Authorization": {fmt.Sprintf("Bearer %s", token)},
|
|
"User-Agent": {mautrix.DefaultUserAgent},
|
|
},
|
|
}
|
|
if method == http.MethodPut || method == http.MethodPost {
|
|
req.Header.Set("Content-Type", "application/json")
|
|
}
|
|
return req
|
|
}
|
|
|
|
func encodeContent(into *http.Request, body any) error {
|
|
var buf bytes.Buffer
|
|
err := json.NewEncoder(&buf).Encode(body)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to encode request: %w", err)
|
|
}
|
|
into.Body = io.NopCloser(&buf)
|
|
return nil
|
|
}
|
|
|
|
func doRequest(req *http.Request, reqData, resp any) (err error) {
|
|
if reqData != nil {
|
|
err = encodeContent(req, reqData)
|
|
if err != nil {
|
|
return
|
|
}
|
|
}
|
|
r, err := cli.Do(req)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to send request: %w", err)
|
|
}
|
|
defer r.Body.Close()
|
|
if r.StatusCode < 200 || r.StatusCode >= 300 {
|
|
var body map[string]any
|
|
_ = json.NewDecoder(r.Body).Decode(&body)
|
|
if body != nil {
|
|
retryCount, ok := body["retries"].(float64)
|
|
if ok && retryCount > 0 && r.StatusCode == 403 && req.URL.Path == "/user/login/response" {
|
|
return fmt.Errorf("%w (%d retries left)", ErrInvalidLoginCode, int(retryCount))
|
|
}
|
|
errorMsg, ok := body["error"].(string)
|
|
if ok {
|
|
return fmt.Errorf("server returned error (HTTP %d): %s", r.StatusCode, errorMsg)
|
|
}
|
|
}
|
|
return fmt.Errorf("unexpected status code %d", r.StatusCode)
|
|
}
|
|
if resp != nil {
|
|
err = json.NewDecoder(r.Body).Decode(resp)
|
|
if err != nil {
|
|
return fmt.Errorf("error decoding response: %w", err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|