Skip to content

Commit ae02b21

Browse files
authored
Merge pull request shenzhencenter#40 from shenzhencenter/develop
Develop
2 parents ad9adad + 5069d8f commit ae02b21

1,379 files changed

Lines changed: 68425 additions & 116610 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/generator.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ on:
66
version:
77
description: "version"
88
required: true
9-
default: "v17.1"
109

1110
jobs:
1211
build:
@@ -64,7 +63,8 @@ jobs:
6463
cp -r $BUILD_PATH/* $OUTPUT_PATH/ && rm -rf $OUTPUT_PATH/google.golang.org
6564
find $OUTPUT_PATH -name '*.go' -exec sed -i "s|${BUILD_PKG}|${PUBLISH_PKG}|g" '{}' \;
6665
find $OUTPUT_PATH/clients/internal/snippets -name '*.go' -exec sed -i "s|\"clients\"|\"${PUBLISH_PKG}/clients\"|g" '{}' \;
67-
rm -rf $OUTPUT_PATH/clients/*_example_test.go
66+
rm -rf $OUTPUT_PATH/clients/*_test.go
67+
rm -rf $OUTPUT_PATH/clients/internal/snippets
6868
6969
- name: Fix errors
7070
run: |

README.md

Lines changed: 84 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -8,31 +8,28 @@
88

99
This library provides a Golang client for the [Google Ads API](https://developers.google.com/google-ads/api/docs/start). It's fully generated from the [googleapis](https://github.com/googleapis/googleapis/tree/master/google/ads/googleads) repository. More information on the generation process can be found [here](https://github.com/shenzhencenter/google-ads-pb/blob/main/.github/workflows/generator.yml).
1010

11-
Although this project isn't official, we deem it as low-risk due to its maturity and our two years of using it in production. However, always consult the [sunset schedule](https://developers.google.com/google-ads/api/docs/sunset-dates) of the Google Ads API.
11+
Although this project isn't official, we deem it as low-risk due to its maturity and our many years of using it in production. However, always consult the [sunset schedule](https://developers.google.com/google-ads/api/docs/sunset-dates) of the Google Ads API.
1212

1313
## Features
1414

1515
- Full support for Google Ads API.
16+
- Support for gRPC and REST Interface.
1617
- Source code generated from the official googleapis repository.
17-
- Support for GRPC and HTTP calls using [protojson](https://google.golang.org/protobuf/encoding/protojson).
18-
- Although we won't regularly update this based on the [official repository](https://github.com/googleapis/googleapis), we continually maintain it. Update frequency depends on our needs but usually occurs a month after the official release.
1918

2019
## Version support
2120

22-
| google-ads-pb | Google Ads API | Sunset date |
23-
| ----------------- | ---------------- | ---------------------------- |
24-
| v1.18.0 | v18 | September 2025 |
25-
| v1.17.1 | v17.1 | May 2025 |
26-
| v1.17.0 | v17 | May 2025 |
27-
| v1.16.1 | v16.1 | January 2025 |
28-
| v1.7.0 | v16 | January 2025 |
29-
| <del>v1.6.0</del> | <del>v15</del> | Deprecated |
30-
| <del>v1.5.1</del> | <del>v14.1</del> | Deprecated |
31-
| <del>v1.5.0</del> | <del>v14</del> | Deprecated |
21+
| google-ads-pb | Google Ads API | Sunset date |
22+
| ------------------ | ---------------- | ---------------------------- |
23+
| v1.19.0 | v19 | |
24+
| v1.18.0 | v18 | September 2025 |
25+
| v1.17.1 | v17.1 | June 4, 2025 |
26+
| v1.17.0 | v17 | June 4, 2025 |
27+
| <del>v1.16.1</del> | <del>v16.1</del> | Deprecated |
28+
| <del>v1.7.0</del> | <del>v16</del> | Deprecated |
3229

3330
## Requirements
3431

35-
- Go 1.22.
32+
- Go 1.23
3633
- Familiarize yourself with the [OAuth2 guide](https://developers.google.com/google-ads/api/docs/oauth/overview).
3734
- If needed, obtain a [developer token](https://developers.google.com/google-ads/api/docs/first-call/dev-token).
3835

@@ -41,105 +38,113 @@ Although this project isn't official, we deem it as low-risk due to its maturity
4138
```bash
4239
go get github.com/shenzhencenter/google-ads-pb
4340
```
44-
41+
4542
## Getting started
4643

47-
1. Set your environment variables.
44+
1. Prepare `ACCESS_TOKEN`, `DEVELOPER_TOKEN`, and `CUSTOMER_ID`.
4845

49-
```bash
50-
export ACCESS_TOKEN=<your access token>
51-
export DEVELOPER_TOKEN=<your developer token>
52-
export CUSTOMER_ID=<your customer id>
53-
```
46+
> Tips: For testing purposes, you can use [google/oauth2l](https://github.com/google/oauth2l) to obtain an access token.
5447
55-
If you're using gRPC, you should attach the access token, developer token, and customer ID to the context.
48+
2. gRPC example.
5649

5750
```go
58-
ctx := context.Background()
59-
headers := metadata.Pairs(
60-
"authorization", "Bearer "+os.Getenv("ACCESS_TOKEN"),
61-
"developer-token", os.Getenv("DEVELOPER_TOKEN"),
62-
"login-customer-id", os.Getenv("CUSTOMER_ID"),
51+
var (
52+
customerID = os.Getenv("CUSTOMER_ID")
53+
developerToken = os.Getenv("DEVELOPER_TOKEN")
54+
accessToken = os.Getenv("ACCESS_TOKEN")
6355
)
64-
ctx = metadata.NewOutgoingContext(ctx, headers)
65-
```
66-
67-
If you're using HTTP, you should attach the access token, developer token, and customer ID to the header.
6856

69-
```go
70-
header := make(http.Header)
71-
header.Set("content-type", "application/json")
72-
header.Set("authorization", os.Getenv("ACCESS_TOKEN"))
73-
header.Set("developer-token", os.Getenv("DEVELOPER_TOKEN"))
74-
```
75-
76-
2. Establish a GRPC connection.
77-
78-
```go
7957
cred := grpc.WithTransportCredentials(credentials.NewClientTLSFromCert(nil, ""))
8058
conn, err := grpc.NewClient("googleads.googleapis.com:443", cred)
8159
if err != nil {
8260
panic(err)
8361
}
8462
defer conn.Close()
85-
```
86-
87-
3. Start making calls.
8863

89-
```go
90-
customerServiceClient := services.NewCustomerServiceClient(conn)
91-
accessibleCustomers, err := customerServiceClient.ListAccessibleCustomers(
92-
ctx, // be sure to use the context with the access token, developer token, and customer ID
93-
&services.ListAccessibleCustomersRequest{},
64+
ctx := context.Background()
65+
headers := metadata.Pairs(
66+
"authorization", "Bearer "+accessToken,
67+
"developer-token", developerToken,
68+
"login-customer-id", customerID,
9469
)
70+
ctx = metadata.NewOutgoingContext(ctx, headers)
71+
72+
req := &services.SearchGoogleAdsRequest{
73+
CustomerId: customerID,
74+
Query: "SELECT user_list.name, user_list.resource_name FROM user_list",
75+
}
76+
svc := services.NewGoogleAdsServiceClient(conn)
77+
var header metadata.MD
78+
result, err := svc.Search(ctx, req, grpc.Header(&header))
79+
requestId := header.Get("request-id")
80+
log.Printf("request-id: %v, login-customer-id: %v", requestId[0], customerID)
9581
if err != nil {
96-
panic(err)
82+
apiErr := status.Convert(err)
83+
log.Fatalf("code: %s, message: %s, details: %v", apiErr.Code(), apiErr.Message(), apiErr.Details())
9784
}
9885

99-
for _, customer := range accessibleCustomers.ResourceNames {
100-
fmt.Println("ResourceName: " + customer)
86+
for _, row := range result.Results {
87+
if row.UserList == nil {
88+
continue
89+
}
90+
log.Print("resource_name: ", row.UserList.GetResourceName(), " name: ", row.UserList.GetName())
10191
}
10292
```
10393

104-
You can also make HTTP calls using [protojson](https://google.golang.org/protobuf/encoding/protojson), though it isn't recommended.
94+
3. HTTP example.
10595

10696
```go
107-
const endpoint = "https://googleads.googleapis.com/v18/customers:listAccessibleCustomers"
108-
req := services.ListAccessibleCustomersRequest{}
109-
requestBody, _ := protojson.Marshal(&req)
110-
request, _ := http.NewRequest("GET", endpoint, bytes.NewBuffer(requestBody))
97+
var (
98+
customerID = os.Getenv("CUSTOMER_ID")
99+
developerToken = os.Getenv("DEVELOPER_TOKEN")
100+
accessToken = os.Getenv("ACCESS_TOKEN")
101+
)
102+
103+
var endpoint = fmt.Sprintf("https://googleads.googleapis.com/v18/customers/%s/googleAds:search", customerID)
104+
req := services.SearchGoogleAdsRequest{
105+
Query: "SELECT user_list.name, user_list.resource_name FROM user_list",
106+
}
107+
reqBody, _ := protojson.Marshal(&req)
108+
109+
reqHttp, _ := http.NewRequest("POST", endpoint, bytes.NewReader(reqBody))
111110
header := make(http.Header)
112111
header.Set("content-type", "application/json")
113-
header.Set("authorization", os.Getenv("ACCESS_TOKEN"))
114-
header.Set("developer-token", os.Getenv("DEVELOPER_TOKEN"))
115-
request.Header = header
116-
response, _ := http.DefaultClient.Do(request)
117-
defer response.Body.Close()
118-
var responseBody []byte
119-
if responseBody, err = io.ReadAll(response.Body); err != nil {
120-
panic(err)
112+
header.Set("authorization", "Bearer "+accessToken)
113+
header.Set("developer-token", developerToken)
114+
header.Set("login-customer-id", customerID)
115+
reqHttp.Header = header
116+
117+
httpResp, err := http.DefaultClient.Do(reqHttp)
118+
if os.Getenv("DEBUG") != "" {
119+
reqId := httpResp.Header.Get("request-id")
120+
log.Print("request-id: ", reqId, " login-customer-id: ", reqHttp.Header.Get("login-customer-id"))
121121
}
122-
listAccessibleCustomersResponse := new(services.ListAccessibleCustomersResponse)
123-
if err := protojson.Unmarshal(responseBody, listAccessibleCustomersResponse); err != nil {
124-
panic(err)
122+
if err != nil {
123+
log.Panic(err)
124+
}
125+
defer httpResp.Body.Close()
126+
var httpRespBody []byte
127+
if httpRespBody, err = io.ReadAll(httpResp.Body); err != nil {
128+
log.Panic(err)
129+
}
130+
result := new(services.SearchGoogleAdsResponse)
131+
if err := protojson.Unmarshal(httpRespBody, result); err != nil {
132+
log.Fatal("failed to unmarshal response: ", err, "response: ", string(httpRespBody))
125133
}
126-
for _, customer := range listAccessibleCustomersResponse.ResourceNames {
127-
fmt.Println("ResourceName: " + customer)
134+
for _, row := range result.Results {
135+
if row.UserList == nil {
136+
continue
137+
}
138+
log.Print("resource_name: ", row.UserList.GetResourceName(), " name: ", row.UserList.GetName())
128139
}
129140
```
130141

131-
> **Note**: The above examples are just a starting point. You should adjust them based on your needs.
132-
133-
## Examples
134-
135-
See [clients/internal/snippets](https://github.com/shenzhencenter/google-ads-pb/tree/main/clients/internal/snippets).
136-
137-
## Related
138-
139-
Here are some related projects
142+
## References
140143

141144
- [Google APIs](https://github.com/googleapis/googleapis)
142145
- [Google Ads API Client Library for PHP](https://github.com/googleads/google-ads-php)
146+
- [google/oauth2l](https://github.com/google/oauth2l)
147+
- [How to Use a Service Account to Call the Google Ads API with Golang](https://www.liaozhen.cn/posts/how-to-use-service-account-call-google-ads-api/)
143148

144149
## Contributing
145150

clients/account_budget_proposal_client.go

Lines changed: 6 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

clients/account_budget_proposal_client_example_go123_test.go

Lines changed: 0 additions & 23 deletions
This file was deleted.

clients/account_link_client.go

Lines changed: 7 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

clients/account_link_client_example_go123_test.go

Lines changed: 0 additions & 23 deletions
This file was deleted.

0 commit comments

Comments
 (0)