Skip to content

Commit

Permalink
feat(ga): upgrade measurement protocol to GA4 from UA
Browse files Browse the repository at this point in the history
Signed-off-by: Niladri Halder <niladri.halder26@gmail.com>
  • Loading branch information
niladrih committed Jul 18, 2023
1 parent 6944921 commit 09756cd
Show file tree
Hide file tree
Showing 23 changed files with 352 additions and 7,661 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
example/tracker-id.txt
example/tracker-id.txt
**/.idea
64 changes: 39 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,58 +2,72 @@

Track and monitor your Go programs for free with Google Analytics

The `ga` package is essentially a Go wrapper around the [Google Analytics - Measurement Protocol](https://developers.google.com/analytics/devguides/collection/protocol/v1/reference)

**Warning** This package is 95% generated from the [Parameter Reference](https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters) so it may contain bugs - please report them. GA allows "10 million hits per month per property" and will reject requests after that.
The `ga` package is essentially a Go wrapper around the [Google Analytics - Measurement Protocol (Google Analytics 4)](https://developers.google.com/analytics/devguides/collection/protocol/ga4/reference?client_type=gtag)

### Install

```
go get -v github.com/jpillora/go-ogle-analytics
go get -v github.com/openebs/go-ogle-analytics
```

### API

Create a new `client` and `Send()` a 'pageview', 'screenview', 'event', 'transaction', 'item', 'social', 'exception' or 'timing' event.

#### http://godoc.org/github.com/jpillora/go-ogle-analytics
Create a new `client` and `Send()` an 'event'.

### Quick Usage

1. Log into GA and create a new property and note its Tracker ID
1. Log into GA and create a new property and note its Measurement ID

1. Create a `ga-test.go` file
2. Create a `ga-test.go` file

``` go
package main

import "github.com/jpillora/go-ogle-analytics"
import (
gaClient "github.com/openebs/go-ogle-analytics/client"
gaEvent "github.com/openebs/go-ogle-analytics/event"
)

func main() {
client, err := ga.NewClient("UA-XXXXXXXX-Y")
if err != nil {
panic(err)
}

err = client.Send(ga.NewEvent("Foo", "Bar").Label("Bazz"))
if err != nil {
panic(err)
}

println("Event fired!")
}
client, err := gaClient.NewMeasurementClient(
gaClient.WithApiSecret("yourApiSecret"),
gaClient.WithMeasurementId("G-yourMeasurementClient"),
gaClient.WithClientId("uniqueUserId-000000001"),
)
if err != nil {
panic(err)
}

event, err := gaEvent.NewOpenebsEvent(
gaEvent.WithCategory("Foo"),
gaEvent.WithAction("Bar"),
gaEvent.WithLabel("Baz"),
gaEvent.WithValue(19072023),
)
if err != nil {
panic(err)
}

err = client.Send(event)
if err != nil {
panic(err)
}

println("Event fired!")
}

```

1. In GA, go to Real-time > Events
3. In GA, go to Report > Realtime

1. Run `ga-test.go`
4. Run `ga-test.go`

```
$ go run ga-test.go
Event fired!
```

1. Watch as your event appears
5. Watch as your event appears

![foo-ga](https://cloud.githubusercontent.com/assets/633843/5979585/023fc580-a8fd-11e4-803a-956610bcc2e2.png)

Expand Down
91 changes: 0 additions & 91 deletions client.go

This file was deleted.

87 changes: 87 additions & 0 deletions client/build.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package client

import (
"context"
"net"
"net/http"
"regexp"

"github.com/openebs/lib-csi/pkg/common/errors"
)

var measurementIDMatcher = regexp.MustCompile(`^G-[a-zA-Z0-9]+$`)

type MeasurementClientOption func(*MeasurementClient) error

type MeasurementClient struct {
HttpClient *http.Client
apiSecret string
measurementId string
clientId string
}

func NewMeasurementClient(opts ...MeasurementClientOption) (*MeasurementClient, error) {
dialer := &net.Dialer{
Resolver: &net.Resolver{
PreferGo: true,
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
dialer := net.Dialer{}
return dialer.DialContext(ctx, network, "8.8.8.8:53")
},
},
}
c := &MeasurementClient{
HttpClient: &http.Client{
Transport: &http.Transport{
DialContext: dialer.DialContext,
},
},
}

var err error
for _, opt := range opts {
err = opt(c)
if err != nil {
return nil, errors.Wrap(err, "failed to build MeasurementClient")
}
}

return c, nil
}

func WithApiSecret(secret string) MeasurementClientOption {
return func(s *MeasurementClient) error {
if len(secret) == 0 {
return errors.Errorf("failed to set api_secret: secret is an empty string")
}

s.apiSecret = secret
return nil
}
}

func WithMeasurementId(measurementId string) MeasurementClientOption {
return func(s *MeasurementClient) error {
if len(measurementId) == 0 {
return errors.Errorf("failed to set measurement_id: id is an empty string")
}

if !measurementIDMatcher.MatchString(measurementId) {
return errors.Errorf("Invalid measurement_id: %s", measurementId)
}

s.measurementId = measurementId
return nil
}
}

func WithClientId(clientId string) MeasurementClientOption {
return func(s *MeasurementClient) error {
if len(clientId) == 0 {
return errors.Errorf("failed to set client_id: id is an empty string")
}

s.clientId = clientId
return nil
}
}
61 changes: 61 additions & 0 deletions client/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package client

import (
"bytes"
"encoding/json"
"net/http"
"net/url"

"github.com/openebs/lib-csi/pkg/common/errors"

"github.com/openebs/go-ogle-analytics/event"
"github.com/openebs/go-ogle-analytics/payload"
)

func (c *MeasurementClient) Copy() *MeasurementClient {
cpy := *c
return &cpy
}

func (c *MeasurementClient) addFields(v url.Values) {
v.Add("api_secret", c.apiSecret)
v.Add("measurement_id", c.measurementId)
}

func (c *MeasurementClient) Send(event *event.OpenebsEvent) error {

client := c.Copy()

dataPayload, err := payload.NewPayload(
payload.WithClientId(client.clientId),
payload.WithOpenebsEvent(event),
)

if err != nil {
return err
}
jsonData, err := json.Marshal(dataPayload)
if err != nil {
return err
}

gaUrl := "https://www.google-analytics.com/mp/collect"

req, err := http.NewRequest("POST", gaUrl, bytes.NewReader(jsonData))
v := req.URL.Query()
client.addFields(v)
req.URL.RawQuery = v.Encode()

req.Header.Set("Content-Type", "application/json")

resp, err := client.HttpClient.Do(req)
if err != nil {
return err
}

if resp.StatusCode/100 != 2 {
return errors.Errorf("Rejected by Google with code %d", resp.StatusCode)
}

return nil
}
19 changes: 0 additions & 19 deletions conv.go

This file was deleted.

Loading

0 comments on commit 09756cd

Please sign in to comment.