diff --git a/CHANGELOG.md b/CHANGELOG.md index 4122180..41e9b2a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 2.4.0 + +* added funnel endpoints +* fixed missing regions parameter for filter + ## 2.3.1 * added missing event metadata field diff --git a/pkg/client.go b/pkg/client.go index 7a571df..c9d8cad 100644 --- a/pkg/client.go +++ b/pkg/client.go @@ -58,6 +58,8 @@ const ( tagKeysEndpoint = "/api/v1/statistics/tags" tagDetailsEndpoint = "/api/v1/statistics/tag/details" keywordsEndpoint = "/api/v1/statistics/keywords" + listFunnelEndpoint = "/api/v1/funnel?id=%s" + funnelEndpoint = "/api/v1/statistics/funnel" ) var referrerQueryParams = []string{ @@ -581,6 +583,28 @@ func (client *Client) Keywords(filter *Filter) ([]Keyword, error) { return stats, nil } +// ListFunnel returns a list of all funnels including step definition for given domain ID. +func (client *Client) ListFunnel(id string) ([]Funnel, error) { + funnel := make([]Funnel, 0) + + if err := client.performGet(client.baseURL+fmt.Sprintf(listFunnelEndpoint, id), client.requestRetries, &funnel); err != nil { + return nil, err + } + + return funnel, nil +} + +// Funnel returns a funnel definition and statistics for given funnel ID and filter. +func (client *Client) Funnel(id string, filter *Filter) (*FunnelData, error) { + var funnel FunnelData + + if err := client.performGet(client.getStatsRequestURL(funnelEndpoint, filter)+fmt.Sprintf("&funnel_id=%s", id), client.requestRetries, &funnel); err != nil { + return nil, err + } + + return &funnel, nil +} + func (client *Client) getPageViewData(r *http.Request, options *PageViewOptions) PageView { return PageView{ URL: client.selectField(options.URL, r.URL.String()), @@ -817,6 +841,7 @@ func (client *Client) getStatsRequestURL(endpoint string, filter *Filter) string client.setURLParams(v, "event_meta_key", filter.EventMetaKey) client.setURLParams(v, "language", filter.Language) client.setURLParams(v, "country", filter.Country) + client.setURLParams(v, "region", filter.Region) client.setURLParams(v, "city", filter.City) client.setURLParams(v, "referrer", filter.Referrer) client.setURLParams(v, "referrer_name", filter.ReferrerName) diff --git a/pkg/client_test.go b/pkg/client_test.go index 1c07a62..cd6f31e 100644 --- a/pkg/client_test.go +++ b/pkg/client_test.go @@ -33,12 +33,27 @@ func TestNewClient(t *testing.T) { baseURL := os.Getenv("PIRSCH_BASE_URL") if clientID != "" && clientSecret != "" { + t.Logf("Using base URL: %s", baseURL) client := NewClient(clientID, clientSecret, &ClientConfig{ BaseURL: baseURL, }) d, err := client.Domain() assert.NoError(t, err) assert.NotNil(t, d) + funnels, err := client.ListFunnel(d.ID) + assert.NoError(t, err) + assert.NotEmpty(t, funnels) + + for _, funnel := range funnels { + f, err := client.Funnel(funnel.ID, &Filter{ + DomainID: d.ID, + From: time.Now().Add(-time.Hour * 24 * 30), + To: time.Now(), + }) + assert.NoError(t, err) + assert.NotEmpty(t, f.Definition.ID) + assert.NotEmpty(t, f.Data) + } } } diff --git a/pkg/types.go b/pkg/types.go index 62d6fde..0ae83a4 100644 --- a/pkg/types.go +++ b/pkg/types.go @@ -445,3 +445,39 @@ type Keyword struct { CTR float64 `json:"ctr"` Position float64 `json:"position"` } + +// Funnel is the definition of a funnel. +type Funnel struct { + BaseEntity + + DomainID string `json:"domain_id"` + Name string `json:"name"` + Steps []FunnelStep `json:"steps"` +} + +// FunnelStep is the definition of a funnel step. +type FunnelStep struct { + BaseEntity + + FunnelID string `json:"funnel_id"` + Name string `json:"name"` + Step int `json:"step"` + Filter Filter `json:"filter"` +} + +// FunnelStepData is the result type for a funnel step. +type FunnelStepData struct { + Step int `json:"step"` + Visitors int `json:"visitors"` + RelativeVisitors float64 `json:"relative_visitors"` + PreviousVisitors int `json:"previous_visitors"` + RelativePreviousVisitors float64 `json:"relative_previous_visitors"` + Dropped int `json:"dropped"` + DropOff float64 `json:"drop_off"` +} + +// FunnelData is the response type for the funnel definition and statistics. +type FunnelData struct { + Definition *Funnel `json:"definition"` + Data []FunnelStepData `json:"data"` +}