问题
最近需要使用 Google Api Go Client 获取 Google Adsense的数据,由于常规 generate 接口返回的数据是有10w行的限制,不满足目前的使用需要,于是使用了 csv的生成方法 generateCsv,和 generate 相比 generateCsv 能返回更多的数据并且不需要改动太多参数。
在调用 generateCsv 接口时,发现接口不能返回正确数据,提示错误,错误信息如下:
panic: invalid character 'D' looking for beginning of value
根据错误信息可以得知错误应该是解析错误,通过方法接口和源代码看出,接口返回的是csv类型的数据,但 api 只针对 json 进行解析,没有判断数据类型,导致解析失败。
解决
找到问题后,我立即就想到一个方法,就是在decode代码里添加csv格式的判断,尝试了一下,由于对csv解析方法不熟悉,并且修改 Client 代码会导致模块更新不方便(客户端代码都是生成的,于是决定另寻它法。 通过寻找各种资料issue后,找到了一个可能可行的方法,就是创建手动创建http连接发送请求。
根据相应的文档,很快就写好了相应的代码:
package main
import (
"context"
"fmt"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
"google.golang.org/api/adsense/v2"
"google.golang.org/api/option"
"google.golang.org/api/transport/http"
"io"
"net/url"
)
func main() {
ctx := context.Background()
var config = &oauth2.Config{
ClientID: "xxx.apps.googleusercontent.com", // from https://console.developers.google.com/project/<your-project-id>/apiui/credential
ClientSecret: "GOCSPX-xxxxxx", // from https://console.developers.google.com/project/<your-project-id>/apiui/credential
Endpoint: google.Endpoint,
Scopes: []string{adsense.AdsenseReadonlyScope},
RedirectURL: "https://developers.google.com",
}
//token := newOAuthClient(ctx, config)
client, _, err := http.NewClient(ctx, option.WithTokenSource(config.TokenSource(ctx, &oauth2.Token{RefreshToken: "code"})))
if err != nil {
return
}
URL, err := url.Parse(fmt.Sprintf("https://adsense.googleapis.com/v2/accounts/pub-123123/reports:generateCsv"))
if err != nil {
return
}
query := URL.Query()
query.Set("dateRange", "YESTERDAY")
query.Set("dimensions", "URL_CHANNEL_NAME")
query.Set("metrics", "PAGE_VIEWS")
URL.RawQuery = query.Encode()
resp, err := client.Get(URL.String())
if err != nil {
return
}
defer resp.Body.Close()
all, err := io.ReadAll(resp.Body)
if err != nil {
return
}
fmt.Println(string(all))
}
主要逻辑就是创建到google cloud service 的连接,调用 generateCsv 接口即可。
小结
本文讲述了使用 google api go client 调用AdSense接口遇到的问题及解决方法。