관심 장소 피드 만들기 및 업로드
관심 장소 피드를 만들고 업로드할 때는 다음 안내를 따르세요.
- POI 데이터 파일의 경우 POI 피드에 설명된 사양을 따르세요. 업로드마다 고유한 관심 장소 데이터 파일 이름을 사용하는 것이 좋습니다. 파일 이름에 타임스탬프를 포함합니다(예:
POI_1633621547.json). - 매일 전체 새로고침으로 로컬 POI SFTP 서버에 피드를 업로드합니다.
- SFTP 서버 세부정보는 파트너 포털의 구성 > 피드 섹션에서 확인할 수 있습니다.
- 파트너 포털의 수집 > 기록 섹션에서 피드 수집 상태를 확인합니다.
피드 사양
필드 요구사항
VssPoi
단일 관심 장소(POI) 항목(예: 호텔 또는 레스토랑)을 나타냅니다.
| 필드 이름 | 유형 | 요구사항 | 설명 |
|---|---|---|---|
poi_id | 문자열 | 필수 | 필수 항목입니다. POI를 식별하는 파트너가 생성한 문자열입니다. |
name | object(Text) | 필수 | 필수 항목입니다. 관심 장소의 이름입니다. |
telephone | 문자열 | 국가 및 지역 번호를 포함한 관심 장소의 연락처 전화번호입니다(예: +14567891234). | |
url | 문자열 | 관심 장소의 공개 웹사이트 URL입니다. 참고: 이 정보는 매칭 목적으로만 사용되며 표시되지 않습니다. | |
location | object(GeoCoordinates) | 필수 | 필수 항목입니다. 관심 장소의 위치입니다. |
display_address | object(Text) | UI에 표시되는 주소입니다. | |
images | 객체 배열(Image) | POI 이미지입니다. 최대 이미지 수: 5개 | |
rating | 숫자 | 관심 장소의 평균 평점입니다. | |
num_ratings | 숫자 | rating 필드의 참여 평점 수입니다. | |
rating_scale | 숫자 | rating 필드에 사용되는 평가 척도입니다. 최대 평점이 5인 경우 rating_scale은 5입니다. | |
category | enum(Category) | 필수 | 필수 항목입니다. 관심 장소의 카테고리를 나타냅니다. |
description | object(Text) | 관심 장소에 대한 설명입니다. | |
| oneOf(additional_data) | 필수 | 이 oneOf의 필드 중 하나만 설정할 수 있습니다. |
텍스트
현지화가 적용된 텍스트를 나타냅니다.
| 필드 이름 | 유형 | 요구사항 | 설명 |
|---|---|---|---|
localizations | 객체 배열(LocalizedString) | 현지화된 문자열입니다. | |
default_locale | 문자열 | 기본 언어로 사용할 언어는 현지화에 있어야 합니다. |
LocalizedString
현지화된 문자열을 나타냅니다.
| 필드 이름 | 유형 | 요구사항 | 설명 |
|---|---|---|---|
locale | 문자열 | 텍스트의 언어 태그(예: 'en', 'en-US', 'sr-Latn')입니다. | |
text | 문자열 | 지정된 언어의 텍스트입니다. |
GeoCoordinates
위도, 경도, 주소 등 위치의 지역 데이터입니다.
| 필드 이름 | 유형 | 요구사항 | 설명 |
|---|---|---|---|
latitude | 숫자 | [-90, +90] 도 (포함) 경도가 설정된 경우 필수이며, 그렇지 않은 경우 있으면 좋습니다. | |
longitude | 숫자 | [-180, +180] 도 (포함) 위도가 설정된 경우 필수이고, 그렇지 않으면 있으면 좋습니다. | |
| oneOf(addresses) | 필수 | 이 oneOf의 필드 중 하나만 설정할 수 있습니다. |
PostalAddress
위치의 우편 주소입니다.
| 필드 이름 | 유형 | 요구사항 | 설명 |
|---|---|---|---|
country | 문자열 | 필수 | 필수 항목입니다. 국가입니다(ISO 3166-1 alpha-2 국가 코드 사용, 예: 'US'). |
locality | 문자열 | 필수 | 필수 항목입니다. 지역/도시입니다(예: '마운틴 뷰'). |
region | 문자열 | 지역/주/도입니다(예: 'CA'). 이 필드는 보통 지역이 주소의 일부인 국가에서만 필요합니다. (선택사항) | |
postal_code | 문자열 | 필수 | 필수 항목입니다. 우편번호입니다(예: '94043'). |
street_address | 문자열 | 필수 | 필수 항목입니다. 상세 주소(예: '1600 Amphitheatre Pkwy')입니다. |
이미지
관심 장소 (POI)의 이미지를 나타냅니다.
| 필드 이름 | 유형 | 요구사항 | 설명 |
|---|---|---|---|
url | 문자열 | 이미지의 URL입니다. Google에서 이 URL에서 호스팅되는 미디어를 크롤링합니다. 최대 길이: 2,000 | |
alt_text | object(Text) | 접근성에 사용될 대체 텍스트입니다. |
HotelData
호텔별 피드 데이터입니다.
| 필드 이름 | 유형 | 요구사항 | 설명 |
|---|---|---|---|
hotel_star_class | 숫자 | 공식 호텔 등급 별 값입니다. '5성급 호텔'과 같은 라벨에 사용할 수 있습니다. 이 값은 1~5 사이의 정수여야 합니다. | |
brand_ids | 문자열 배열 | 이 호텔을 표시할 수 있는 브랜드입니다. 이 필드가 비어 있으면 호텔이 피드와 연결된 브랜드 아래에 표시될 수 있습니다. |
LocalData
시설별 피드 데이터입니다.
| 필드 이름 | 유형 | 요구사항 | 설명 |
|---|---|---|---|
business_hours | object(BusinessHours) | 시설의 정규 영업시간입니다. | |
price_range | object(PriceRange) | 시설에서 제공하는 서비스의 가격대입니다. | |
establishment_category | object(Text) | 시설 유형입니다. | |
brand_landing_pages | 객체 배열(BrandLandingPages) | 브랜드 방문 페이지입니다. |
BusinessHours
이 위치의 영업시간을 나타냅니다. [TimeRange][madden.vss_poi_feed.TimeRange] 인스턴스 컬렉션을 보유합니다. 예: 토요일 오전 9시~오후 12시, 오후 1시~오후 5시에 영업하는 경우: 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 } } 예: 토요일 오후 9시부터 일요일 오전 2시까지 영업하는 경우: time_ranges { open_day: SATURDAY open_time: { hours: 21, minutes: 0 } close_day: SUNDAY close_time: { hours: 2, minutes: 0 } }
| 필드 이름 | 유형 | 요구사항 | 설명 |
|---|---|---|---|
time_ranges | 객체 배열(TimeRange) | 이 관심 장소가 영업 중인 시간의 컬렉션입니다. 각 기간은 주중에 관심 장소가 영업 중인 시간 범위를 나타냅니다. |
TimeRange
지정된 개장 날짜/시간에 시작해 지정된 종료 날짜/시간에 종료하는 관심 장소의 영업 기간을 나타냅니다. 영업 종료 시간은 시작 시간 뒤(예를 들어 당일 이후 시간 또는 이후 날짜)에 와야 합니다.
| 필드 이름 | 유형 | 요구사항 | 설명 |
|---|---|---|---|
open_day | enum(DayOfWeek) | 기간의 시작일입니다. | |
open_time | object(TimeOfDay) | 기간의 시작 시간입니다. | |
close_day | enum(DayOfWeek) | 기간의 종료일입니다. | |
close_time | object(TimeOfDay) | 기간의 종료 시간입니다. |
TimeOfDay
| 필드 이름 | 유형 | 요구사항 | 설명 |
|---|---|---|---|
hours | 숫자 | 24시간 형식의 시간입니다. 0 이상이어야 하며 일반적으로 23 이하여야 합니다. API는 비즈니스 종료 시간과 같은 시나리오에서 '24:00:00' 값을 허용하도록 선택할 수 있습니다. | |
minutes | 숫자 | 시간의 분입니다. 0 이상, 59 이하여야 합니다. | |
seconds | 숫자 | 분의 초입니다. 0 이상이어야 하며 일반적으로 59 이하여야 합니다. API가 윤초를 허용하는 경우 값에 60을 사용할 수 있습니다. | |
nanos | 숫자 | 나노초 단위의 초수입니다. 0 이상, 999,999,999 이하여야 합니다. |
PriceRange
관심 장소에서 제공하는 서비스의 가격 범위입니다.
| 필드 이름 | 유형 | 요구사항 | 설명 |
|---|---|---|---|
min_price | object(Money) | POI에서 제공하는 서비스의 최저 가격입니다. | |
max_price | object(Money) | POI에서 제공하는 서비스의 최고 가격입니다. |
Money
금액과 통화 유형을 나타냅니다.
| 필드 이름 | 유형 | 요구사항 | 설명 |
|---|---|---|---|
currency_code | 문자열 | ISO 4217에 정의된 3자리 통화 코드입니다. | |
units | 숫자 | 금액의 전체 단위입니다.
예를 들어 currencyCode이 "USD"이면 1단위는 1달러(USD)입니다. | |
nanos | 숫자 | 금액의 나노 (10^-9) 단위 수입니다.
이 값은 -999,999,999~+999,999,999(끝값 포함) 사이여야 합니다.
units가 양수이면 nanos는 양수 또는 0이어야 합니다.
units가 0이면 nanos는 양수, 0 또는 음수일 수 있습니다.
units가 음수이면 nanos는 음수 또는 0이어야 합니다.
예를 들어 $-1.75는 units=-1 및 nanos=-750,000,000으로 나타냅니다. |
BrandLandingPages
단일 관심 장소 (POI)의 현지화된 브랜드 방문 페이지입니다.
| 필드 이름 | 유형 | 요구사항 | 설명 |
|---|---|---|---|
brand_id | 문자열 | 이 구성이 적용되는 브랜드입니다. | |
localized_landing_pages | 객체 배열(LocalizedLandingPage) | 현지화된 방문 페이지입니다. url 및 locales 필드 값은 모든 현지화된 방문 페이지에서 고유해야 합니다. | |
default_url | 문자열 | 현지화된 방문 페이지 중 사용자의 언어와 일치하는 페이지가 없는 경우 사용할 기본 방문 페이지 URL입니다. |
LocalizedLandingPage
관심 장소 (POI)의 현지화된 방문 페이지입니다.
| 필드 이름 | 유형 | 요구사항 | 설명 |
|---|---|---|---|
url | 문자열 | 방문 페이지의 URL입니다. 최대 길이: 2,000 | |
locales | 문자열 배열 | 이 페이지를 지정된 언어 환경설정이 있는 사용자로 제한합니다. 'en', 'en-US', 'sr-Latn'과 같은 언어 태그를 포함해야 합니다. |
카테고리
관심 장소의 카테고리를 나타냅니다.
아래의 additional_data oneof 필드와 일치해야 합니다.
| 이름 | 설명 |
|---|---|
UNKNOWN_CATEGORY | |
HOTEL | |
LOCAL |
DayOfWeek
요일을 나타냅니다.
| 이름 | 설명 |
|---|---|
DAY_OF_WEEK_UNSPECIFIED | 요일이 지정되지 않습니다. |
MONDAY | 월요일 |
TUESDAY | 화요일 |
WEDNESDAY | 수요일 |
THURSDAY | 목요일 |
FRIDAY | 금요일 |
SATURDAY | 토요일 |
SUNDAY | 일요일 |
additional_data
필수 항목입니다. 카테고리별 필드입니다.
위의 category 필드와 일치해야 합니다.
| 필드 이름 | 유형 | 요구사항 | 설명 |
|---|---|---|---|
hotel_data | object(HotelData) |
| 호텔 관련 필드입니다. |
local_data | object(LocalData) |
| 현지별 필드입니다. |
addresses
필수 항목입니다. 위치의 주소입니다.
| 필드 이름 | 유형 | 요구사항 | 설명 |
|---|---|---|---|
address | object(PostalAddress) | 위치의 우편 주소입니다. |
- 형식: JPEG, PNG 또는 WebP여야 합니다.
- 최대 파일 크기: 이미지당 30MB 미만
- 최대 크기: 총 75메가픽셀 미만 (너비 x 높이 < 75,000,000)
- URL 유형: 이미지 확장 소재의 직접 경로 (예: .jpg로 끝남)
- 권한: 호스팅 서버에서 Googlebot 또는 크롤러의 액세스를 허용하고 이미지 디렉터리를 차단하는 robots.txt가 없는지 확인합니다.
정의
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; }
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; } }
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; }
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; } }
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; }
이미지 정의
// 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; }
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; }
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; }
샘플
관심 장소 피드
파일 이름: 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" } ] } } ] }
다국어 관심 장소 피드
파일 이름: 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" } ] } } ] }