sync/handlers/fansly.go
2025-05-19 18:26:52 -04:00

112 lines
2.9 KiB
Go

package handlers
import (
"FanslySync/structs"
"encoding/json"
"fmt"
"io"
"net/http"
"time"
"github.com/wailsapp/wails/v2/pkg/logger"
)
type FanslyAPIController struct {
client *http.Client
token string
logger logger.Logger
}
// New creates a new Fansly client with the provided token (optional).
func NewFanslyAPIController(token string, log logger.Logger) *FanslyAPIController {
client := &http.Client{
Timeout: 30 * time.Second,
}
return &FanslyAPIController{
client: client,
token: token,
logger: log,
}
}
// GET issues a GET to /api/v1/{path}, optionally adding the Auth header,
// and unmarshals the JSON response into the result parameter.
func (f *FanslyAPIController) GET(path string, needsAuth bool, out interface{}) error {
// build request
url := "https://apiv3.fansly.com/api/v1/" + path
req, err := http.NewRequest("GET", url, nil)
if err != nil {
f.logger.Error("[FanslyAPIController] NewRequest GET " + path + ": " + err.Error())
return err
}
// Set headers
req.Header.Set("User-Agent", "FanslySync/3.0 sticks@teamhydra.dev")
req.Header.Set("Accept", "application/json")
// set auth
if needsAuth && f.token != "" {
req.Header.Set("Authorization", f.token)
}
// send
resp, err := f.client.Do(req)
if err != nil {
f.logger.Error("[FanslyAPIController] Do GET " + path + ": " + err.Error())
return err
}
defer resp.Body.Close()
// non-200
if resp.StatusCode != http.StatusOK {
f.logger.Error(fmt.Sprintf("[FanslyAPIController] GET %s failed: %s", path, resp.Status))
// read body for logs
body, _ := io.ReadAll(resp.Body)
f.logger.Info("[FanslyAPIController] Response body: " + string(body))
return fmt.Errorf("unexpected status %s", resp.Status)
}
// 200 ok, log
f.logger.Debug(fmt.Sprintf("[FanslyAPIController] GET %s succeeded: %s", path, resp.Status))
// read body and unmarshal
body, err := io.ReadAll(resp.Body)
if err != nil {
f.logger.Error("[FanslyAPIController] Request was OK, but failed to read body: " + err.Error())
return err
}
// unmarshal into our expected response type
err = json.Unmarshal(body, &out)
if err != nil {
f.logger.Error("[FanslyAPIController] GET " + path + " failed to unmarshal response: " + err.Error())
return err
}
return nil
}
// SetToken updates the authorization token for subsequent requests.
func (f *FanslyAPIController) SetToken(token string) {
f.token = token
}
// Returns the current user's account information from the Fansly API.
//
// Will error if the token is not set or the request fails.
//
// Returns a FanslyAccount struct containing the account information.
func (f *FanslyAPIController) GetMe() (*structs.FanslyAccount, error) {
var response structs.FanslyBaseResponse[structs.FanslyAccountResponse]
err := f.GET("account/me", true, &response)
if err != nil {
f.logger.Error("[FanslyAPIController] GetMe failed: " + err.Error())
return nil, err
}
// Return the account info
return &response.Response.Account, nil
}