2023-03-06 19:53:07 +00:00
|
|
|
package api
|
2023-03-04 11:54:08 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
2023-11-05 16:03:52 +00:00
|
|
|
"log/slog"
|
2023-03-04 11:54:08 +00:00
|
|
|
"net/http"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
type EpicStruct struct {
|
|
|
|
url string
|
2023-03-06 18:02:40 +00:00
|
|
|
baseUrl string
|
2023-03-04 11:54:08 +00:00
|
|
|
idPrefix string
|
2023-03-06 18:02:40 +00:00
|
|
|
headers map[string]string
|
2023-03-04 11:54:08 +00:00
|
|
|
deals DealsMap
|
2023-11-05 16:03:52 +00:00
|
|
|
logger *slog.Logger
|
2023-03-04 11:54:08 +00:00
|
|
|
}
|
|
|
|
|
2023-11-05 16:03:52 +00:00
|
|
|
func NewEpicApi(logger *slog.Logger) EpicStruct {
|
2023-03-06 18:02:40 +00:00
|
|
|
epic := EpicStruct{
|
2023-03-04 11:54:08 +00:00
|
|
|
url: "https://store-site-backend-static-ipv4.ak.epicgames.com/freeGamesPromotions",
|
2023-03-06 18:02:40 +00:00
|
|
|
baseUrl: "https://store.epicgames.com/p/",
|
2023-03-04 11:54:08 +00:00
|
|
|
idPrefix: "epic-",
|
2023-03-06 18:02:40 +00:00
|
|
|
headers: make(map[string]string),
|
2023-03-04 11:54:08 +00:00
|
|
|
deals: make(map[string]Deal),
|
2023-11-05 16:03:52 +00:00
|
|
|
logger: logger,
|
2023-03-04 11:54:08 +00:00
|
|
|
}
|
2023-03-06 18:02:40 +00:00
|
|
|
epic.headers["Accept-Language"] = "en"
|
|
|
|
epic.headers["User-Agent"] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:93.0) Gecko/20100101 Firefox/93.0"
|
|
|
|
return epic
|
2023-03-04 11:54:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type epicApiBody struct {
|
|
|
|
Data struct {
|
|
|
|
Catalog struct {
|
|
|
|
SearchStore struct {
|
|
|
|
Elements []struct {
|
|
|
|
Title string `json:"title"`
|
|
|
|
Id string `json:"id"`
|
|
|
|
Description string `json:"description"`
|
|
|
|
OfferType string `json:"offerType"`
|
|
|
|
IsCodeRedemptionOnly bool `json:"isCodeRedemptionOnly"`
|
|
|
|
ProductSlug string `json:"productSlug"`
|
|
|
|
OfferMappings []struct {
|
|
|
|
PageSlug string `json:"pageSlug"`
|
|
|
|
PageType string `json:"pageType"`
|
|
|
|
} `json:"offerMappings"`
|
|
|
|
Price struct {
|
|
|
|
TotalPrice struct {
|
|
|
|
DiscountPrice int `json:"discountPrice"`
|
|
|
|
OriginalPrice int `json:"originalPrice"`
|
|
|
|
Discount int `json:"discount"`
|
|
|
|
CurrencyCode string `json:"currencyCode"`
|
|
|
|
} `json:"totalPrice"`
|
|
|
|
} `json:"price"`
|
|
|
|
Promotions *struct {
|
|
|
|
PromotionalOffers []struct {
|
|
|
|
PromotionalOffers []struct {
|
|
|
|
StartDate time.Time `json:"startDate"`
|
|
|
|
EndDate time.Time `json:"endDate"`
|
|
|
|
DiscountSetting struct {
|
|
|
|
DiscountType string `json:"discountType"`
|
|
|
|
DiscountPercentage int `json:"discountPercentage"`
|
|
|
|
} `json:"discountSetting"`
|
|
|
|
} `json:"promotionalOffers"`
|
|
|
|
} `json:"promotionalOffers"`
|
|
|
|
} `json:"promotions"`
|
|
|
|
} `json:"elements"`
|
|
|
|
Paging struct {
|
|
|
|
Count int `json:"count"`
|
|
|
|
Total int `json:"total"`
|
|
|
|
} `json:"paging"`
|
|
|
|
} `json:"searchStore"`
|
|
|
|
} `json:"Catalog"`
|
|
|
|
} `json:"data"`
|
|
|
|
}
|
|
|
|
|
2023-03-06 19:53:07 +00:00
|
|
|
func (e EpicStruct) Load() error {
|
2023-03-04 11:54:08 +00:00
|
|
|
client := &http.Client{}
|
|
|
|
req, err := http.NewRequest("GET", e.url, nil)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2023-03-06 18:02:40 +00:00
|
|
|
for key, value := range e.headers {
|
|
|
|
req.Header.Set(key, value)
|
|
|
|
}
|
|
|
|
|
2023-03-04 11:54:08 +00:00
|
|
|
res, err := client.Do(req)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
body, err := io.ReadAll(res.Body)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
var data epicApiBody
|
|
|
|
err = json.Unmarshal(body, &data)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, element := range data.Data.Catalog.SearchStore.Elements {
|
|
|
|
if element.Promotions == nil ||
|
|
|
|
len(element.Promotions.PromotionalOffers) == 0 ||
|
|
|
|
len(element.Promotions.PromotionalOffers[0].PromotionalOffers) == 0 ||
|
|
|
|
element.Promotions.PromotionalOffers[0].PromotionalOffers[0].DiscountSetting.DiscountPercentage != 0 {
|
|
|
|
// no deal
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
productSlug := element.ProductSlug
|
|
|
|
if len(element.OfferMappings) != 0 && productSlug == "" {
|
|
|
|
productSlug = element.OfferMappings[0].PageSlug
|
|
|
|
}
|
|
|
|
if productSlug == "" {
|
2023-11-05 16:03:52 +00:00
|
|
|
e.logger.Error("product slug not found", slog.String("title", element.Title))
|
2023-03-04 11:54:08 +00:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
id := fmt.Sprintf("%v%v", e.idPrefix, element.Id)
|
|
|
|
title := element.Title
|
2023-03-06 18:02:40 +00:00
|
|
|
url := fmt.Sprintf("%v%v", e.baseUrl, productSlug)
|
2023-03-04 11:54:08 +00:00
|
|
|
|
|
|
|
e.deals[id] = Deal{
|
|
|
|
Id: id,
|
|
|
|
Title: title,
|
|
|
|
Url: url,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-03-06 19:53:07 +00:00
|
|
|
func (e EpicStruct) Get() []Deal {
|
2023-03-04 11:54:08 +00:00
|
|
|
var deals []Deal
|
|
|
|
for _, deal := range e.deals {
|
|
|
|
deals = append(deals, deal)
|
|
|
|
}
|
|
|
|
return deals
|
|
|
|
}
|