mtgbot/modules/apiact/tcgplayer.go

333 lines
7.0 KiB
Go

package apiact
import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"log"
"net/http"
"net/url"
"strconv"
"strings"
"time"
"git.trj.tw/golang/mtgbot/modules/config"
)
// TCGPlayer -
type TCGPlayer struct {
URL string
APIVersion string
AccessToken string
UserName string
Expire time.Time
}
// TCGPlayerAPIRes -
type TCGPlayerAPIRes struct {
Success bool `json:"success"`
Errors []string `json:"errors"`
Results []map[string]interface{} `json:"results"`
}
func (p *TCGPlayer) getAPIURL(urlPath string, requireVersion bool) (apiURL string, err error) {
u, err := url.Parse(p.URL)
if err != nil {
return "", err
}
u, err = u.Parse(p.APIVersion)
if err != nil {
return "", err
}
u, err = u.Parse(urlPath)
if err != nil {
return "", err
}
return u.String(), nil
}
func (p *TCGPlayer) getHeader() map[string]string {
m := make(map[string]string)
m["Content-Type"] = "application/json"
if len(p.AccessToken) > 0 {
m["Authorization"] = fmt.Sprintf("Bearer %s", p.AccessToken)
}
return m
}
// NewTCGApi -
func NewTCGApi(apiVersion string) (api *TCGPlayer, err error) {
if len(apiVersion) == 0 {
apiVersion = "v1.19.0"
}
api = &TCGPlayer{}
api.APIVersion = apiVersion
api.URL = "https://api.tcgplayer.com"
return
}
// GetToken -
func (p *TCGPlayer) GetToken() (err error) {
conf := config.GetConf()
apiURL, err := p.getAPIURL("/token", false)
dataReader := strings.NewReader(fmt.Sprintf("grant_type=client_credentials&client_id=%s&client_secret=%s", conf.TCGPlayer.PublicKey, conf.TCGPlayer.PrivateKey))
reqObj := RequestObject{}
reqObj.Method = "POST"
reqObj.URL = apiURL
reqObj.Body = dataReader
reqObj.Headers = p.getHeader()
req, err := GetRequest(reqObj)
if err != nil {
return err
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
tokenStruct := struct {
AccessToken string `json:"access_token"`
TokenType string `json:"token_type"`
ExpiresIn int `json:"expires_in"`
UserName string `json:"userName"`
Issued string `json:".issued"`
Exipres string `json:"expires"`
}{}
respByte, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
err = json.Unmarshal(respByte, &tokenStruct)
if err != nil {
return err
}
if len(tokenStruct.AccessToken) == 0 {
return errors.New("get access token fail")
}
p.AccessToken = tokenStruct.AccessToken
return
}
// TCGPlayerCategory -
type TCGPlayerCategory struct {
CaegoryID int `json:"categoryId"`
Name string `json:"name"`
DisplayName string `json:"displayName"`
ModifiedOn string `json:"modifiedOn"`
SEOCategoryName string `json:"seoCategoryName"`
SealedLabel string `json:"sealedLabel"`
NonSealedLabel string `json:"nonSealedLabel"`
ConditionGuideURL string `json:"conditionGuideUrl"`
IsScannable bool `json:"isScannable"`
Popularity int `json:"popularity"`
}
// ListCategory -
func (p *TCGPlayer) ListCategory(limit, offset int) (category []*TCGPlayerCategory, err error) {
apiURL, err := p.getAPIURL("/catalog/categories", true)
if err != nil {
return nil, err
}
tmpStruct := struct {
TCGPlayerAPIRes
Results []*TCGPlayerCategory `json:"results"`
}{}
if limit < 1 {
limit = 1
}
if offset < 0 {
offset = 0
}
qsVal := url.Values{}
qsVal.Add("limit", strconv.Itoa(limit))
qsVal.Add("offset", strconv.Itoa(offset))
apiURL += fmt.Sprintf("?%s", qsVal.Encode())
reqObj := RequestObject{
Method: "GET",
Headers: p.getHeader(),
URL: apiURL,
}
req, err := GetRequest(reqObj)
if err != nil {
return nil, err
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
respByte, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
err = json.Unmarshal(respByte, &tmpStruct)
if err != nil {
return nil, err
}
if tmpStruct.Success != true {
if len(tmpStruct.Errors) > 0 {
return nil, errors.New(tmpStruct.Errors[0])
}
return nil, errors.New("get category fail")
}
return tmpStruct.Results, nil
}
// TCGPlayerCategoryGroup -
type TCGPlayerCategoryGroup struct {
GroupID int `json:"groupId"`
Name string `json:"name"`
Abbreviation string `json:"abbreviation"`
Supplemental bool `json:"supplemental"`
PublishedOn string `json:"publishedOn"`
ModifiedOn string `json:"modifiedOn"`
CategoryID int `json:"categoryId"`
}
// ListCategoryGroups -
func (p *TCGPlayer) ListCategoryGroups(categoryID, limit, offset int) (groups []*TCGPlayerCategoryGroup, err error) {
apiURL, err := p.getAPIURL(fmt.Sprintf("/catalog/categories/%d/groups", categoryID), true)
if err != nil {
return nil, err
}
if limit < 1 {
limit = 1
}
if offset < 0 {
offset = 0
}
qsVal := url.Values{}
qsVal.Add("limit", strconv.Itoa(limit))
qsVal.Add("offset", strconv.Itoa(offset))
apiURL += fmt.Sprintf("?%s", qsVal.Encode())
tmpStruct := struct {
TCGPlayerAPIRes
TotalItems int `json:"totalItems"`
Results []*TCGPlayerCategoryGroup `json:"results"`
}{}
_ = tmpStruct
reqObj := RequestObject{
Method: "GET",
Headers: p.getHeader(),
URL: apiURL,
}
req, err := GetRequest(reqObj)
if err != nil {
return nil, err
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
respByte, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
log.Println(string(respByte))
err = json.Unmarshal(respByte, &tmpStruct)
if err != nil {
return nil, err
}
if tmpStruct.Success != true {
if len(tmpStruct.Errors) > 0 {
return nil, errors.New(tmpStruct.Errors[0])
}
return nil, errors.New("get category groups fail")
}
return tmpStruct.Results, nil
}
// TCGPlayerProductPrice -
type TCGPlayerProductPrice struct {
ProductID int `json:"productId"`
LowPrice float32 `json:"lowPrice"`
MidPrice float32 `json:"midPrice"`
HighPrice float32 `json:"highPrice"`
MarketPrice float32 `json:"marketPrice"`
DirectLowPrice float32 `json:"directLowPrice"`
SubTypeName string `json:"subTypeName"`
}
// ListGroupProductPrice -
func (p *TCGPlayer) ListGroupProductPrice(groupID int) (prices []*TCGPlayerProductPrice, err error) {
apiURL, err := p.getAPIURL(fmt.Sprintf("/pricing/group/%d", groupID), true)
if err != nil {
return nil, err
}
tmpStruct := struct {
TCGPlayerAPIRes
Results []*TCGPlayerProductPrice `json:"results"`
}{}
reqObj := RequestObject{
URL: apiURL,
Headers: p.getHeader(),
Method: "GET",
}
req, err := GetRequest(reqObj)
if err != nil {
return nil, err
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
respByte, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
err = json.Unmarshal(respByte, &tmpStruct)
if err != nil {
return nil, err
}
if tmpStruct.Success != true {
if len(tmpStruct.Errors) > 0 {
return nil, errors.New(tmpStruct.Errors[0])
}
return nil, errors.New("get product price fail")
}
return tmpStruct.Results, nil
}