Files
Joren 25410749db Initial Marktplaats SDK scaffold
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.
2026-04-15 23:45:49 +02:00

187 lines
6.2 KiB
Go

package mrktplaats
import (
"encoding/json"
"fmt"
"time"
)
// Price represents a listing price. All amounts are in euro cents.
type Price struct {
PriceType string `json:"priceType"`
PriceTypeLabel string `json:"priceTypeLabel"`
PriceAmount int `json:"priceAmount"`
}
// Picture represents an image with CDN URLs at various sizes.
type Picture struct {
ID int `json:"id"`
ExtraSmall string `json:"extraSmall"`
Medium string `json:"medium"`
Large string `json:"large"`
ExtraExtraLarge string `json:"extraExtraLarge,omitempty"`
AspectRatio interface{} `json:"aspectRatio,omitempty"`
Width int `json:"width,omitempty"`
Height int `json:"height,omitempty"`
}
// AdAddress represents the geographic location of a listing.
type AdAddress struct {
City string `json:"city"`
Country string `json:"country"`
CountryAbbreviation string `json:"countryAbbreviation"`
ZipCode string `json:"zipCode,omitempty"`
Latitude float64 `json:"latitude"`
Longitude float64 `json:"longitude"`
}
// Attribute represents a listing attribute (e.g. condition, brand).
type Attribute struct {
ID int `json:"id"`
Key string `json:"key"`
Name string `json:"name"`
Values []AttributeValue `json:"values"`
}
// AttributeValue represents a single value of an attribute.
type AttributeValue struct {
ID int `json:"id"`
Name string `json:"name"`
}
// AdCore contains the core fields shared across search results and item detail views.
type AdCore struct {
URN string `json:"urn"`
Title string `json:"title"`
Description string `json:"description,omitempty"`
CategoryID int `json:"categoryId"`
Price Price `json:"price"`
Picture *Picture `json:"picture,omitempty"`
Pictures []Picture `json:"pictures,omitempty"`
AdAddress AdAddress `json:"adAddress"`
Attributes []Attribute `json:"attributes,omitempty"`
Link string `json:"link,omitempty"`
}
// SellerInformation identifies the seller of a listing.
type SellerInformation struct {
ID int `json:"id"`
Name string `json:"name"`
Type string `json:"type,omitempty"`
Phone string `json:"phone,omitempty"`
PhoneHidden bool `json:"phoneNumberHidden,omitempty"`
AllowASQ bool `json:"allowAsq,omitempty"`
ActiveSince json.RawMessage `json:"activeSince,omitempty"`
SavedForUser bool `json:"savedForUser,omitempty"`
KYCState json.RawMessage `json:"kycState,omitempty"`
MerchantState string `json:"merchantState,omitempty"`
DealerPackage string `json:"dealerPackage,omitempty"`
}
// User represents an authenticated user account.
type User struct {
ID int `json:"id"`
EncryptedID string `json:"encryptedId"`
Name string `json:"name"`
Email string `json:"email"`
Phone string `json:"phone"`
ZipCode string `json:"zipCode"`
ActivationDate string `json:"activationDate"`
RegistrationDate string `json:"registrationDate"`
OneClickOptedIn bool `json:"oneClickOptedIn"`
OneClickBlocked bool `json:"oneClickBlocked"`
ProfilePicture string `json:"profilePicture"`
ShowMapOnVipEnabled bool `json:"showMapOnVipEnabled"`
NdfcDeclarationStatus string `json:"ndfcDeclarationStatus"`
}
// DiscoveryPrice is the snake_case price used by older API3 endpoints.
type DiscoveryPrice struct {
PriceType string `json:"price_type"`
PriceTypeLabel string `json:"price_type_label"`
PriceAmount int `json:"price_amount"`
}
// DiscoveryPicture is the snake_case picture used by older API3 endpoints.
type DiscoveryPicture struct {
ID int `json:"id"`
ExtraSmall string `json:"extra_small"`
Medium string `json:"medium"`
Large string `json:"large"`
}
// FlexTime is a time.Time that accepts dates without a timezone suffix
// (e.g. "2025-10-18T14:50:53") in addition to standard RFC3339.
type FlexTime struct{ time.Time }
// UnmarshalJSON parses RFC3339 dates, falling back to local (UTC) parsing
// when the timezone suffix is absent.
func (ft *FlexTime) UnmarshalJSON(data []byte) error {
if len(data) < 2 || data[0] != '"' {
return nil
}
s := string(data[1 : len(data)-1])
t, err := time.Parse(time.RFC3339, s)
if err != nil {
t, err = time.ParseInLocation("2006-01-02T15:04:05", s, time.UTC)
if err != nil {
return fmt.Errorf("FlexTime: cannot parse %q", s)
}
}
ft.Time = t
return nil
}
// Review represents a user review.
type Review struct {
ID int `json:"id"`
Reviewer ReviewUser `json:"reviewer"`
Reviewee ReviewUser `json:"reviewee"`
Direction string `json:"direction"`
CreationDate FlexTime `json:"creationDate"`
Score int `json:"score"`
ItemID string `json:"itemId"`
Advertisement ReviewAd `json:"advertisement"`
Details []ReviewDetail `json:"details"`
Content ReviewContent `json:"content"`
ReviewSubject string `json:"reviewSubject"`
}
// ReviewUser is a participant in a review.
type ReviewUser struct {
ID int `json:"id"`
Nickname string `json:"nickname"`
}
// ReviewAd is the listing associated with a review.
type ReviewAd struct {
ID string `json:"id"`
Title string `json:"title"`
CategoryName string `json:"categoryName"`
}
// ReviewDetail contains category-level review scoring.
type ReviewDetail struct {
Category string `json:"category"`
Score int `json:"score"`
Characteristics []ReviewCharacteristic `json:"characteristics"`
}
// ReviewCharacteristic is an individual review trait.
type ReviewCharacteristic struct {
ID int `json:"id"`
Text string `json:"text"`
IsPositive bool `json:"isPositive"`
}
// ReviewContent holds the textual content of a review.
type ReviewContent struct {
Subject string `json:"subject"`
}
// ReviewSummary provides aggregate review statistics.
type ReviewSummary struct {
NumberOfReviews int `json:"numberOfReviews"`
AverageScore float64 `json:"averageScore"`
}