预约空闲状态 Feed

创建和上传预约空档 Feed

创建和上传预约空闲时间 Feed 时,请遵循以下说明:

  • 遵循预约空闲时间数据文件的预约空闲时间 Feed 中所述的规范。我们建议您为每次上传使用唯一的预约空闲时间数据文件名。 在文件名中添加时间戳,例如 appointment availability_1633621547.json
  • 在文件集描述符中,将 name 字段设置为 appointment.availability。如需查看描述符文件示例,请参阅 JSON 示例。 我们建议为每次上传使用唯一的描述符文件名。 在文件名中添加时间戳,例如 appointment availability_1633621547.filesetdesc.json。 描述符文件必须上传到通用 SFTP 服务器。
  • 每 30 分钟将 Feed 上传到通用 SFTP 服务器,作为完全刷新。
  • 您可以在合作伙伴门户的配置 > Feed 部分中找到 SFTP 服务器详细信息。
  • 选择 Feed 服务器

    在合作伙伴门户网站中选择 Feed 服务器
  • 在合作伙伴门户的 Feed > 历史记录部分中查看 Feed 提取状态。

上传增量更新型 Feed

预约空闲时间还支持增量 Feed,使合作伙伴能够仅上传对空闲时间所做的更改。

如需上传增量 Feed,请在 Feed 的至少一个空闲时段内设置 is_incremental: true。如果部分 Feed 的 is_incremental 设置为 true,而部分 Feed 的 is_incremental 设置为 false,则系统会将所有 Feed 都视为增量 Feed。

增量更新提供以下操作:

不更改
对于没有变化的实体,请勿添加相应实体的“商品目录 ID”。
更新可用性
如需更新单个空房情况,请上传需要修改的特定空房情况条目(相同的 availability_id),并更改所选的任意字段。
删除空闲时间段
如果某个库存状况条目不再有效或应被删除,请上传该库存状况(相同的 availability_id),并将 spots_available 设置为 0,系统会自动将其删除。此外,如需移除商家 / 实体的所有数据,请将所有可用时间段的 spots_available 设置为 0,这样即可从“可用性”中移除商家 / 实体本身。
添加服务时间
对于新的有空时间段,请在 Feed 上传中添加新的有空时间条目及其唯一的新 availability_id。系统会像处理常规 Feed 中的商品一样处理这些商品。

定义

AppointmentAvailabilityFeed 的定义

message AppointmentAvailabilityFeed {
  repeated AppointmentAvailability data = 1;
}

AppointmentAvailability 的定义

// This represents the availability data for a bookable service provided by a
// merchant.
// For example, it can be a haircut/nail manicure service for a beauty salon or
// a massage service for a spa.
// The availability feed should be a list of this message.
message AppointmentAvailability {
  // An opaque string generated by the partner that identifies a service time
  // slot. Must be unique across all entities and service time slots.
  // Strongly recommended to only include URL-safe characters.
  // Required.
  string availability_id = 1;

  // An opaque string generated by the partner that identifies an Entity.
  // Must be unique across all entities.
  // Strongly recommended to only include URL-safe characters.
  // Required.
  string entity_id = 2;

  // An opaque string of ASCII characters from an aggregator partner which
  // uniquely identifies the Service (haircut, nail manicure, massage).
  // Strongly recommended to only include URL-safe characters.
  // Required.
  string service_id = 3;

  // The name of the service provider. For example, the name of the
  // hairdresser or the spa staff member.
  // Optional.
  string provider = 12;

  // Timestamp of when this availability slot starts in UTC.
  // Given in seconds since the unix epoch.
  // For example, 1735714800 seconds for 1 Jan 2025, 07:00:00 (UTC).
  // Required.
  int64 start_time_sec = 4;

  // The minimum number of minutes in advance before the start time that this
  // availability slot can be booked.
  // For example, if the start time is 10:00 AM and the min_advance_minutes is
  // 60, then the latest time this slot can be booked is 9:00 AM on the day of
  // the appointment.
  // If not set, it is assumed to be 0, meaning the slot can be booked at any
  // time before the start time.
  // Optional.
  int32 min_advance_minutes = 13;

  // Number of total spots and available spots of this booking availability.
  // Required.
  int32 spots_total = 5;
  // Required.
  int32 spots_available = 6;

  // The minimum number of spots that should be booked for this availability.
  // For example, a user has to book at least 2 spots for a time slot sometimes.
  // If set, spots_minimum_book should be less or equal to spots_available.
  // Optional.
  int32 spots_minimum_book = 7;

  // Link of this booking availability. Users will be redirected to partner
  // website to continue booking after clicking this link.
  // Required.
  string booking_link = 8;

  // Base price per person.
  // Required.
  google.type.Money base_price = 9;
  // Fee per person.
  // Required.
  google.type.Money fee_price = 10;

  // Whether the feed is incremental or not.
  // By default it is false, meaning the Availability feed will override the
  // previous data for the same entity_id.
  // If this is set to be true, the Availability feed will be proceeded as
  // incremental updates for the same entity_id.
  //    1) If it is a new availability_id, the entry is added.
  //    2) If it is an existing availability_id and the spots_available is 0,
  //       the entry is removed.
  //    3) If it is an existing availability_id and the spots_available is not
  //    0, the entry is updated.
  bool is_incremental = 11;
}

外部 proto 引用:

高尔夫可用性 Feed 示例

预约空闲状态 Feed

{
  "data": [
    {
      "availability_id": "availability_id_1",
      "entity_id": "entity_id_1",
      "service_id": "service_id_1",
      "start_time_sec": 1728257400,
      "spots_total": 4,
      "spots_available": 4,
      "spots_minimum_book": 2,
      "booking_link": "https://www.googleappointments.com/a_link_direct_to_booking_page",
      "base_price": {
        "currency_code": "USD",
        "units": 80,
        "nanos": 0
      },
      "fee_price": {
        "currency_code": "USD",
        "units": 1,
        "nanos": 750000000
      }
    },
    {
      "availability_id": "availability_id_2",
      "entity_id": "entity_id_2",
      "service_id": "service_id_2",
      "start_time_sec": 1728259200,
      "spots_total": 4,
      "spots_available": 4,
      "spots_minimum_book": 2,
      "booking_link": "https://googlegolfappointments.com/a_link_direct_to_booking_page",
      "base_price": {
        "currency_code": "USD",
        "units": 80,
        "nanos": 0
      },
      "fee_price" : {
        "currency_code": "USD",
        "units": 2,
        "nanos": 850000000
      }
    }
  ]
}

描述符文件

{
  "generation_timestamp": 1663347730,
  "name": "appointment.availability",
  "data_file": [
    "appointment_availability_1663347730.json"
  ]
}