Golang使用Analytics Reporting API

前言

自己的博客是使用hexo构建的,由于不带后端,统计访问量只能通过第三方服务实现。
之前试过不蒜子之类的统计服务,体验下来并不是很稳定的样子,时不时会出现502错误。
自己很早就接入了Google Analytics,看到Google提供了Analytics Reporting API,数据挺全的,日后想做点花里胡哨的统计功能可能也比较方便,便打算拿这个来当访问量的数据源。
看到官方文档Server只写了Java、Python、PHP这三种使用方式,JavaScript的数据访问貌似必须OAuth登录,那只能搞个轻量的服务放在自己的云主机上了。现在想到Java就觉得特别臃肿,查了一下,除了Java、Python、PHP这三种语言,Google的亲儿子Golang也是支持使用Reporting API,符合个人轻量的定义,那就特此记录一下折腾的过程。

创建服务账号&创建密钥

在Google Cloud Platform中创建服务账号,只要有查看权限就行。

针对创建好的服务账号,选择操作下的管理密钥。

在添加密钥中选中创建新密钥,选择JSON类型的。

关联Analytics

打开Analytics的管理,点击账号访问管理权限,添加我们创建的服务账号Email,权限选择阅读和分析即可。

Coding

官方的文档只有Java、Python、PHP三种,如何使用Golang自己还是摸索了一下。

go.mod依赖

1
require google.golang.org/api v0.57.0

import

1
google.golang.org/api/analyticsreporting/v4

创建Service

WithCredentialsFile就是使用下载的JSON文件作为Credential,如果要自行传入byte slice则使用WithCredentialsJSON

1
2
3
4
5
analyticsReportingService, err := analyticsreporting.NewService(context.Background(), option.WithCredentialsFile("下载的密钥.json"))
if err != nil {
    panic(err)
}
reportsService := analyticsreporting.NewReportsService(analyticsReportingService)

构建请求内容

reportsService的BatchGet支持GetReportsRequest结构体指针作为参数,这个结构体的定义跟官网上的js api是比较相近的。在Analytics的管理->数据视图->数据视图设置中可以查到视图Id也就是ViewId。
不过这里我想做的是查询newUsers数跟PageViews,也就是UV跟PV了,维度的话我是打算根据路径来区分,所以我构造了下面的请求内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
request := &analyticsreporting.GetReportsRequest{
    ReportRequests: []*analyticsreporting.ReportRequest{
        {
            ViewId: "自己的ViewId",
            DateRanges: []*analyticsreporting.DateRange{
                {StartDate: "2020-01-01", EndDate: "today"},
            },
            Metrics: []*analyticsreporting.Metric{
                {Expression: "ga:newUsers"},
                {Expression: "ga:pageviews"},
            },
            Dimensions: []*analyticsreporting.Dimension{
                {Name: "ga:pagePath"},
            },
        },
    },
}

验证

调用一下,验证一下是否可以成功获取到数据。

1
2
3
4
5
6
response, err := reportsService.BatchGet(request).Do()
if err != nil {
    panic(err)
}
jsonBytes, err := response.MarshalJSON()
println(string(jsonBytes))

我删掉了除/以外的内容,可以看到返回的内容将列名跟数据拆开了,具体的内容都是字面意思了。这样就成功地取到了每个页面的UV、PV。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
{
    "reports": [{
        "columnHeader": {
            "dimensions": ["ga:pagePath"],
            "metricHeader": {
                "metricHeaderEntries": [{
                    "name": "ga:newUsers",
                    "type": "INTEGER"
                }, {
                    "name": "ga:pageviews",
                    "type": "INTEGER"
                }]
            }
        },
        "data": {
            "maximums": [{
                "values": ["1190", "2361"]
            }],
            "minimums": [{
                "values": ["0", "1"]
            }],
            "rowCount": 131,
            "rows": [{
                "dimensions": ["/"],
                "metrics": [{
                    "values": ["1190", "2361"]
                }]
            }],
            "totals": [{
                "values": ["1436", "3518"]
            }]
        }
    }]
}

小结

本文只是简单介绍了一下如何使用Golang调用Analytics Reporting API。
后续我是打算将这做成一个服务,服务启动的时候拉取一次数据,缓存在内存中。hexo前端请求服务获取当前页面UV、PV都从内存中取,服务间歇性更新数据。看了下Analytics Reporting API的免费配额是一天5万次请求,大概是支持1.728s查询一次,这对我们这种用途绰绰有余了。
目前只是简单开了个坑,还在填坑中。

作者

ZhongHuihong

发布于

2021-10-01

更新于

2021-10-04

许可协议