Documentation
¶
Index ¶
- Constants
- Variables
- func AllowedAdRectsString() string
- func DateToTime(date string) time.Time
- func MidnightToMidnight(t time.Time) (start, end time.Time)
- func RawMarshal(v interface{}) *json.RawMessage
- func SetApp(cmp *Campaign, app App)
- type Ad
- type AdGroup
- type AdReport
- type AdsListItem
- type Advertiser
- type Agency
- type App
- type AppAdvBidding
- type AppDomainTargeting
- type AppGeography
- type AppPacing
- type AppSearchRetargeting
- type Campaign
- type CampaignReport
- type Click
- type Client
- func (c *Client) AsUser(ctx context.Context, uid string) (nc *Client, err error)
- func (c *Client) Clicks(ctx context.Context, clicksAddr string, date time.Time, uid, cid string) (out []byte, err error)
- func (c *Client) CreateAd(ctx context.Context, uid string, req *CreateAdRequest) (ad *Ad, err error)
- func (c *Client) CreateAdFromFile(ctx context.Context, uid string, req *CreateAdRequest, filename string) (ad *Ad, err error)
- func (c *Client) CreateAdGroup(ctx context.Context, uid, name string) (id string, err error)
- func (c *Client) CreateAdvertiser(ctx context.Context, req *CreateAdvertiserRequest) (uid string, err error)
- func (c *Client) CreateCampaign(ctx context.Context, uid string, cmp *Campaign) (string, error)
- func (c *Client) CreateDraftCampaign(ctx context.Context, uid string, cmp *Campaign) (string, error)
- func (c *Client) CreateFullCampaign(ctx context.Context, uid string, req *CreateFullCampaignRequest) (cmp *Campaign, err error)
- func (c *Client) CreateProximitySegment(ctx context.Context, uid string, seg *ProximitySegment) (id string, err error)
- func (c *Client) CreateSegment(ctx context.Context, uid string, seg *Segment) (id string, err error)
- func (c *Client) CurrentKey() string
- func (c *Client) DeleteAd(ctx context.Context, adID string) (err error)
- func (c *Client) DeleteAdGroup(ctx context.Context, adgroupID string) (err error)
- func (c *Client) DeleteCampaign(ctx context.Context, cid string) error
- func (c *Client) DeleteDraftCampaign(ctx context.Context, cid string) error
- func (c *Client) DeleteProximitySegment(ctx context.Context, segID string) (err error)
- func (c *Client) DeleteSegment(ctx context.Context, segID string) (err error)
- func (c *Client) GetAPIVersion(ctx context.Context) (ver string, err error)
- func (c *Client) GetAdsReport(ctx context.Context, uid string, start, end time.Time) (rp map[string]*AdReport, err error)
- func (c *Client) GetCampaign(ctx context.Context, cid string) (*Campaign, error)
- func (c *Client) GetCampaignReport(ctx context.Context, uid, cid string, start, end time.Time) (cs *CampaignReport, err error)
- func (c *Client) GetDraftCampaign(ctx context.Context, cid string) (*Campaign, error)
- func (c *Client) GetHeatmap(ctx context.Context, uid string) (out *Heatmap, err error)
- func (c *Client) GetUserAPIKey(ctx context.Context, uid string) (apiKey string, err error)
- func (c *Client) GetUserID(ctx context.Context) (uid string, err error)
- func (c *Client) ListAdGroups(ctx context.Context, uid string) (ags map[string]*AdGroup, err error)
- func (c *Client) ListAds(ctx context.Context, uid string) (ads map[string]*Ad, err error)
- func (c *Client) ListAdsByAdGroup(ctx context.Context, uid, adGroupID string) (map[string]*Ad, error)
- func (c *Client) ListAdsFilter(ctx context.Context, uid string, filterFn func(ad *Ad) bool) (ads map[string]*Ad, err error)
- func (c *Client) ListAdvertisers(ctx context.Context, agencyID string) (out map[string]*Advertiser, err error)
- func (c *Client) ListAgencies(ctx context.Context) (out map[string]*Agency, err error)
- func (c *Client) ListCampaigns(ctx context.Context, uid string) (map[string]*Campaign, error)
- func (c *Client) ListDraftCampaigns(ctx context.Context, uid string) (map[string]*Campaign, error)
- func (c *Client) ListProximitySegments(ctx context.Context, uid string) (segs map[string]*ProximitySegment, err error)
- func (c *Client) ListSegments(ctx context.Context, uid string) (segs map[string]*Segment, err error)
- func (c *Client) ListStoreVisits(ctx context.Context, uid string) (segs map[string]*ProximitySegment, err error)
- func (c *Client) RawRequest(method, endpoint string, req, resp interface{}) (err error)
- func (c *Client) RawRequestCtx(ctx context.Context, method, endpoint string, req, resp interface{}) (err error)
- func (c *Client) Receipts(ctx context.Context, sc *ssync.Client, date time.Time, uid, cid string) (out []byte, err error)
- func (c *Client) UpdateAd(ctx context.Context, ad *Ad) error
- func (c *Client) UpdateCampaign(ctx context.Context, cmp *Campaign) error
- func (c *Client) UpdateDraftCampaign(ctx context.Context, cmp *Campaign) error
- func (c *Client) UpdateProximitySegment(ctx context.Context, seg *ProximitySegment) (err error)
- func (c *Client) UpdateSegment(ctx context.Context, seg *Segment) (err error)
- func (c *Client) UpgradeCampaign(ctx context.Context, uid, draftCampaignID string) (cid string, err error)
- func (c *Client) Visits(ctx context.Context, visitsAddr string, date time.Time, uid, cid string) (out []byte, err error)
- type Coords
- type CreateAdRequest
- type CreateAdvertiserRequest
- type CreateFullCampaignRequest
- type Heatmap
- type ImpClick
- type Location
- type ProximitySegment
- type Receipt
- type Rect
- type Segment
- type SpecificTargeting
- type UUIDTargeting
- type Visit
Constants ¶
const ( CampaignMinimumBudget = 1 CampaignMaximumBudget = 300 CampaignMaximumImpBudget = 100000 )
const ( // Version is the current SDK version Version = "v0.6" // DefaultServer is the default api server used DefaultServer = "https://meteora.us" )
Variables ¶
var ( ErrMissingUID = errors.New("missing user id") ErrBadUID = errors.New("bad user id") ErrMissingCID = errors.New("missing campaign id") ErrMissingSegID = errors.New("missing segment id") ErrMissingSegName = errors.New("missing segment name") ErrMissingProxSegName = errors.New("missing proximity segment name") ErrMissingLocations = errors.New("must specify at least one proximity location") ErrDateRange = errors.New("bad or missing date range") ErrInvalidName = errors.New("invalid name") ErrInvalidAgencyID = errors.New("invalid agency id") ErrInvalidEmail = errors.New("invalid email") ErrInvalidPassword = errors.New("password must be at least 8 characters") ErrInvalidLanding = errors.New("invalid landing url") ErrMissingAdImage = errors.New("missing ad image or third party code") ErrMissingAds = errors.New("must pass at least one ad") ErrInvalidAdSize = fmt.Errorf("invalid ad size, the accepted sizes are: %s", AllowedAdRectsString()) ErrInvalidBudget = fmt.Errorf("invalid budget, must be between $%d and %d", CampaignMinimumBudget, CampaignMaximumBudget) ErrInvalidImpBudget = fmt.Errorf("invalid imp budget, must be less than %d", CampaignMaximumImpBudget) ErrInvalidSchedule = errors.New("invalid schedule provided") ErrRequestIsNil = errors.New("request is nil") ErrCampaignIsNil = errors.New("campaign is nil") ErrInvalidSSyncClient = errors.New("invalid ssync client") ErrMissingClicksServer = errors.New("missing clicks server") ErrMissingVisitsServer = errors.New("missing visits server") ErrInternal = errors.New("internal error") )
common errors
var AllApps = []App{ AppAdvBidding{}, AppSearchRetargeting{}, AppDomainTargeting{}, AppGeography{}, UUIDTargeting{}, }
var (
AllTime = time.Unix(-1, 0)
)
var DefaultApps = []App{ &AppPacing{Status: true}, }
DefaultApps are the default apps to be added to a new empty campaign.
Functions ¶
func AllowedAdRectsString ¶
func AllowedAdRectsString() string
func DateToTime ¶
func RawMarshal ¶
func RawMarshal(v interface{}) *json.RawMessage
Types ¶
type Ad ¶
type Ad struct { ID string `json:"id,omitempty"` GroupID string `json:"group,omitempty"` AdvertiserID string `json:"advertiserID,omitempty"` Active bool `json:"active,omitempty"` Clicks int `json:"clicks,omitempty"` Conv int `json:"conv,omitempty"` Width int `json:"width,omitempty"` Height int `json:"height,omitempty"` Imps int `json:"imps,omitempty"` AdType string `json:"adType,omitempty"` ImageKey string `json:"imageKey,omitempty"` ImageLocation string `json:"imageLocation,omitempty"` Name string `json:"name,omitempty"` Size string `json:"size,omitempty"` LandingURL string `json:"landingURL,omitempty"` ImpTracker string `json:"impTrack,omitempty"` ClickTracker string `json:"clickTrack,omitempty"` // Third party ThirdPartyCode string `json:"thirdPartyCode,omitempty"` }
Ad is mostly a trimmed down version of api/server/types.Ad
type AdGroup ¶
type AdGroup struct { ID string `json:"id"` Name string `json:"name"` AdCount int `json:"adCount"` }
AdGroup represents an ad group
type AdReport ¶
type AdReport struct { ID string `json:"id"` Imp int64 `json:"imp,omitempty"` Clicks int64 `json:"clicks,omitempty"` Spent float64 `json:"spent,omitempty"` }
AdReport represents a basic ad report
type AdsListItem ¶
AdsListItem is a copied type from API for compatibility with the Heatmap JS lib
type Advertiser ¶
type Advertiser struct { ID string `json:"id"` PathID string `json:"pathID"` AgencyID string `json:"agencyID"` Name string `json:"name"` NumCampaigns int `json:"numCmps"` Status bool `json:"status"` }
Advertiser represents an advertiser user
type AppAdvBidding ¶
type AppAdvBidding struct { Status bool `json:"status"` BaseCPM float64 `json:"baseCpm"` MaxCPM float64 `json:"maxCpm"` }
func (AppAdvBidding) Name ¶
func (AppAdvBidding) Name() string
type AppDomainTargeting ¶
type AppDomainTargeting struct { Targeted []string `json:"targeted"` Banned []string `json:"banned"` }
func (AppDomainTargeting) Name ¶
func (AppDomainTargeting) Name() string
type AppGeography ¶
type AppGeography struct { Status bool `json:"status"` Cities []string `json:"cities"` States []string `json:"states"` Zipcodes []string `json:"zipCodes"` DMAs []string `json:"dmas"` }
func (AppGeography) Name ¶
func (AppGeography) Name() string
type AppSearchRetargeting ¶
func (AppSearchRetargeting) Name ¶
func (AppSearchRetargeting) Name() string
type Campaign ¶
type Campaign struct { ID string `json:"id"` OwnerID string `json:"ownerID"` Active bool `json:"active"` Archived bool `json:"archived,omitempty"` Name string `json:"name"` Notes string `json:"notes,omitempty"` Budget float64 `json:"budget"` ImpBudget uint32 `json:"impBudget"` Created int64 `json:"created"` Scheduled bool `json:"scheduled"` Start int64 `json:"start"` End int64 `json:"end"` Segments []string `json:"segments,omitempty"` Adgroups []string `json:"adGroups,omitempty"` Apps map[string]*json.RawMessage `json:"apps,omitempty"` Searches []string `json:"searches,omitempty"` }
Campaign is a QoL alias for campaigns.Campaign
type CampaignReport ¶
type CampaignReport struct { ID string `json:"id"` Imp int64 `json:"imp,omitempty"` Clicks int64 `json:"clicks,omitempty"` Spent float64 `json:"spent,omitempty"` Period uint32 `json:"reportingPeriod,omitempty"` Domains map[string]ImpClick `json:"domains,omitempty"` Visits []Visit `json:"visits,omtiempty"` // est visits please see terms }
CampaignReport represents a basic campaign report
type Click ¶
type Click = struct { X int `json:"x"` Y int `json:"y"` // TTC represents time to click (in milliseconds) TTC int `json:"ttc,omitempty"` UUID string `json:"uuid"` AdID string `json:"adID"` TS int64 `json:"ts"` }
Click is a click action
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is a Meteora API client. All client funcs require a context.Context, however it can be set to nil.
func NewWithAddr ¶
NewWithAddr returns a new instance of Client with the given api addr and key. If testing locally on an unsecure https server, use https+insecure://localhost:8080.
func (*Client) AsUser ¶
AsUser fetches the given uid's api key and returns a new client using it or an error.
func (*Client) CreateAd ¶
func (c *Client) CreateAd(ctx context.Context, uid string, req *CreateAdRequest) (ad *Ad, err error)
CreateAd will create an Advertisement for a given user ID
func (*Client) CreateAdFromFile ¶
func (c *Client) CreateAdFromFile(ctx context.Context, uid string, req *CreateAdRequest, filename string) (ad *Ad, err error)
CreateAdFromFile will create an Advertisement for a given user ID using a given filename
func (*Client) CreateAdGroup ¶
CreateAdGroup will create an adgroup by the owning user ID
func (*Client) CreateAdvertiser ¶
func (*Client) CreateCampaign ¶
CreateCampaign will create a campaign for a given user ID
func (*Client) CreateDraftCampaign ¶
func (c *Client) CreateDraftCampaign(ctx context.Context, uid string, cmp *Campaign) (string, error)
CreateDraftCampaign will create a draft campaign for a given user ID
func (*Client) CreateFullCampaign ¶
func (c *Client) CreateFullCampaign(ctx context.Context, uid string, req *CreateFullCampaignRequest) (cmp *Campaign, err error)
CreateFullCampaign takes full control of the passed request, reusing it can cause races and/or crashes. A new ADGroup will be created for this request and filled in with the ads, and appended to cmp.Adgroups.
func (*Client) CreateProximitySegment ¶
func (c *Client) CreateProximitySegment(ctx context.Context, uid string, seg *ProximitySegment) (id string, err error)
CreateProxSegment will create a proximity segment for a given user ID
func (*Client) CreateSegment ¶
func (c *Client) CreateSegment(ctx context.Context, uid string, seg *Segment) (id string, err error)
CreateSegment will create a new segment for a given user ID
func (*Client) CurrentKey ¶
CurrentKey returns the API key used to initalize this client
func (*Client) DeleteAdGroup ¶
DeleteAdGroup will delete an adgroup by it's ID
func (*Client) DeleteCampaign ¶
DeleteCampaign will delete a campaign by it's ID
func (*Client) DeleteDraftCampaign ¶
DeleteDraftCampaign will delete a draft campaign by it's ID
func (*Client) DeleteProximitySegment ¶
DeleteProxSegment will delete a proximity segment by it's ID
func (*Client) DeleteSegment ¶
DeleteSegment will delete a segment by it's ID
func (*Client) GetAPIVersion ¶
GetAPIVersion will get the current API version
func (*Client) GetAdsReport ¶
func (c *Client) GetAdsReport(ctx context.Context, uid string, start, end time.Time) (rp map[string]*AdReport, err error)
GetAdsReport will generate a advertisements report for a given user ID and date range
func (*Client) GetCampaign ¶
GetCampaign will get a campaign by campaign id
func (*Client) GetCampaignReport ¶
func (c *Client) GetCampaignReport(ctx context.Context, uid, cid string, start, end time.Time) (cs *CampaignReport, err error)
GetCampaignReport will generate a report for a given campaign ID and date range
func (*Client) GetDraftCampaign ¶
GetDraftCampaign will get a campaign by campaign id
func (*Client) GetHeatmap ¶
GetHeatmap will return the heatmaps belonging to a user ID
func (*Client) GetUserAPIKey ¶
GetUserAPIKey will return a user's API key
func (*Client) ListAdGroups ¶
ListAdGroups will list all the adgroups for a given user id
func (*Client) ListAdsByAdGroup ¶
func (c *Client) ListAdsByAdGroup(ctx context.Context, uid, adGroupID string) (map[string]*Ad, error)
ListAdsByAdGroup will list all ads for a user and ad group
func (*Client) ListAdsFilter ¶
func (c *Client) ListAdsFilter(ctx context.Context, uid string, filterFn func(ad *Ad) bool) (ads map[string]*Ad, err error)
ListAdsFilter will list ads which pass a given filter
func (*Client) ListAdvertisers ¶
func (c *Client) ListAdvertisers(ctx context.Context, agencyID string) (out map[string]*Advertiser, err error)
ListAdvertisers will list the advertisers for a given agency
func (*Client) ListAgencies ¶
ListAgencies will list the agencies
func (*Client) ListCampaigns ¶
ListCampaigns will list all the campaigns for a given user id
func (*Client) ListDraftCampaigns ¶
ListDraftCampaigns will list all the draft campaigns for a given user id
func (*Client) ListProximitySegments ¶
func (c *Client) ListProximitySegments(ctx context.Context, uid string) (segs map[string]*ProximitySegment, err error)
ListProxSegments will list the proximity segments belonging to a given user ID
func (*Client) ListSegments ¶
func (c *Client) ListSegments(ctx context.Context, uid string) (segs map[string]*Segment, err error)
ListSegments will list the segments belonging to a given user ID
func (*Client) ListStoreVisits ¶
func (c *Client) ListStoreVisits(ctx context.Context, uid string) (segs map[string]*ProximitySegment, err error)
ListProxSegments will list the store visits belonging to a given user ID
func (*Client) RawRequest ¶
RawRequest is an alias for RawRequestCtx(context.Background(), method, endpoint, req, resp)
func (*Client) RawRequestCtx ¶
func (c *Client) RawRequestCtx(ctx context.Context, method, endpoint string, req, resp interface{}) (err error)
RawRequestCtx allows a raw c.raw request to the given endpoint
func (*Client) UpdateCampaign ¶
UpdateCampaign will update a campaign
func (*Client) UpdateDraftCampaign ¶
UpdateDraftCampaign will update a draft campaign
func (*Client) UpdateProximitySegment ¶
func (c *Client) UpdateProximitySegment(ctx context.Context, seg *ProximitySegment) (err error)
UpdateProxSegment will update a proximity segment by it's ID
func (*Client) UpdateSegment ¶
UpdateSegment will update a segment by it's ID
func (*Client) UpgradeCampaign ¶
func (c *Client) UpgradeCampaign(ctx context.Context, uid, draftCampaignID string) (cid string, err error)
UpgradeCampaign will attempt to upgrade a draft campaign to a full campaign and returning new campaign id. note that it may return an error and a campaign id if deleting the draft campaign fails after creating the full campaign.
type Coords ¶
type Coords struct { // Note, the json keys for these values are setup to match google's coordinate object Latitude float64 `json:"lat"` Longitude float64 `json:"lng"` }
Coords are a set of coordinates
type CreateAdRequest ¶
type CreateAdRequest struct { Name string `json:"name,omitempty"` Width int `json:"width,omitempty"` Height int `json:"height,omitempty"` LandingURL string `json:"landingURL,omitempty"` // Everything below here is optional GroupID string `json:"group,omitempty"` ImpTracker string `json:"impTrack,omitempty"` ClickTracker string `json:"clickTrack,omitempty"` Encoded bool `json:"encoded,omitempty"` AdImage interface{} `json:"adImage,omitempty"` // Third party ThirdPartyCode string `json:"thirdPartyCode,omitempty"` }
CreateAdRequest is the request needed to create an Ad
type CreateAdvertiserRequest ¶
type CreateAdvertiserRequest struct { Name string `json:"company"` // required Email string `json:"email"` // required AgencyID string `json:"agency"` // Required AdvertiserFee int `json:"advertiserFee"` // required Password string `json:"pass"` // optional, needed only if you want to login from the meteora dash PasswordConfirm string `json:"passConfirm"` // not needed, filled automatically if password is set Status bool `json:"status"` // automatically set }
type CreateFullCampaignRequest ¶
type CreateFullCampaignRequest struct { Campaign *Campaign `json:"campaign,omitempty"` // required Ads []*CreateAdRequest `json:"ads,omitempty"` // required CampaignApps []App `json:"campaignApps,omitempty"` Segments []*Segment `json:"segments,omitempty"` // optional ProximitySegment []*ProximitySegment `json:"proximitySegment,omitempty"` // optional IsDraft bool `json:"isDraft"` // contains filtered or unexported fields }
func (*CreateFullCampaignRequest) Rollback ¶
func (req *CreateFullCampaignRequest) Rollback(c *Client)
deletes any partially created resources
type Heatmap ¶
type Heatmap struct { AdsList []*AdsListItem `json:"adsList"` Clicks []*Click `json:"clicks"` }
Heatmap contains the raw Heatmap data from API
func (*Heatmap) ClicksByAds ¶
ClicksByAds returns a map of a slice of clicks by Ad ID.
type Location ¶
type Location struct { // ID of location ID string `json:"id"` // Label of the location Label string `json:"label"` // Type of location, can be "circle" or "polygon" Type string `json:"type"` // Center coordinates of the location Center Coords `json:"center"` // Radius in meters Radius float64 `json:"radius"` // Points for drawing on map, this is only used for polygons Points []Coords `json:"points"` }
Location represents a specified location
type ProximitySegment ¶
type ProximitySegment struct { ID string `json:"id,omitempty"` // this is strictly used by the SDK Name string `json:"name"` OwnerID string `json:"ownerID"` // Current location id IDCounter int `json:"idCounter,omitempty"` // List of locations Locations []*Location `json:"locations"` // List of deletedLocations DeletedLocations []*Location `json:"deletedLocations,omitempty"` // Lookback period Lookback int16 `json:"lookback,omitempty"` }
Segment is a segment by proximity location
type Receipt ¶
type Receipt struct { CID string `json:"id"` // Campaign id AdvID string `json:"advertiserId"` // Advertiser id SegID string `json:"segID,omitempty"` // Segment id ImpID string `json:"impid"` // Meteora impression id AdID string `json:"adId"` // Ad id UUID string `json:"uuid"` // User id for ad viewer Timestamp int64 `json:"timestamp"` // Timestamp of win Amount float64 `json:"amount,omitempty"` // Cost of the impression (true value) [Deprecated] Credits int64 `json:"credits,omitempty"` // Cost of the impression (true value * 1,000,000) Domain string `json:"domain,omitempty"` // Domain the ad was served on Services string `json:"usedSvc,omitempty"` // Comma separated list of services used for the impression Inventory string `json:"invt,omitempty"` // Platform used to view impression (IE desktop, mobile, mobile app) ExID string `json:"svc"` // Servicer (exchange) id ExImpID string `json:"eid,omitempty"` // Exchange-provided impression id ExInfo string `json:"exInfo,omitempty"` // Miscellaneous exchange information PxID string `json:"pxID,omitempty"` // Proximity target id Lat float64 `json:"lat,omitempty"` Long float64 `json:"long,omitempty"` }
type Segment ¶
type Segment struct { // Name is required for Create Name string `json:"name,omitempty"` SegmentID string `json:"segmentID,omitempty"` AdvertiserID string `json:"advertiserID,omitempty"` Active bool `json:"active,omitempty"` TargetConsumers string `json:"targetConsumers,omitempty"` MinimumPageViews int `json:"minimumPageViews,omitempty"` VisitedSiteAtLeast int `json:"visitedSiteAtLeast,omitempty"` UniqueUsers int `json:"uniqueUsers,omitempty"` AvgPurchase int `json:"avgPurchase,omitempty"` PreviouslySpentBetween []int `json:"previouslySpentBetween,omitempty"` LastVisitedBetween []int `json:"lastVisitedBetween,omitempty"` ViewedProductsBetween []int `json:"viewedProductsBetween,omitempty"` UrlsVisited []string `json:"urlsVisited,omitempty"` SkusVisited []string `json:"skusVisited,omitempty"` IncludeParams []string `json:"includeParams,omitempty"` ExcludeParams []string `json:"excludeParams,omitempty"` }
Segment is a normal user segment
type SpecificTargeting ¶
type SpecificTargeting struct { Status bool `json:"status"` Inventory []string `json:"inventory,omitempty"` Devices []string `json:"devices,omitempty"` Browsers []string `json:"browsers,omitempty"` Exchanges []string `json:"exchanges,omitempty"` }
func (SpecificTargeting) Name ¶
func (SpecificTargeting) Name() string
type UUIDTargeting ¶
type UUIDTargeting struct { Whitelist []string `json:"whitelist"` Blacklist []string `json:"blacklist"` Status bool `json:"status"` }
func (UUIDTargeting) Name ¶
func (UUIDTargeting) Name() string
type Visit ¶
type Visit struct { CampaignID string `json:"cid,omitempty"` ProximityID string `json:"pxID,omitempty"` Name string `json:"pxName,omitempty"` StoreName string `json:"storeName,omitempty"` StoreID string `json:"storeID,omitempty"` TS int64 `json:"ts,omitempty"` IFA string `json:"IFA,omitempty"` }
/ Visit is a single visit details