1
0
mirror of https://github.com/taigrr/wtf synced 2025-01-18 04:03:14 -08:00
Chris Cummer 3a388fba23
20191215 code improvements (#790)
* Upgrade godo to latest
* Fix a bunch of issues found by
* Running staticcheck on a codebase for the first time is a sobering experience
* go mod tidy
* More static improvements

Signed-off-by: Chris Cummer <chriscummer@me.com>
2019-12-16 20:25:29 -08:00

135 lines
3.7 KiB
Go

package googleanalytics
import (
"context"
"fmt"
"io/ioutil"
"log"
"net/http"
"time"
"github.com/wtfutil/wtf/utils"
"golang.org/x/oauth2/google"
gaV3 "google.golang.org/api/analytics/v3"
gaV4 "google.golang.org/api/analyticsreporting/v4"
"google.golang.org/api/option"
)
type websiteReport struct {
Name string
Report *gaV4.GetReportsResponse
RealtimeReport *gaV3.RealtimeData
}
func (widget *Widget) Fetch() []websiteReport {
secretPath, err := utils.ExpandHomeDir(widget.settings.secretFile)
if err != nil {
log.Fatalf("Unable to parse secretFile path")
}
serviceV4, err := makeReportServiceV4(secretPath)
if err != nil {
log.Fatalf("Unable to create v3 Google Analytics Reporting Service")
}
var serviceV3 *gaV3.Service
if widget.settings.enableRealtime {
serviceV3, err = makeReportServiceV3(secretPath)
if err != nil {
log.Fatalf("Unable to create v3 Google Analytics Reporting Service")
}
}
visitorsDataArray := getReports(
serviceV4, widget.settings.viewIds, widget.settings.months, serviceV3,
)
return visitorsDataArray
}
func buildNetClient(secretPath string) *http.Client {
clientSecret, err := ioutil.ReadFile(secretPath)
if err != nil {
log.Fatalf("Unable to read secretPath. %v", err)
}
jwtConfig, err := google.JWTConfigFromJSON(clientSecret, gaV4.AnalyticsReadonlyScope)
if err != nil {
log.Fatalf("Unable to get config from JSON. %v", err)
}
return jwtConfig.Client(context.Background())
}
func makeReportServiceV3(secretPath string) (*gaV3.Service, error) {
client := buildNetClient(secretPath)
svc, err := gaV3.NewService(context.Background(), option.WithHTTPClient(client))
if err != nil {
log.Fatalf("Failed to create v3 Google Analytics Reporting Service")
}
return svc, err
}
func makeReportServiceV4(secretPath string) (*gaV4.Service, error) {
client := buildNetClient(secretPath)
svc, err := gaV4.NewService(context.Background(), option.WithHTTPClient(client))
if err != nil {
log.Fatalf("Failed to create v4 Google Analytics Reporting Service")
}
return svc, err
}
func getReports(
serviceV4 *gaV4.Service, viewIds map[string]interface{}, displayedMonths int, serviceV3 *gaV3.Service,
) []websiteReport {
startDate := fmt.Sprintf("%s-01", time.Now().AddDate(0, -displayedMonths+1, 0).Format("2006-01"))
var websiteReports []websiteReport
for website, viewID := range viewIds {
// For custom queries: https://ga-dev-tools.appspot.com/dimensions-metrics-explorer/
req := &gaV4.GetReportsRequest{
ReportRequests: []*gaV4.ReportRequest{
{
ViewId: viewID.(string),
DateRanges: []*gaV4.DateRange{
{StartDate: startDate, EndDate: "today"},
},
Metrics: []*gaV4.Metric{
{Expression: "ga:sessions"},
},
Dimensions: []*gaV4.Dimension{
{Name: "ga:month"},
},
},
},
}
response, err := serviceV4.Reports.BatchGet(req).Do()
if err != nil {
log.Fatalf("GET request to analyticsreporting/v4 returned error with viewID: %s", viewID)
}
if response.HTTPStatusCode != 200 {
log.Fatalf("Did not get expected HTTP response code")
}
report := websiteReport{Name: website, Report: response}
if serviceV3 != nil {
report.RealtimeReport = getLiveCount(serviceV3, viewID.(string))
}
websiteReports = append(websiteReports, report)
}
return websiteReports
}
func getLiveCount(service *gaV3.Service, viewID string) *gaV3.RealtimeData {
res, err := service.Data.Realtime.Get("ga:"+viewID, "rt:activeUsers").Do()
if err != nil {
log.Fatalf("Failed to fetch real time data for view ID %s: %v. Have you enrolled in the real time beta? If not, do so here: https://docs.google.com/forms/d/1qfRFysCikpgCMGqgF3yXdUyQW4xAlLyjKuOoOEFN2Uw/viewform", viewID, err)
}
return res
}