Crea y sube feeds de PDI
Cuando crees y subas feeds de PDI, sigue estas instrucciones:
- Sigue la especificación que se describe en el feed de PDI para los archivos de datos de PDI. Te recomendamos que uses nombres de archivo únicos para los datos de PDI en cada carga. Incluye una marca de tiempo en el nombre del archivo, por ejemplo,
POI_1633621547.json. - Sube feeds al servidor SFTP de PDI local todos los días como actualizaciones completas.
- Puedes encontrar los detalles del servidor SFTP en la sección Configuración > Feeds del Portal para socios.
- Consulta el estado de la transferencia del feed en la sección Transferencia > Historial del Partner Portal.
Especificaciones del feed
Requisitos de campo
VssPoi
Representa una sola entidad de lugar de interés (POI), p.ej., un hotel o un restaurante.
| Nombre del campo | Tipo | Requisito | Descripción |
|---|---|---|---|
poi_id | string | Obligatorio | Obligatorio. Es una cadena generada por el socio que identifica un PDI. |
name | object(Text) | Obligatorio | Obligatorio. Es el nombre del PDI. |
telephone | string | Es el número de teléfono de contacto del PDI, incluidos los códigos de país y de área, p.ej., +14567891234. | |
url | string | Es la URL del sitio web público del PDI. Nota: Esto se usará solo para fines de correlación, no para mostrarse. | |
location | object(GeoCoordinates) | Obligatorio | Obligatorio. Ubicación del PDI. |
display_address | object(Text) | Es la dirección que se muestra en la IU. | |
images | array de object(Image) | Imágenes del POI. Cantidad máxima de imágenes: 5 | |
rating | número | Es la calificación promedio del PDI. | |
num_ratings | número | Es la cantidad de calificaciones que contribuyen al campo rating. | |
rating_scale | número | Es la escala de calificación que se usa para el campo rating. Si la calificación máxima es 5, rating_scale es 5. | |
category | enum(Category) | Obligatorio | Obligatorio. Representa la categoría del PDI. |
description | object(Text) | Es una descripción del lugar de interés. | |
| oneOf(additional_data) | Obligatorio | Solo se puede establecer uno de los campos en este oneOf. |
Texto
Representa un texto con localizaciones.
| Nombre del campo | Tipo | Requisito | Descripción |
|---|---|---|---|
localizations | array de object(LocalizedString) | Son las cadenas localizadas. | |
default_locale | string | Es la configuración regional que se usará como idioma predeterminado y debe estar presente en las localizaciones. |
LocalizedString
Representa una cadena localizada.
| Nombre del campo | Tipo | Requisito | Descripción |
|---|---|---|---|
locale | string | Es la etiqueta de idioma del texto, como "en", "en-US" o "sr-Latn". | |
text | string | Es el texto en la configuración regional especificada. |
GeoCoordinates
Son los datos geográficos de una ubicación, incluidas la latitud, longitud y dirección.
| Nombre del campo | Tipo | Requisito | Descripción |
|---|---|---|---|
latitude | número | De -90 a +90 grados (inclusive). Es obligatorio si se configura la longitud; de lo contrario, es opcional. | |
longitude | número | De -180 a +180 grados (inclusive). Es obligatorio si se establece la latitud; de lo contrario, es conveniente tenerlo. | |
| oneOf(addresses) | Obligatorio | Solo se puede establecer uno de los campos en este oneOf. |
PostalAddress
Es la dirección postal de la ubicación.
| Nombre del campo | Tipo | Requisito | Descripción |
|---|---|---|---|
country | string | Obligatorio | Obligatorio. Es el país, con el código de país ISO 3166-1 alpha-2, p.ej., "US". |
locality | string | Obligatorio | Obligatorio. La localidad o ciudad, p.ej., "Mountain View". |
region | string | La región, el estado o la provincia, p.ej., "CA". Este campo solo es obligatorio en los países donde la región suele formar parte de la dirección. (opcional) | |
postal_code | string | Obligatorio | Obligatorio. El código postal, p.Ej., "94043". |
street_address | string | Obligatorio | Obligatorio. La dirección, p.Ej., "1600 Amphitheatre Pk acuerdo". |
Imagen
Representa una imagen del lugar de interés (POI).
| Nombre del campo | Tipo | Requisito | Descripción |
|---|---|---|---|
url | string | Es la URL de la imagen. Google rastreará el contenido multimedia alojado en esta URL. Longitud máxima: 2,000. | |
alt_text | object(Text) | Es el texto alternativo que se usará para la accesibilidad. |
HotelData
Son datos del feed específicos del hotel.
| Nombre del campo | Tipo | Requisito | Descripción |
|---|---|---|---|
hotel_star_class | número | Es el valor oficial de la categoría del hotel en estrellas. Se puede usar en una etiqueta como "Hotel de 5 estrellas". Se espera que este valor sea un número entero entre 1 y 5. | |
brand_ids | array de cadenas | Son las marcas que pueden mostrar este hotel. Si este campo está vacío, el hotel se puede mostrar en cualquiera de las marcas asociadas con el feed. |
LocalData
Son los datos del feed específicos del establecimiento.
| Nombre del campo | Tipo | Requisito | Descripción |
|---|---|---|---|
business_hours | object(BusinessHours) | Es el horario de atención habitual del establecimiento. | |
price_range | object(PriceRange) | Es el intervalo de precios de los servicios que ofrece el establecimiento. | |
establishment_category | object(Text) | Es el tipo de establecimiento. | |
brand_landing_pages | array de object(BrandLandingPages) | Son las páginas de destino de la marca. |
BusinessHours
Representa los períodos durante los que esta ubicación está abierta. Contiene una colección de instancias de [TimeRange][madden.vss_poi_feed.TimeRange]. Ejemplo: Abierto los sábados de 9:00 a.m. a 12:00 p.m. y de 1:00 p.m. a 5:00 p.m.: time_ranges { open_day: SATURDAY open_time: { hours: 9, minutes: 0 } close_day: SATURDAY close_time: { hours: 12, minutes: 0 } } time_rages { open_day: SATURDAY open_time: { hours: 13, minutes: 0 } close_day: SATURDAY close_time: { hours: 17, minutes: 0 } } Ejemplo: Abierto los sábados de 9:00 p.m. a 2:00 a.m. del domingo: time_ranges { open_day: SATURDAY open_time: { hours: 21, minutes: 0 } close_day: SUNDAY close_time: { hours: 2, minutes: 0 } }
| Nombre del campo | Tipo | Requisito | Descripción |
|---|---|---|---|
time_ranges | array de object(TimeRange) | Es una colección de horarios en los que este PDI está abierto. Cada período representa un rango de horas en el que el lugar de interés está abierto durante la semana. |
TimeRange
Representa un intervalo de tiempo durante el cual el lugar de interés está abierto, que comienza en el día y la hora de apertura especificados y finaliza en el día y la hora de cierre especificados. La hora de cierre debe ser posterior a la hora de apertura, por ejemplo, más tarde el mismo día o en un día posterior.
| Nombre del campo | Tipo | Requisito | Descripción |
|---|---|---|---|
open_day | enum(DayOfWeek) | Es el día de apertura del período. | |
open_time | object(TimeOfDay) | Es la hora de apertura del intervalo. | |
close_day | enum(DayOfWeek) | Es el día de cierre del período. | |
close_time | object(TimeOfDay) | Es la hora de cierre del período. |
TimeOfDay
| Nombre del campo | Tipo | Requisito | Descripción |
|---|---|---|---|
hours | número | Horas de un día en formato de 24 horas. Debe ser mayor o igual que 0 y, por lo general, menor o igual que 23. Una API puede permitir el valor "24:00:00" para casos como el horario de cierre de empresas. | |
minutes | número | Minutos de una hora. Debe ser mayor o igual que 0 y menor o igual que 59. | |
seconds | número | Segundos de un minuto. Debe ser mayor o igual que 0 y, por lo general, menor o igual que 59. Una API puede permitir el valor 60 si permite segundos bisiestos. | |
nanos | número | Fracciones de segundos, en nanosegundos. Debe ser mayor o igual que 0 y menor o igual que 999,999,999. |
PriceRange
Es el rango de precios de los servicios que ofrece el PDI.
| Nombre del campo | Tipo | Requisito | Descripción |
|---|---|---|---|
min_price | object(Money) | Es el precio mínimo de los servicios que ofrece el PDI. | |
max_price | object(Money) | Es el precio máximo de los servicios que ofrece el PDI. |
Dinero
Representa un importe de dinero con su tipo de moneda.
| Nombre del campo | Tipo | Requisito | Descripción |
|---|---|---|---|
currency_code | string | Es el código de moneda de tres letras definido en la norma ISO 4217. | |
units | número | La unidad entera del importe.
Por ejemplo, si currencyCode es "USD", 1 unidad es un dólar estadounidense. | |
nanos | número | Número de unidades nano (10^-9) del importe.
Debe ser un valor entre -999,999,999 y +999,999,999.
Si units es positivo, nanos debe ser positivo o cero.
Si units es cero, nanos puede ser positivo, cero o negativo.
Si units es negativo, nanos debe ser negativo o cero.
Por ejemplo, –$1.75 se representa como units=-1 y nanos=-750,000,000. |
BrandLandingPages
Son las páginas de destino de la marca localizadas para un solo lugar de interés.
| Nombre del campo | Tipo | Requisito | Descripción |
|---|---|---|---|
brand_id | string | Es la marca a la que se aplica esta configuración. | |
localized_landing_pages | array de object(LocalizedLandingPage) | Son las páginas de destino localizadas. Los valores de los campos url y locales deben ser únicos en todas las páginas de destino localizadas. | |
default_url | string | Es la URL de la página de destino predeterminada que se usará cuando ninguna de las páginas de destino localizadas coincida con el idioma del usuario. |
LocalizedLandingPage
Es la página de destino localizada para el lugar de interés.
| Nombre del campo | Tipo | Requisito | Descripción |
|---|---|---|---|
url | string | Es la URL de la página de destino. Longitud máxima: 2,000. | |
locales | array de cadenas | Restringe esta página a los usuarios con la preferencia de idioma especificada. Debe contener etiquetas de idioma, como "en", "en-US" o "sr-Latn". |
Categoría
Representa la categoría del PDI.
Debe coincidir con el campo additional_data oneof que se indica a continuación.
| Nombre | Descripción |
|---|---|
UNKNOWN_CATEGORY | |
HOTEL | |
LOCAL |
DayOfWeek
Representa un día de la semana.
| Nombre | Descripción |
|---|---|
DAY_OF_WEEK_UNSPECIFIED | No se especifica el día de la semana. |
MONDAY | Lunes |
TUESDAY | Martes |
WEDNESDAY | Miércoles |
THURSDAY | Jueves |
FRIDAY | Viernes |
SATURDAY | Sábado |
SUNDAY | Domingo |
additional_data
Obligatorio. Son campos específicos de la categoría.
Debe coincidir con el campo category anterior.
| Nombre del campo | Tipo | Requisito | Descripción |
|---|---|---|---|
hotel_data | object(HotelData) | Es mutuamente excluyente con | Son campos específicos del hotel. |
local_data | object(LocalData) | Es mutuamente excluyente con | Son campos específicos para la configuración local. |
direcciones
Obligatorio. Es la dirección de una ubicación.
| Nombre del campo | Tipo | Requisito | Descripción |
|---|---|---|---|
address | object(PostalAddress) | Es la dirección postal de la ubicación. |
- Formato: Debe ser JPEG, PNG o WebP.
- Tamaño máximo del archivo: Menos de 30 MB por imagen
- Dimensiones máximas: Menos de 75 megapíxeles en total (ancho x alto < 75,000,000)
- Tipo de URL: Es la ruta directa al recurso de imagen (p.ej., termina en .jpg).
- Permisos: Asegúrate de que el servidor de hosting permita el acceso a Googlebot o a los rastreadores, y que no haya ningún archivo robots.txt que bloquee los directorios de imágenes.
Definiciones
Definición de VssPoiFeed
// Represents a Point of Interest (POI) data feed provided by a partner. export message VssPoiFeed { // The POIs in the feed. repeated VssPoi data = 1; }
Definición de VssPoi
// Represents a single Point of Interest (POI) entity e.g. a hotel or // restaurant. export message VssPoi { // Required. A string generated by the partner that identifies a POI. string poi_id = 1; // The entity name, telephone, url and location are used to support // matching partner inventory with entities already present on Google. // Required. The name of the POI. Text name = 2; // The contact telephone number of the POI including its country and // area codes, e.g. +14567891234. string telephone = 3 [(datapol.semantic_type) = ST_PHONE_NUMBER]; // The url of the POI's public website. // Note: This will be used just for matching purposes, not for display. string url = 4; // Required. The location of the POI. GeoCoordinates location = 5; // The address displayed on the UI. Text display_address = 17; // Images of the POI. // Max number of images: 5. repeated Image images = 6; // Average rating for the POI. float rating = 12; // The number of contributing ratings for the `rating` field. int64 num_ratings = 13; // The rating scale used for the `rating` field. If max rating is 5, then // rating_scale is 5. int32 rating_scale = 14; // Represents the category of the POI. // It should match the `additional_data` oneof field below. export enum Category { LOCAL = 4; } // Required. Represents the category of the POI. Category category = 9; // A description of the POI. Text description = 16; // Required. Category specific fields. // It should match the `category` field above. oneof additional_data { // Local specific fields. LocalData local_data = 15; } }
Definición de Text
// Represents a text with localizations. message Text { // Represents a localized string. message LocalizedString { // The text's language tag, such as "en", "en-US" or "sr-Latn". string locale = 1; // The text in the specified locale. string text = 2; } // The localized strings. repeated LocalizedString localizations = 1; // The locale to use as the default language it must be present in the // localizations. string default_locale = 2; }
Definición de GeoCoordinates
// The Geo data of a location, including latitude, longitude, and address. message GeoCoordinates { option (datapol.msg_semantic_type) = ST_LOCATION; // [-90, +90] degrees (inclusive). // Required if longitude is set, otherwise nice to have. double latitude = 1; // [-180, +180] degrees (inclusive). // Required if latitude is set, otherwise nice to have. double longitude = 2; // Required. Address for a location. oneof addresses { // Postal address of the location. PostalAddress address = 3; } }
Definición de PostalAddress
// The postal address for the location. message PostalAddress { option (datapol.msg_semantic_type) = ST_LOCATION; // Required. The country, using ISO 3166-1 alpha-2 country code, e.g. "US". string country = 1; // Required. The locality/city, e.g. "Mountain View". 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; // Required. The postal code, e.g. "94043". string postal_code = 4; // Required. The street address, e.g. "1600 Amphitheatre Pkwy". string street_address = 5; }
Definición de imagen
// Represents an image of the Point of Interest (POI). export message Image { // The url of the image. Google will crawl the media hosted at this URL. // Max length: 2000. string url = 1; // The alternative text to be used for accessibility. Text alt_text = 2; }
Definición de LocalData
// Establishment specific feed data. message LocalData { // The regular business hours of the establishment. BusinessHours business_hours = 1; // Price range of the services offered by the establishment. PriceRange price_range = 2; // The type of establishment. Text establishment_category = 3; // The brand landing pages. repeated BrandLandingPages brand_landing_pages = 4; }
Definición de BrandLandingPages
// The Localized brand landing pages for a single Point of Interest (POI). message BrandLandingPages { // The brand this configuration applies to. string brand_id = 1 [(datapol.semantic_type) = ST_PARTNER_ID]; // Localized landing page for the Point of Interest (POI). message LocalizedLandingPage { // The url of the landing page. // Max length: 2000. string url = 1; // Restricts this page to users with the specified language preference. // Must contain language tags, such as "en", "en-US" or "sr-Latn". repeated string locales = 3; } // The localized landing pages. // The url and locales fields values must be unique across all the localized // landing pages. repeated LocalizedLandingPage localized_landing_pages = 2; // The default landing page url to be used when none of the localized // landing pages matches the user's language. string default_url = 3; }
Ejemplos
Feed de lugares de interés
Nombre de archivo: poi_1707240000.json
{ "data": [ { "poi_id": "test_restaurant_1", "name": { "localizations": [ { "locale": "en", "text": "Tasty Bites Test Restaurant" } ], "default_locale": "en" }, "telephone": "+1234567890", "url": "https://www.tastybitestest.com", "location": { "latitude": 37.422, "longitude": -122.084, "address": { "country": "US", "locality": "Mountain View", "postal_code": "94043", "street_address": "1600 Amphitheatre Pkwy" } }, "display_address": { "localizations": [ { "locale": "en", "text": "1600 Amphitheatre Pkwy, Mountain View, CA 94043" } ], "default_locale": "en" }, "images": [ { "url": "https://www.tastybitestest.com/images/interior.jpg", "alt_text": { "localizations": [ { "locale": "en", "text": "Cozy dining area of Tasty Bites" } ], "default_locale": "en" } } ], "rating": 4.7, "num_ratings": 150, "rating_scale": 5, "category": "LOCAL", "description": { "localizations": [ { "locale": "en", "text": "A mock restaurant for testing the POI feed ingestion." } ], "default_locale": "en" }, "local_data": { "establishment_category": { "localizations": [ { "locale": "en", "text": "Restaurant" } ], "default_locale": "en" }, "price_range": { "min_price": { "currency_code": "USD", "units": 15, "nanos": 0 }, "max_price": { "currency_code": "USD", "units": 45, "nanos": 0 } }, "business_hours": { "time_ranges": [ { "open_day": "MONDAY", "open_time": { "hours": 11, "minutes": 0 }, "close_day": "MONDAY", "close_time": { "hours": 21, "minutes": 0 } }, { "open_day": "TUESDAY", "open_time": { "hours": 11, "minutes": 0 }, "close_day": "TUESDAY", "close_time": { "hours": 21, "minutes": 0 } }, { "open_day": "WEDNESDAY", "open_time": { "hours": 11, "minutes": 0 }, "close_day": "WEDNESDAY", "close_time": { "hours": 21, "minutes": 0 } }, { "open_day": "THURSDAY", "open_time": { "hours": 11, "minutes": 0 }, "close_day": "THURSDAY", "close_time": { "hours": 22, "minutes": 0 } }, { "open_day": "FRIDAY", "open_time": { "hours": 11, "minutes": 0 }, "close_day": "FRIDAY", "close_time": { "hours": 23, "minutes": 0 } }, { "open_day": "SATURDAY", "open_time": { "hours": 10, "minutes": 0 }, "close_day": "SATURDAY", "close_time": { "hours": 23, "minutes": 0 } }, { "open_day": "SUNDAY", "open_time": { "hours": 10, "minutes": 0 }, "close_day": "SUNDAY", "close_time": { "hours": 20, "minutes": 0 } } ] }, "brand_landing_pages": [ { "brand_id": "tasty_bites_brand", "localized_landing_pages": [ { "url": "https://www.tastybitestest.com/en", "locales": ["en-US", "en-GB"] } ], "default_url": "https://www.tastybitestest.com" }, { "brand_id": "delicious_eats_brand", "localized_landing_pages": [ { "url": "https://www.deliciouseats.com/en", "locales": ["en-US", "en-GB"] } ], "default_url": "https://www.deliciouseats.com" } ] } } ] }
Feed de PDI en varios idiomas
Nombre de archivo: poi_multilingual.json
{ "data": [ { "poi_id": "test_restaurant_1", "name": { "localizations": [ { "locale": "en", "text": "Tasty Bites Test Restaurant" }, { "locale": "fr", "text": "Restaurant de test Tasty Bites" } ], "default_locale": "en" }, "telephone": "+1234567890", "url": "https://www.tastybitestest.com", "location": { "latitude": 37.422, "longitude": -122.084, "address": { "country": "US", "locality": "Mountain View", "postal_code": "94043", "street_address": "1600 Amphitheatre Pkwy" } }, "display_address": { "localizations": [ { "locale": "en", "text": "1600 Amphitheatre Pkwy, Mountain View, CA 94043" }, { "locale": "fr", "text": "1600 Amphitheatre Pkwy, Mountain View, CA 94043" } ], "default_locale": "en" }, "images": [ { "url": "https://www.tastybitestest.com/images/interior.jpg", "alt_text": { "localizations": [ { "locale": "en", "text": "Cozy dining area of Tasty Bites" }, { "locale": "fr", "text": "Espace salle à manger accueillant de Tasty Bites" } ], "default_locale": "en" } } ], "rating": 4.7, "num_ratings": 150, "rating_scale": 5, "category": "LOCAL", "description": { "localizations": [ { "locale": "en", "text": "A mock restaurant for testing the POI feed ingestion." }, { "locale": "fr", "text": "Un faux restaurant pour tester l'ingestion de flux de points d'intérêt." } ], "default_locale": "en" }, "local_data": { "establishment_category": { "localizations": [ { "locale": "en", "text": "Restaurant" }, { "locale": "fr", "text": "Restaurant" } ], "default_locale": "en" }, "price_range": { "min_price": { "currency_code": "USD", "units": 15, "nanos": 0 }, "max_price": { "currency_code": "USD", "units": 45, "nanos": 0 } }, "business_hours": { "time_ranges": [ { "open_day": "MONDAY", "open_time": { "hours": 11, "minutes": 0 }, "close_day": "MONDAY", "close_time": { "hours": 21, "minutes": 0 } }, { "open_day": "TUESDAY", "open_time": { "hours": 11, "minutes": 0 }, "close_day": "TUESDAY", "close_time": { "hours": 21, "minutes": 0 } }, { "open_day": "WEDNESDAY", "open_time": { "hours": 11, "minutes": 0 }, "close_day": "WEDNESDAY", "close_time": { "hours": 21, "minutes": 0 } }, { "open_day": "THURSDAY", "open_time": { "hours": 11, "minutes": 0 }, "close_day": "THURSDAY", "close_time": { "hours": 22, "minutes": 0 } }, { "open_day": "FRIDAY", "open_time": { "hours": 11, "minutes": 0 }, "close_day": "FRIDAY", "close_time": { "hours": 23, "minutes": 0 } }, { "open_day": "SATURDAY", "open_time": { "hours": 10, "minutes": 0 }, "close_day": "SATURDAY", "close_time": { "hours": 23, "minutes": 0 } }, { "open_day": "SUNDAY", "open_time": { "hours": 10, "minutes": 0 }, "close_day": "SUNDAY", "close_time": { "hours": 20, "minutes": 0 } } ] }, "brand_landing_pages": [ { "brand_id": "tasty_bites_brand", "localized_landing_pages": [ { "url": "https://www.tastybitestest.com/fr", "locales": ["fr-FR", "fr-CA"] }, { "url": "https://www.tastybitestest.com/en", "locales": ["en-US", "en-GB"] } ], "default_url": "https://www.tastybitestest.com" }, { "brand_id": "delicious_eats_brand", "localized_landing_pages": [ { "url": "https://www.deliciouseats.com/fr", "locales": ["fr-FR", "fr-CA"] }, { "url": "https://www.deliciouseats.com/en", "locales": ["en-US", "en-GB"] } ], "default_url": "https://www.deliciouseats.com" } ] } } ] }