Google Analytics 4 (Measurement Protocol) sender for strongo/analytics.
Sends analytics events to GA4 via the Measurement Protocol using HTTP POST — no browser or JavaScript required.
go get github.com/strongo/analytics2ga4- In GA4 Admin → Data Streams, open your web/app stream and note the Measurement ID (e.g.
G-XXXXXXXXXX). - Scroll down to Measurement Protocol API secrets and create a new secret. Copy the secret value.
- Both values go into the
Clientstruct. Each GA4 property × stream combination needs its ownClient.
Same property / same stream: All events from one
Clientland in one GA4 data stream. To fan events to multiple properties (e.g. dev + prod), add multipleCliententries toNewSender.
import (
"github.com/strongo/analytics"
"github.com/strongo/analytics2ga4"
)
// Wire up once during application startup.
sender, err := analytics2ga4.NewSender(myLogger,
analytics2ga4.Client{
MeasurementID: "G-XXXXXXXXXX",
APISecret: "your-api-secret",
},
)
if err != nil {
log.Fatal(err)
}
analytics.AddSender(sender)
// Then anywhere in your code:
msg := analytics.NewEvent("command_received", "bot", "start")
msg.SetUserContext(analytics.NewUserContext(strconv.FormatInt(telegramUserID, 10)))
analytics.QueueMessage(ctx, msg)analytics2ga4.Client{
MeasurementID: "G-XXXXXXXXXX",
APISecret: "secret",
Endpoint: "https://www.google-analytics.com/mp/collect", // default
HTTPClient: &http.Client{Timeout: 5 * time.Second},
}- Every event automatically includes
session_id(derived from client ID + UTC day) andengagement_time_msec=1; without these, events are silently dropped from standard and realtime GA4 reports. - Event names are sanitised to GA4 rules: alphanumerics and underscores, starting with a letter, max 40 characters.
surface=telegram_botis injected into every event's params unless the message already carries asurfaceproperty.- Multiple clients → fan-out: one HTTP POST per client per
QueueMessagecall.
| analytics type | GA4 event name | Notable params |
|---|---|---|
analytics.Event |
sanitised event name | action, label, value, category |
analytics.Pageview |
page_view |
page_location, page_title |
analytics.ErrorMessage |
app_exception |
description, fatal=0 |
analytics.Timing |
sanitised event name | duration_ms |
MIT