5 个版本 (3 个破坏性更新)
新功能 0.8.0 | 2024年8月10日 |
---|---|
0.7.0 | 2024年4月14日 |
0.6.0 | 2023年11月25日 |
0.5.1 | 2023年9月12日 |
0.5.0 | 2023年8月13日 |
#31 in #grpc-client
每月下载量 247
585KB
463 代码行
googleads-rs
当前版本 0.8.0 使用 Google Ads API v17.1
Google Ads API 的 gRPC 客户端库,自动从 API 定义文件生成。
我使用它来运行 Google Ads Query Language 查询,跨越大量 MCC 账户。
可能有更优雅的方法从 GoogleAdsRow 以反射方式拉取查询结果。我没能找到。所以我手动制作了一个 GoogleAdsRow.get(path: &str)
访问器方法来获取我需要的字段。
示例
let client: GoogleAdsServiceClient<InterceptedService<Channel, GoogleAdsAPIAccess>> =
GoogleAdsServiceClient::with_interceptor(api_context.channel.clone(), api_context);
let result: Result<Response<Streaming<SearchGoogleAdsStreamResponse>>, Status> = client
.search_stream(SearchGoogleAdsStreamRequest {
customer_id: customer_id.clone(),
query,
summary_row_setting: 0,
})
.await;
match result {
Ok(response) => {
let mut stream = response.into_inner();
let mut columns: Vec<Vec<String>> = Vec::new();
let mut headers: Option<Vec<String>> = None;
while let Some(item) = stream.next().await {
match item {
Ok(stream_response) => {
let field_mask = stream_response.field_mask.unwrap();
if headers.is_none() {
headers = Some(field_mask.paths.clone());
}
for r in stream_response.results {
let row: GoogleAdsRow = r;
// go through all columns specified in query, pull out string value, and insert into columns
for i in 0..headers.as_ref().unwrap().len() {
let path = &headers.as_ref().unwrap()[i];
let string_val: String = row.get(path).trim_matches('"').to_string();
match columns.get_mut(i) {
Some(v) => {
v.push(string_val);
}
None => {
let v: Vec<String> = vec![string_val];
columns.insert(i, v);
}
}
}
}
}
Err(status) => {
bail!(
"GoogleAdsClient streaming error. Account: {customer_id}, Message: {}, Details: {}",
status.message(),
String::from_utf8_lossy(status.details()).into_owned()
);
}
}
}
}
}
API 升级
运行 update.sh
来更新库以支持新的 Google Ads API 版本
- 下载新 Google Ads API 版本的最新的 proto 文件
- 在 build.rs、lib.rs 和 README.md 中替换对旧 API 版本的引用
./utils/update.sh v17
构建过程
- build.rs 动态扫描可用的 proto 文件,过滤它们,并将它们传递给 tonic 以生成
protos.rs
(遵循 aquarhead 的策略) - lib.rs 包含
protos.rs
- lib.rs 还包含手动编写的
get()
函数
pub fn get(&self, field_name: &str) -> String {
match field_name {
"ad_group_criterion.criterion_id" => format!("{}", self.ad_group_criterion.as_ref().unwrap().criterion_id),
"ad_group_criterion.status" => format!("{}", self.ad_group_criterion.as_ref().unwrap().status()),
<snip>
}
}
致谢
- 最初是从 gkkachi 的 gapi-grpc-rs 分支出来的,它使用 Python 生成
protos.rs
- 删除了 Python 并迁移到自定义的 build.rs,根据 aquarhead 的建议
依赖关系
~13–24MB
~437K SLoC