| /* | |
| Menu feed example used in | |
| https://developers.google.com/maps-booking/verticals/dining/guides/tutorials/tutorial-menu-feed-protos#go. | |
| * | |
| */ | |
| package main | |
| import ( | |
| pb "feed/app/generated/food/menu/v1/proto" | |
| "fmt" | |
| localized_text "google.golang.org/genproto/googleapis/type/localized_text" | |
| money "google.golang.org/genproto/googleapis/type/money" | |
| "google.golang.org/protobuf/encoding/protojson" | |
| timestamppb "google.golang.org/protobuf/types/known/timestamppb" | |
| proto "google.golang.org/protobuf/proto" | |
| ) | |
| func main() { | |
| //create a menu component | |
| menu := &pb.Menu{ | |
| MenuId: "menu1", | |
| MerchantIds: []string{"dining-1"}, | |
| DisplayName: &pb.TextField{ | |
| Text: []*localized_text.LocalizedText{{ | |
| Text: "Menu", | |
| LanguageCode: "en-us", | |
| }}, | |
| }, | |
| Language: "en-us", | |
| LastMerchantUpdateTime: ×tamppb.Timestamp{ | |
| Seconds: 1633621547, | |
| }, | |
| } | |
| //create a menu section component | |
| section := &pb.MenuSection{ | |
| MenuSectionId: "appetizers", | |
| DisplayName: &pb.TextField{ | |
| Text: []*localized_text.LocalizedText{{ | |
| Text: "Lunch Appetizers", | |
| LanguageCode: "en-us", | |
| }}, | |
| }, | |
| MenuItemIds: []string{"breadsticks-sauce"}, | |
| } | |
| //create a menu item component | |
| item := &pb.MenuItem{ | |
| MenuItemId: "breadsticks-sauce", | |
| DisplayName: &pb.TextField{ | |
| Text: []*localized_text.LocalizedText{{ | |
| Text: "Breadsticks & Sauce", | |
| LanguageCode: "en-us", | |
| }}, | |
| }, | |
| Description: &pb.TextField{ | |
| Text: []*localized_text.LocalizedText{{ | |
| Text: "Breakfast basket w/ side of tomato sauce (size 6 or 12)", | |
| LanguageCode: "en-us", | |
| }}, | |
| }, | |
| Pricing: &pb.MenuItem_MenuItemOptionSet_{ | |
| MenuItemOptionSet: &pb.MenuItem_MenuItemOptionSet{ | |
| MenuItemOptionIds: []string{"breadstick-sm", "breadstick-lg"}, | |
| }, | |
| }, | |
| } | |
| imageUris := []string{ | |
| "http://www.example.com/photos/breadsticks.jpg", | |
| "http://www.example.com/photos/sauce.jpg", | |
| } | |
| for _, uri := range imageUris { | |
| image := &pb.Image{ | |
| Uri: uri, | |
| } | |
| item.Images = append(item.Images, image) | |
| } | |
| //create a menu item option | |
| option := &pb.MenuItemOption{ | |
| MenuItemOptionId: "breadstick-sm", | |
| Value: &pb.MenuItemOptionProperty{ | |
| PropertyType: pb.MenuItemOptionProperty_SIZE, | |
| Value: &pb.MenuItemOptionProperty_TextVal{ | |
| TextVal: &pb.TextField{ | |
| Text: []*localized_text.LocalizedText{{ | |
| Text: "Small", | |
| LanguageCode: "en-us", | |
| }}, | |
| }, | |
| }, | |
| }, | |
| OfferSet: &pb.OfferSet{ | |
| Offers: []*pb.Offer{{ | |
| Price: &money.Money{ | |
| CurrencyCode: "USD", | |
| Units: 8, | |
| Nanos: 0, | |
| }, | |
| }}, | |
| }, | |
| } | |
| //create feed | |
| feed := &pb.FoodMenuFeed{ | |
| Data: []*pb.MenuComponent{{ | |
| Type: &pb.MenuComponent_Menu{ | |
| Menu: menu, | |
| }, | |
| }, | |
| { | |
| Type: &pb.MenuComponent_Section{ | |
| Section: section, | |
| }, | |
| }, | |
| { | |
| Type: &pb.MenuComponent_Item{ | |
| Item: item, | |
| }, | |
| }, | |
| { | |
| Type: &pb.MenuComponent_Option{ | |
| Option: option, | |
| }, | |
| }}, | |
| } | |
| // Example testing for menu feed size | |
| // Protocol buffer message must be less than 2 GiB | |
| // https://protobuf.dev/programming-guides/proto-limits/ | |
| // It is recommended to not exceed 200 MB, as there is an Actions | |
| // Center limit of 200 MB per file after compression. | |
| if proto.Size(feed) > 200 * 1024 * 1024 { | |
| // create new file | |
| } | |
| marshalOptions := protojson.MarshalOptions{ | |
| UseProtoNames: true, | |
| } | |
| jsonBytes, _ := marshalOptions.Marshal(feed) | |
| fmt.Printf("message = %s", string(jsonBytes)) | |
| } | |