Clone the twdehands SDK into mrktplaats and retarget naming and defaults for app.marktplaats.nl while keeping the same request/response bodies and endpoint behavior.
114 lines
3.7 KiB
Go
114 lines
3.7 KiB
Go
package mrktplaats
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/url"
|
|
"strings"
|
|
)
|
|
|
|
// ListingService handles viewing individual listing details (VIP).
|
|
type ListingService struct {
|
|
t *transport
|
|
}
|
|
|
|
// ListingDetail is the full detail view of a single listing.
|
|
type ListingDetail struct {
|
|
AdCore AdCore `json:"adCore"`
|
|
SellerInformation SellerInformation `json:"sellerInformation"`
|
|
Bids []Bid `json:"bids,omitempty"`
|
|
CurrentMinimumBid int `json:"currentMinimumBid,omitempty"`
|
|
ShowBanner bool `json:"showBanner,omitempty"`
|
|
Traits json.RawMessage `json:"traits,omitempty"`
|
|
BuyersProtectionAllowed bool `json:"buyersProtectionAllowed,omitempty"`
|
|
IsBuyerProtectionApplicableForDefaultOn bool `json:"isBuyerProtectionApplicableForDefaultOn,omitempty"`
|
|
LargeItemShippingLogicalAllowed bool `json:"largeItemShippingLogicalAllowed,omitempty"`
|
|
}
|
|
|
|
// DefaultCTATypes is the standard set of CTA types the client declares support for.
|
|
var DefaultCTATypes = []string{"bid", "asq", "website", "phone", "buyNow"}
|
|
|
|
type viewItemRequest struct {
|
|
SupportedCTATypes []string `json:"supportedCTATypes"`
|
|
SupportsReservedFlag bool `json:"supportsReservedFlag"`
|
|
}
|
|
|
|
// Get retrieves the full details of a listing by its URN.
|
|
// An optional correlationID (from a prior search) can be passed for analytics.
|
|
func (s *ListingService) Get(ctx context.Context, urn string, correlationID ...string) (*ListingDetail, error) {
|
|
path := fmt.Sprintf("/app/vip/v4/item/%s", urn)
|
|
|
|
var params url.Values
|
|
if len(correlationID) > 0 && correlationID[0] != "" {
|
|
params = url.Values{"correlation_id": {correlationID[0]}}
|
|
}
|
|
|
|
body := viewItemRequest{
|
|
SupportedCTATypes: DefaultCTATypes,
|
|
SupportsReservedFlag: true,
|
|
}
|
|
|
|
var resp ListingDetail
|
|
if err := s.t.postJSON(ctx, path, params, nil, body, &resp); err != nil {
|
|
return nil, err
|
|
}
|
|
return &resp, nil
|
|
}
|
|
|
|
// VIPDisplayTargetingRequest defines parameters for item page ad targeting.
|
|
// Positions is serialized as a comma-separated string; Postcode and SellerID
|
|
// are sent as JSON null when empty.
|
|
type VIPDisplayTargetingRequest struct {
|
|
AdURN string
|
|
Attr json.RawMessage
|
|
Positions []string
|
|
Postcode string
|
|
SellerID string
|
|
}
|
|
|
|
// MarshalJSON serializes in the format the marktplaats API expects.
|
|
func (r VIPDisplayTargetingRequest) MarshalJSON() ([]byte, error) {
|
|
attr := r.Attr
|
|
if len(attr) == 0 {
|
|
attr = json.RawMessage(`{}`)
|
|
}
|
|
type wire struct {
|
|
AdURN string `json:"adUrn"`
|
|
Attr json.RawMessage `json:"attr"`
|
|
Positions string `json:"positions"`
|
|
Postcode *string `json:"postcode"`
|
|
SellerID *string `json:"sellerId"`
|
|
}
|
|
w := wire{
|
|
AdURN: r.AdURN,
|
|
Attr: attr,
|
|
Positions: strings.Join(r.Positions, ", "),
|
|
}
|
|
if r.Postcode != "" {
|
|
w.Postcode = &r.Postcode
|
|
}
|
|
if r.SellerID != "" {
|
|
w.SellerID = &r.SellerID
|
|
}
|
|
return json.Marshal(w)
|
|
}
|
|
|
|
// DefaultVIPPositions are the standard ad positions for an item detail page.
|
|
var DefaultVIPPositions = []string{
|
|
"VIP_LEADERBOARD_MID1",
|
|
"vip_native",
|
|
"vip_native_2",
|
|
"VIP_GALLERY_BANNER",
|
|
"VIP_DESCRIPTION_BANNER",
|
|
}
|
|
|
|
// DisplayTargeting retrieves ad targeting configuration for a listing detail page.
|
|
func (s *ListingService) DisplayTargeting(ctx context.Context, req *VIPDisplayTargetingRequest) ([]DisplayTargetingResult, error) {
|
|
var resp []DisplayTargetingResult
|
|
if err := s.t.postJSON(ctx, "/app/vip/v4/display-targeting", nil, nil, req, &resp); err != nil {
|
|
return nil, err
|
|
}
|
|
return resp, nil
|
|
}
|