AI-generated Key Takeaways
-
This document outlines the protocol buffer schema for ingesting merchant, action, and service data related to food ordering.
-
It defines message structures for entities, actions (like food ordering), services (delivery, takeout), fees, service areas, and operating hours.
-
Entities represent businesses with details like name, location, and contact information, linked to actions and services they offer.
-
Services specify offerings like delivery or takeout, including details about fees, service areas, and operational hours with ASAP and advance ordering options.
-
Data is organized into feeds (EntityFeed, ActionFeed, FoodServiceFeed) for efficient ingestion and processing.
- google.type.Money.proto
- google.type.latlng.proto
- google.type.dayofweek.proto
- google.type.timeofday.proto
// Feeds declaration syntax = "proto3"; import "google/protobuf/duration.proto"; import "google/protobuf/timestamp.proto"; import "google/type/timeofday.proto"; import "google/type/dayofweek.proto"; import "google/type/money.proto"; import "google/type/latlng.proto"; package madden.ingestion; // Merchant feed starts message EntityFeed { repeated Entity data = 1; } // // Information about an Entity that is on the partner's platform. For example, // an Entity could be a retail store, a hospital, an online business etc. message Entity { // 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 = 1; // If present, the name, telephone, url and location are used to support // matching partner inventory with entities already present on Google. This // information will not be displayed. // The name of the Entity. (required) string name = 2; // The contact telephone number of the Entity including its country and area // codes, e.g. +14567891234. Highly recommended. (optional) string telephone = 3; // The url of the Entity's public website. Highly recommended. (optional) string url = 4; // The location of the Entity (required) madden.ingestion.GeoCoordinates location = 5; // This field is used by the aggregator to define which Brand should be // applied to which entity. (optional) string aggregator_brand_id = 6; } // The Geo data of a location, including latitude, longitude, and address. // At least one of [lat/lng or address] should be provided (or both). message GeoCoordinates { // [-90, +90] degrees (inclusive). (optional) double latitude = 1; // [-180, +180] degrees (inclusive). (optional) double longitude = 2; // Address for a location, could either be structured or unstructured. oneof addresses { // Postal address of the location, preferred. PostalAddress address = 3; // An unstructured address could also be provided as a fallback. // E.g. "1600 amphitheatre parkway mountain view, ca 94043" string unstructured_address = 4; } } // The postal address for a merchant. message PostalAddress { // The country, using ISO 3166-1 alpha-2 country code, e.g. "US" (required) string country = 1; // The locality/city, e.g. "Mountain View". (required) string locality = 2; // The region/state/province, e.g. "CA". This field is only required in // countries where region is commonly a part of the address. (optional) string region = 3; // The postal code, e.g. "94043". (required) string postal_code = 4; // The street address, e.g. "1600 Amphitheatre Pkwy". (required) string street_address = 5; } // Merchant feed ends // Actions feed starts message ActionFeed { repeated ActionDetail data = 1; } message ActionDetail { string entity_id = 2; string link_id = 3; // Deep link for action detail string url = 4; repeated Action actions = 1; } // Information about an Action which could be performed. message Action { // Deprecated fields not to be reused. reserved 1; oneof action_info { FoodOrderingInfo food_ordering_info = 3; } } message FoodOrderingInfo { // Service type for food ordering action. enum ServiceType { UNKNOWN = 0; DELIVERY = 1; TAKEOUT = 2; } ServiceType service_type = 1 ; } // Actions feed ends // Service feed starts // Food Ordering Team's EPA Service Feeds Spec. message FoodServiceFeed { // Service feed entity data. repeated ServiceData data = 1; } // Service feed entity data. message ServiceData { oneof type { FoodOrderingService service = 1; ServiceHours service_hours = 2; ServiceArea service_area = 3; Fee fee = 4; } } message FoodOrderingService { // Unique identifier of the provided service. // Required. string service_id = 1 ; enum ServiceType { SERVICE_TYPE_UNKNOWN = 0; DELIVERY = 1; TAKEOUT = 2; } // The type of the service. // Required and cannot be SERVICE_TYPE_UNKNOWN. ServiceType service_type = 2 ; // The parent entity’s ID. // Required. string parent_entity_id = 3 ; // Indicates if the entity is disabled. // Optional. bool disabled = 4 ; // The lead time given in the service entity will apply to all // the service hours unless an overridden property is set in the // service hours entity. // Required. ETA lead_time = 5 ; // Parent action detail's link ID. // Required. string action_link_id = 6 ; } // Lead time range [min, max). At least one of min or max needs to be provided. // A fixed value can be provided by setting both min and max to the same value. message ETA { // Indicates a range of ETA duration. google.protobuf.Duration min_lead_time_duration = 1 ; google.protobuf.Duration max_lead_time_duration = 2 ; } message Fee { // Unique identifier to the Fee entity. // Required. string fee_id = 1 ; enum FeeType { FEE_TYPE_UNKNOWN = 0; DELIVERY = 1; SERVICE = 2; } // Indicates the nature of the service, e.g. delivery fee/service fee. // Required. FeeType fee_type = 2 ; oneof amount { // A fixed amount of fees to be collected. google.type.Money fixed_amount = 3 ; // A range of fees that could be collected. Will mirror // madden.ingestion.MoneyRange for the starting point. MoneyRange range_amount = 4; // Fees in terms of amount percentage. Will mirror // madden.ingestion.QuantitativeValue for the starter. PercentageBasedFee cart_percentage = 5; } // Service association needs to be provided. // Required. repeated string service_ids = 6 ; // Service area can be provided to further restrict eligibility of the // fee. // Optional. repeated string area_ids = 7 ; } // Wrapper for a range of monetary amount that could be bounded or unbounded. // At least one of min_amount or max_amount is required. message MoneyRange { // Minimum amount. google.type.Money min_amount = 1 ; // Maximum amount. google.type.Money max_amount = 2 ; } // Variable fee which changes based on the price of the order. message PercentageBasedFee { // Optional, base fee not including the variable percentage based fee. google.type.Money base_value = 1 ; // Optional, overall range of possible values of the PercentageBasedFee. MoneyRange range = 2; // Optional, percentage representing an additional variable fee based on // the cart subtotal. E.g. 15.0 represents a fee of 15% of the cart. double percentage_of_cart_value = 3 ; } message ServiceArea { // Unique identifier. // Required. string area_id = 1 ; // Identifier to the parent service entity. // Required. repeated string service_ids = 2 ; // One of the following needs to be provided to define the service area. // Required. oneof region { GeoCircle circle = 3; Locality locality = 4; Polygon polygon = 5; } // Sets to true if the assigned area is excluded from serving. // Optional. optional bool excluded_area = 6; } // Geographical circular area described by a point and radius. message GeoCircle { // Geographical center of the area. // Required. google.type.LatLng center = 1 ; // Radius for the circular area, in meters. Must be greater than 0. // Required. double radius = 2 ; } // Geolocation of interests. message Locality { string country_code = 1 ; // Postal code in the country's local format in string. string postal_code = 2 ; } // Represents a polygon shaped region. message Polygon { reserved 1; // List of S2Loops which defines a polygon. A point is considered in the // polygon if it is contained in odd number of loops. repeated Loop loops = 2 ; } // Represents a loop of geo coordinates. This should be a valid S2Loop. message Loop { // Points making the boundary of loop. repeated google.type.LatLng point = 1 ; } // Service hours entity for ASAP/Advance orders. message ServiceHours { // Unique identifier of the provided advance service hours. // Required. string hours_id = 1 ; // The unique identifier of the Service entity correlated to this ServiceHours // entity. // Required. repeated string service_ids = 2 ; // The hours the orders can be fulfilled. For ASAP services, this is also // orderable time. // One of the fields (asap_hours/advance_hours) is required to be set. repeated AsapTimeWindow asap_hours = 3 ; repeated AdvanceTimeWindow advance_hours = 4; // When advance ordering services, this is the time windows the orders can be // placed. // Required when advance_hour is given. Invalid when asap_hour is given. repeated TimeOfDayWindow orderable_time = 5 ; // Indicates if the service hours are for special occasions // (e.g. Thanksgiving/...) // Optional bool special_hour = 6; // A timestamp window indicating the validity of the special hours. // Optional. Required if it's special hours. ValidityRange validity_range = 7 ; } message AsapTimeWindow { // A time window the ASAP order can be placed and fulfilled. // Required. TimeOfDayWindow time_windows = 1 ; // Indicates the lead time, specific to service_time, the service can // be fulfilled. // Optional. ETA lead_time = 2; } // The fulfillment time window for advance orders. message AdvanceTimeWindow { // A time window the advance order can be fulfilled. // Required. TimeOfDayWindow time_windows = 1 ; // a window that an advance order can be placed. For example, an advance // order must be placed at least 60 minutes ahead and not exceeding 2 // days, the interval would be [PT60M, P2D). // Optional. DurationInterval advance_booking_interval = 2; } // The TimeWindow object is a composite entity that describes a list // of windows the user's order can be either placed or fulfilled. message TimeOfDayWindow { // The time window the order can be placed/fulfilled. // Required. TimeOfDayRange time_windows = 1 ; // The list of days in a week the windows are applied. // Required. If not given, we assume 7 days a week. repeated google.type.DayOfWeek day_of_week = 2 ; } // A closed-open timestamp range. message ValidityRange { // The beginning time of the range (inclusive). // Optional. google.protobuf.Timestamp valid_from_time = 1 ; // The ending time of the range (exclusive). // Optional. google.protobuf.Timestamp valid_through_time = 2 ; } // A closed-open duration range. message DurationInterval { // The minimum duration (inclusive). // Required. google.protobuf.Duration min_offset = 1 ; // The maximum duration (exclusive). // Required. google.protobuf.Duration max_offset = 2 ; } // A closed-open time range. message TimeOfDayRange { // A Time indicating the beginning time of the day of the range (inclusive). // Required. If not given, we assume 00:00:00. google.type.TimeOfDay open_time = 1; // A Time indicating the ending time of the day of the range (exclusive). // Required. If not given, we assume 23:59:59. google.type.TimeOfDay close_time = 2; } // Service feed ends