79 lines
2.1 KiB
Go
79 lines
2.1 KiB
Go
package upstream
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/nyoungo/dsfree2api/internal/config"
|
|
"github.com/nyoungo/dsfree2api/internal/httpx"
|
|
)
|
|
|
|
// guestCookieName mirrors the upstream guest-token plugin's visitor cookie;
|
|
// its value is the "gid" the balance endpoint reports on.
|
|
const guestCookieName = "dsgt_gid"
|
|
|
|
// SiteBalance is the response of GET /wp-json/dsgt/v1/balance. The free-tier
|
|
// block only appears when the request carries a bot_id.
|
|
type SiteBalance struct {
|
|
Gid string `json:"gid"`
|
|
Balance float64 `json:"balance"`
|
|
Free struct {
|
|
Limit int `json:"limit"`
|
|
Used int `json:"used"`
|
|
Remaining int `json:"remaining"`
|
|
ResetPeriod string `json:"reset_period"`
|
|
} `json:"free"`
|
|
}
|
|
|
|
// FetchBalance queries the site's guest balance endpoint for one visitor id.
|
|
// No nonce is required for guests; the id travels as the visitor cookie.
|
|
// botID selects the per-bot free tier (0 omits it, which also omits free).
|
|
func (c *Client) FetchBalance(
|
|
ctx context.Context,
|
|
site config.Site,
|
|
gid string,
|
|
botID int,
|
|
route Route,
|
|
) (*SiteBalance, error) {
|
|
if gid == "" {
|
|
return nil, errf("no guest id for site %s", site.Code)
|
|
}
|
|
sess, err := httpx.NewSession(httpx.Options{ProxyURL: route.Proxy, Timeout: 20 * time.Second})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer sess.Close()
|
|
sess.SetCookies(map[string]string{guestCookieName: gid})
|
|
|
|
url := site.BaseURL + "/wp-json/dsgt/v1/balance?_t=" + strconv.FormatInt(time.Now().UnixMilli(), 10)
|
|
if botID > 0 {
|
|
url += "&bot_id=" + itoa(botID)
|
|
}
|
|
c.cfg.RLock()
|
|
ua := c.cfg.Upstream.UserAgent
|
|
c.cfg.RUnlock()
|
|
resp, err := sess.Do(ctx, httpx.Request{
|
|
Method: "GET",
|
|
URL: url,
|
|
Header: map[string]string{
|
|
"User-Agent": ua,
|
|
"Accept": "application/json",
|
|
"Referer": site.BaseURL + "/",
|
|
},
|
|
Timeout: 20 * time.Second,
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if resp.Status >= 400 {
|
|
return nil, errf("balance http %d: %s", resp.Status, truncate(string(resp.Body), 200))
|
|
}
|
|
var out SiteBalance
|
|
if err := json.Unmarshal(resp.Body, &out); err != nil {
|
|
return nil, errf("balance bad json: %v", err)
|
|
}
|
|
return &out, nil
|
|
}
|