adding ordering redirect entities/actions/services feed sample
diff --git a/order-redirect/proto/action.proto b/order-redirect/proto/action.proto
new file mode 100644
index 0000000..3ba4a59
--- /dev/null
+++ b/order-redirect/proto/action.proto
@@ -0,0 +1,45 @@
+
+// Feeds declaration
+syntax = "proto3";
+
+package madden.ingestion;
+
+message ActionFeed {
+ repeated ActionDetail data = 1;
+}
+
+message ActionDetail {
+ // Reference to entity id
+ optional string entity_id = 2;
+ // Link id for action detail
+ optional string link_id = 3;
+ // Deep link for action detail
+ optional 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 {
+ AppointmentInfo appointment_info = 2;
+ FoodOrderingInfo food_ordering_info = 3;
+ }
+}
+
+message AppointmentInfo {
+ // Deep link for appointment action.
+ string url = 1;
+}
+
+message FoodOrderingInfo {
+ // Service type for food ordering action.
+ enum ServiceType {
+ UNKNOWN = 0;
+ DELIVERY = 1;
+ TAKEOUT = 2;
+ }
+ ServiceType service_type = 1;
+}
+
diff --git a/order-redirect/proto/dayofweek.proto b/order-redirect/proto/dayofweek.proto
new file mode 100644
index 0000000..4c80c62
--- /dev/null
+++ b/order-redirect/proto/dayofweek.proto
@@ -0,0 +1,50 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+
+package google.type;
+
+option go_package = "google.golang.org/genproto/googleapis/type/dayofweek;dayofweek";
+option java_multiple_files = true;
+option java_outer_classname = "DayOfWeekProto";
+option java_package = "com.google.type";
+option objc_class_prefix = "GTP";
+
+// Represents a day of the week.
+enum DayOfWeek {
+ // The day of the week is unspecified.
+ DAY_OF_WEEK_UNSPECIFIED = 0;
+
+ // Monday
+ MONDAY = 1;
+
+ // Tuesday
+ TUESDAY = 2;
+
+ // Wednesday
+ WEDNESDAY = 3;
+
+ // Thursday
+ THURSDAY = 4;
+
+ // Friday
+ FRIDAY = 5;
+
+ // Saturday
+ SATURDAY = 6;
+
+ // Sunday
+ SUNDAY = 7;
+}
diff --git a/order-redirect/proto/entity.proto b/order-redirect/proto/entity.proto
new file mode 100644
index 0000000..6df538f
--- /dev/null
+++ b/order-redirect/proto/entity.proto
@@ -0,0 +1,69 @@
+
+// Feeds declaration
+syntax = "proto3";
+
+package madden.ingestion;
+
+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;
+}
+
+// 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 {
+ double latitude = 1; // In degrees. (optional)
+ double longitude = 2; // In degrees. (optional)
+
+ // 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;
+}
+
diff --git a/order-redirect/proto/food-service.proto b/order-redirect/proto/food-service.proto
new file mode 100644
index 0000000..047cea2
--- /dev/null
+++ b/order-redirect/proto/food-service.proto
@@ -0,0 +1,313 @@
+
+// Feeds declaration
+syntax = "proto3";
+
+package food.ordering.service.v1;
+
+option go_package = "google/food/ordering/services/v1";
+option java_package = "com.google.food.ordering.services.v1";
+
+import "google/protobuf/duration.proto";
+import "google/protobuf/timestamp.proto";
+import "timeofday.proto";
+import "latlng.proto";
+import "money.proto";
+import "dayofweek.proto";
+
+// 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.
+ 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.
+// In the case of only one field is given, the lead time is treated as a fixed
+// value instead of a range.
+message ETA {
+ // Indicates a range of ETA duration.
+ google.protobuf.Duration min_lead_time_duration = 1
+ ;
+ google.protobuf.Duration max_lead_time_duration = 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;
+}
+
+// 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 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
+ ;
+}
+
+// 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
+ ;
+}
+
+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;
+}
+
+// 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.
+ // Optional. Required when advance_hour is given.
+ repeated TimeOfDayWindow orderable_time = 5
+ ;
+
+ // Indicates if the service hours are for special occasions
+ // (e.g. Thanksgiving/...)
+ // Optional
+ 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
+ ;
+}
+
+// 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 loop of geo coordinates. This should be a valid S2Loop.
+message Loop {
+ // Points making the boundary of loop.
+ repeated google.type.LatLng point =
+ 1
+ ;
+}
+
+// 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
+ ;
+}
+
+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;
+}
+
+// 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.
+ optional 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.
+ optional double percentage_of_cart_value = 3
+ ;
+}
+
+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
+ ;
+}
+
diff --git a/order-redirect/proto/latlng.proto b/order-redirect/proto/latlng.proto
new file mode 100644
index 0000000..9231456
--- /dev/null
+++ b/order-redirect/proto/latlng.proto
@@ -0,0 +1,37 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+
+package google.type;
+
+option cc_enable_arenas = true;
+option go_package = "google.golang.org/genproto/googleapis/type/latlng;latlng";
+option java_multiple_files = true;
+option java_outer_classname = "LatLngProto";
+option java_package = "com.google.type";
+option objc_class_prefix = "GTP";
+
+// An object that represents a latitude/longitude pair. This is expressed as a
+// pair of doubles to represent degrees latitude and degrees longitude. Unless
+// specified otherwise, this must conform to the
+// <a href="http://www.unoosa.org/pdf/icg/2012/template/WGS_84.pdf">WGS84
+// standard</a>. Values must be within normalized ranges.
+message LatLng {
+ // The latitude in degrees. It must be in the range [-90.0, +90.0].
+ double latitude = 1;
+
+ // The longitude in degrees. It must be in the range [-180.0, +180.0].
+ double longitude = 2;
+}
diff --git a/order-redirect/proto/money.proto b/order-redirect/proto/money.proto
new file mode 100644
index 0000000..98d6494
--- /dev/null
+++ b/order-redirect/proto/money.proto
@@ -0,0 +1,42 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+
+package google.type;
+
+option cc_enable_arenas = true;
+option go_package = "google.golang.org/genproto/googleapis/type/money;money";
+option java_multiple_files = true;
+option java_outer_classname = "MoneyProto";
+option java_package = "com.google.type";
+option objc_class_prefix = "GTP";
+
+// Represents an amount of money with its currency type.
+message Money {
+ // The three-letter currency code defined in ISO 4217.
+ string currency_code = 1;
+
+ // The whole units of the amount.
+ // For example if `currencyCode` is `"USD"`, then 1 unit is one US dollar.
+ int64 units = 2;
+
+ // Number of nano (10^-9) units of the amount.
+ // The value must be between -999,999,999 and +999,999,999 inclusive.
+ // If `units` is positive, `nanos` must be positive or zero.
+ // If `units` is zero, `nanos` can be positive, zero, or negative.
+ // If `units` is negative, `nanos` must be negative or zero.
+ // For example $-1.75 is represented as `units`=-1 and `nanos`=-750,000,000.
+ int32 nanos = 3;
+}
diff --git a/order-redirect/proto/timeofday.proto b/order-redirect/proto/timeofday.proto
new file mode 100644
index 0000000..5cb48aa
--- /dev/null
+++ b/order-redirect/proto/timeofday.proto
@@ -0,0 +1,44 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+
+package google.type;
+
+option cc_enable_arenas = true;
+option go_package = "google.golang.org/genproto/googleapis/type/timeofday;timeofday";
+option java_multiple_files = true;
+option java_outer_classname = "TimeOfDayProto";
+option java_package = "com.google.type";
+option objc_class_prefix = "GTP";
+
+// Represents a time of day. The date and time zone are either not significant
+// or are specified elsewhere. An API may choose to allow leap seconds. Related
+// types are [google.type.Date][google.type.Date] and
+// `google.protobuf.Timestamp`.
+message TimeOfDay {
+ // Hours of day in 24 hour format. Should be from 0 to 23. An API may choose
+ // to allow the value "24:00:00" for scenarios like business closing time.
+ int32 hours = 1;
+
+ // Minutes of hour of day. Must be from 0 to 59.
+ int32 minutes = 2;
+
+ // Seconds of minutes of the time. Must normally be from 0 to 59. An API may
+ // allow the value 60 if it allows leap-seconds.
+ int32 seconds = 3;
+
+ // Fractions of seconds in nanoseconds. Must be from 0 to 999,999,999.
+ int32 nanos = 4;
+}
diff --git a/order-redirect/python/action_feed.py b/order-redirect/python/action_feed.py
new file mode 100644
index 0000000..c2f19ea
--- /dev/null
+++ b/order-redirect/python/action_feed.py
@@ -0,0 +1,28 @@
+import json
+from generated import action_pb2
+from google.protobuf.json_format import MessageToDict
+
+#create feed
+feed = action_pb2.ActionFeed()
+
+#create action
+action = feed.data.add()
+action.entity_id = 'merchant-1'
+action.link_id = 'merchant-1-takeout-delivery-action'
+action.actions.extend([
+ action_pb2.Action(
+ food_ordering_info=action_pb2.FoodOrderingInfo(
+ service_type=action_pb2.FoodOrderingInfo.ServiceType.DELIVERY
+ )
+ ),
+ action_pb2.Action(
+ food_ordering_info=action_pb2.FoodOrderingInfo(
+ service_type=action_pb2.FoodOrderingInfo.ServiceType.TAKEOUT
+ )
+ )
+])
+action.url = "http://provider.com/merchant-1"
+
+feedJSON = json.dumps(MessageToDict(feed, preserving_proto_field_name=True))
+print(feedJSON)
+
diff --git a/order-redirect/python/entity_feed.py b/order-redirect/python/entity_feed.py
new file mode 100644
index 0000000..044247a
--- /dev/null
+++ b/order-redirect/python/entity_feed.py
@@ -0,0 +1,30 @@
+import json
+from generated import entity_pb2
+from google.protobuf.json_format import MessageToDict
+
+#create feed
+feed = entity_pb2.EntityFeed()
+
+#create entity
+entity = feed.data.add()
+entity.entity_id = 'merchant-1'
+entity.name = "Mo's Dinner"
+entity.telephone = '+14567891234'
+entity.url = 'http://moesdinner.com'
+
+#create location
+location = entity.location
+location.latitude = 41.525588
+location.longitude = -90.507067
+
+#create address
+address = location.address
+address.country = 'US'
+address.locality = 'Mountain View'
+address.region = 'CA'
+address.postal_code = '94043'
+address.street_address = '1600 Amphitheatre Pkwy'
+
+feedJSON = json.dumps(MessageToDict(feed, preserving_proto_field_name=True))
+print(feedJSON)
+
diff --git a/order-redirect/python/service_feed.py b/order-redirect/python/service_feed.py
new file mode 100644
index 0000000..c767772
--- /dev/null
+++ b/order-redirect/python/service_feed.py
@@ -0,0 +1,47 @@
+import json
+from generated import food_service_pb2
+from generated import timeofday_pb2
+from google.protobuf.json_format import MessageToDict
+
+#create feed
+feed = food_service_pb2.FoodServiceFeed()
+
+#create food_service
+service_data = feed.data.add()
+service_data.service.service_id = 'merchant-1-service-delivery'
+service_data.service.service_type = food_service_pb2.FoodOrderingService.ServiceType.DELIVERY
+service_data.service.parent_entity_id = 'merchant-1'
+service_data.service.lead_time.min_lead_time_duration.seconds = 1200
+service_data.service.action_link_id = 'merchant-1-takeout-delivery-action'
+
+#create fee
+fee_data = feed.data.add()
+fee_data.fee.fee_id = 'merchant-1-fee-delivery'
+fee_data.fee.fee_type = food_service_pb2.Fee.FeeType.DELIVERY
+fee_data.fee.fixed_amount.currency_code = 'USD'
+fee_data.fee.fixed_amount.units = 2
+fee_data.fee.service_ids.append('merchant-1-service-delivery')
+
+#create service hours
+service_hours_data = feed.data.add()
+service_hours_data.service_hours.hours_id = 'merchant-1-advance-hours-delivery'
+service_hours_data.service_hours.service_ids.append('merchant-1-service-delivery')
+asap_hours = service_hours_data.service_hours.asap_hours.add()
+asap_hours.time_windows.MergeFrom(food_service_pb2.TimeOfDayWindow(
+ time_windows=food_service_pb2.TimeOfDayRange(
+ open_time=timeofday_pb2.TimeOfDay(
+ hours=11,
+ minutes=00
+ ),
+ close_time=timeofday_pb2.TimeOfDay(
+ hours=22,
+ minutes=30
+ )
+ )
+ )
+)
+asap_hours.lead_time.min_lead_time_duration.seconds = 2400
+
+feedJSON = json.dumps(MessageToDict(feed, preserving_proto_field_name=True))
+print(feedJSON)
+