RTU 主要用于无法预见的更新,例如紧急关闭或定期更改的元数据(例如预计到达时间)。如果您的更改不需要立即体现,您可以改用批量 Feed 提取。实时更新的处理时间不会超过五分钟。
Google Cloud Platform 设置
- 设置 GCP 项目。您需要使用 GCP 项目才能访问 RTU API。
- 授予编辑者访问权限 food-support@google.com
- 将 GCP 项目编号告知您的 Google POC。您的 GCP 项目必须与您的 Actions Center 账号相关联,才能让实时更新生效。
- 启用 Maps Booking API:
- 在 GCP 中,转到 API 和服务 > 库。
- 搜索“Google Maps Booking API”。
- 找到沙盒实例(“Google Maps Booking API (Dev)”),然后点击启用
- 找到正式版实例(“Google Maps Booking API”),然后点击启用
- 创建对您的 GCP 项目具有 Editor 角色的服务帐号。如需了解详情,请参阅服务帐号设置。
- 请务必将批量 Feed 上传到您正在进行实时更新的环境中。
- 对于 API 身份验证,我们建议您使用自己选择的语言安装 Google 客户端库。使用“https://www.googleapis.com/auth/mapsbooking”作为 OAuth 范围。下面包含的代码示例使用了这些库。否则,您需要按照使用 OAuth 2.0 访问 Google API 中的说明手动处理令牌交换。
服务账号设置
您需要有服务帐号才能向 Google API 发出经过身份验证的 HTTPS 请求,例如实时更新 API。
如需设置服务帐号,请执行以下操作:
- 访问 Google Cloud Platform 控制台。
- 您在 Actions Center 中的账号也有一个关联的 Google Cloud 项目。选择该项目(如果尚未选择)。
- 点击左侧菜单中的服务帐号。
- 点击创建服务帐号。
- 输入服务帐号的名称,然后点击创建。
- 对于选择角色,依次选择项目 > Editor。
- 点击继续。
- 可选:添加用户以授予他们访问该服务帐号的权限,然后点击完成。
- 为您刚刚创建的服务帐号依次点击更多 > 创建密钥。
- 选择 JSON 作为格式,然后点击创建。
- 生成新的公钥/私钥对后,将其下载到您的计算机。
使用 API
Real-time updates API 支持两种类型的操作:更新和删除。不支持通过实时更新 API 添加新实体。如果您在单个 API 请求中包含多个更新,则可以批量处理实时更新。在一次 API 调用中,您最多可以批量处理 1,000 个更新。如果可能,我们建议您采用基于触发器的方法通过 RTU 发送更新(即系统中的数据更改时触发向 Google 的实时更新),而不是采用基于频率的方法(即每 X 分钟扫描一次系统是否有更改)。
实时更新 API 可在沙盒环境和生产环境中运行。沙盒环境用于测试 API 请求和生产环境,以更新向端到端订购用户可见的内容。
- 沙盒 -
partnerdev-mapsbooking.googleapis.com
- 正式版 -
mapsbooking.googleapis.com
端点
实时更新 API 提供两个端点来处理传入的商品目录更新请求:
- 更新 -
/v1alpha/inventory/partners/PARTNER_ID/feeds/google.food_service/record:batchPush
- 删除 -
/v1alpha/inventory/partners/PARTNER_ID/feeds/google.food_service/record:batchDelete
您可以在操作中心的帐号和用户页面中找到参数 PARTNER_ID,如以下屏幕截图所示。
![合作伙伴门户上的合作伙伴 ID](https://developers-dot-devsite-v2-prod.appspot.com/static/actions-center/verticals/ordering/images/rtu-partnerid.png?authuser=7&hl=zh-cn)
以上方屏幕截图中的 PARTNER_ID 值 10000001 为例,在沙盒环境和生产环境中发送 API 请求的完整网址将如下面的示例所示。
沙盒更新
https://partnerdev-mapsbooking.googleapis.com/v1alpha/inventory/partners/10000001/feeds/google.food_service/record:batchPush
沙盒删除
https://partnerdev-mapsbooking.googleapis.com/v1alpha/inventory/partners/10000001/feeds/google.food_service/record:batchDelete
正式版更新
https://mapsbooking.googleapis.com/v1alpha/inventory/partners/10000001/feeds/google.food_service/record:batchPush
正式版 DELETE
https://mapsbooking.googleapis.com/v1alpha/inventory/partners/10000001/feeds/google.food_service/record:batchDelete
更新实体
如需更新商品目录中的实体,请在 HTTP POST 请求中使用 update 端点。每个 POST 请求都必须包含 10000001 参数,以及包含要更新的实体的 JSON 载荷。
注意:请确保每日数据 Feed 中也包含通过实时更新 API 提交的所有更改。否则,您的数据可能已过时或已过时。
更新请求载荷
请求正文是一个包含记录列表的 JSON 对象。每条记录都对应一个要更新的实体。它包含 proto_record
字段和指示实体更新时间的 generation_timestamp
:
{ "records": [ { "proto_record":"ServiceData PROTO", "generation_timestamp":"UPDATE_TIMESTAMP" } ] }
ServiceData PROTO
:您要更新的 ServiceData 实体的 proto 或 JSON 转换。UPDATE_TIMESTAMP
:请务必在后端系统中包含实体生成时间的时间戳。如果未添加此字段,则将设置为 Google 收到请求的时间。通过batchPush
请求更新实体时,generation_timestamp
字段用于实体版本控制。查看关系型目录架构中时间值的预期格式。
- 载荷正文的大小不得超过 5 MB。
- 删除空格以缩减大小。
- 一个
batchPush
请求最多可以包含 1,000 项更新。
示例
更新预计到达时间
假设您急需将送货服务的预计到达时间从 30-60 分钟更新为 60-90 分钟。您的更新必须包含整个 Service 实体的 JSON。
假设某个服务实体如下所示:
{ "service": { "service_id": "service/entity002", "service_type": "DELIVERY", "parent_entity_id": "entity002", "lead_time": { "min_lead_time_duration": "600s", "max_lead_time_duration": "1800s" }, "action_link_id": "delivery_link/entity002" } }
您通过 HTTP POST 执行的实时更新如下所示(为便于阅读,请求正文采用了整齐打印的格式):
POST v1alpha/inventory/partners/PARTNER_ID/feeds/google.food_service/record:batchPush Host: mapsbooking.googleapis.com Content-Type: application/json { "records": [{ "proto_record": { "@type": "type.googleapis.com/food.ordering.service.v1.ServiceData", "service" : { "service_id" : "23456/delivery", "service_type" : "DELIVERY", "parent_entity_id" : "23456", "disabled" : "false", "action_link_id": "delivery_link/entity002", "lead_time" : { "min_lead_time_duration" : { "seconds": "3600" }, "max_lead_time_duration" : { "seconds": "5400" } } } }, "generation_timestamp": "2023-09-13T17:11:10.750Z" }] }
更新多个实体
如需在单个 API 调用中更新多个餐馆实体,请在请求正文的 proto_record 字段中添加多个记录。
POST v1alpha/inventory/partners/PARTNER_ID/feeds/google.food_service/record:batchPush Host: mapsbooking.googleapis.com Content-Type: application/json { "records": [{ "proto_record": { "@type": "type.googleapis.com/food.ordering.service.v1.ServiceData", "service" : { "service_id" : "23456/delivery", "service_type" : "DELIVERY", "parent_entity_id" : "23456", "disabled" : "false", "action_link_id": "delivery_link/entity002", "lead_time" : { "min_lead_time_duration" : { "seconds": "1800" }, "max_lead_time_duration" : { "seconds": "3600" } } } }, "generation_timestamp": "2023-09-13T17:11:10.750Z" }, { "proto_record": { "@type": "type.googleapis.com/food.ordering.service.v1.ServiceData", "fee" : { "fee_id" : "12345/delivery_fee", "fee_type" : "DELIVERY", "fixed_amount" : { "currency_code" : "USD", "units" : "10", "nanos" : "0" }, "service_ids": ["service/entity002"] } }, "generation_timestamp" : "2023-09-13T17:11:10.750Z" }] }
删除实体
如需从广告资源中删除实体,请在 HTTP POST 请求中使用 DELETE 端点。每个 POST 请求都必须包含 PARTNER_ID 参数以及 JSON 载荷,该载荷中包含要删除的实体的标识符。
注意:请确保您的每日数据 Feed 中也包含通过实时更新 API 提交的所有更改。否则,每日批量注入将覆盖您的实时更改。
POST v1alpha/inventory/partners/PARTNER_ID/feeds/google.food_service/record:batchDelete Host: mapsbooking.googleapis.com Content-Type: application/json { "records": [{ "proto_record": { "@type": "type.googleapis.com/food.ordering.service.v1.ServiceData", "service" : { "service_id" : "23456/delivery" } }, "delete_time": "2023-09-13T17:11:10.750Z" }, { "proto_record": { "@type": "type.googleapis.com/food.ordering.service.v1.ServiceData", "fee" : { "fee_id" : "12345/delivery_fee" } }, "delete_time" : "2023-09-13T17:11:10.750Z" }] }
添加实体
请勿使用实时更新添加新实体,因为这可能会导致数据不一致。请改用批量 Feed。
验证和 API 响应代码
对实时更新 API 调用执行两种类型的验证:
- 请求级 - 这些验证检查载荷是否遵循架构,以及每个
proto_record
都包含id
和type
字段。这些检查是同步的,并且其结果会在 API 响应正文中返回。响应代码 200 和空 JSON 正文{}
表示这些验证已通过,并且该请求中的实体已排队等待处理。非 200 响应代码表示其中一个或多个验证失败,并且整个请求被拒绝(包括负载中的所有实体)。例如,如果proto_record
缺少@type
,系统会返回以下错误响应:
{ "error": { "code": 400, "message": "Record:{...}", "status": "INVALID_ARGUMENT", "details": [ { "@type": "type.googleapis.com/google.rpc.DebugInfo", "detail": "[ORIGINAL ERROR] generic::invalid_argument: Failed to parse one or more rtu records. Record:... The entity type could not be extracted from the entity value." } ] }
- 实体级:系统会根据架构对载荷中的每个实体 (proto_record) 进行验证。此验证阶段遇到的问题不会在 API 响应中报告。系统只会在 Actions Center 的 RTU 报告信息中心内报告这类事件。
注意:200 响应代码并不意味着所有实体都已成功提取。
API 配额
实时 API 更新的配额为每 60 秒 1,500 个请求,或平均每秒 25 个请求。超出配额时,Google 会返回以下错误消息:
{ "error": { "code": 429, "message": "Insufficient tokens for quota ...", "status": "RESOURCE_EXHAUSTED", "details": [...] } }
如需处理这种情况,请以指数级更大的间隔再次重试调用,直到成功为止。如果您经常用尽配额,可考虑在一个 API 请求中添加更多实体。一次 API 调用最多可以添加 1000 个实体。
处理时间实时更新
通过实时更新更新的实体在 5 分钟内处理完毕。