Repository: googlemaps/google-maps-services-go
Pull request #261 (2022-01-15 22:48:04)

chore: Add status badges to READM
Add the following new badges to `README.md`:

[![Go Report Card](https://goreportcard.com/badge/github.com/googlemaps/google-maps-services-go)](https://goreportcard.com/report/github.com/googlemaps/google-maps-services-go)
![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/googlemaps/google-maps-services-go)
[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)


Patch:
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 355feb8..da514f1 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -1,1 +1,1 @@
-.github/ @googlemaps/dpe
+.github/ @googlemaps/admin
diff --git a/.github/sync-repo-settings.yaml b/.github/sync-repo-settings.yaml
new file mode 100644
index 0000000..a7b2d39
--- /dev/null
+++ b/.github/sync-repo-settings.yaml
@@ -0,0 +1,44 @@
+# Copyright 2022 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.
+
+# https://github.com/googleapis/repo-automation-bots/tree/main/packages/sync-repo-settings
+
+rebaseMergeAllowed: true
+squashMergeAllowed: true
+mergeCommitAllowed: false
+deleteBranchOnMerge: true
+branchProtectionRules:
+- pattern: main
+  isAdminEnforced: false
+  requiresStrictStatusChecks: false
+  requiredStatusCheckContexts:
+    - 'cla/google'
+    - 'test'
+    - 'snippet-bot check'
+    - 'header-check'
+  requiredApprovingReviewCount: 1
+  requiresCodeOwnerReviews: true
+- pattern: master
+  isAdminEnforced: false
+  requiresStrictStatusChecks: false
+  requiredStatusCheckContexts:
+    - 'cla/google'
+    - 'test'
+    - 'snippet-bot check'
+    - 'header-check'
+  requiredApprovingReviewCount: 1
+  requiresCodeOwnerReviews: true
+permissionRules:
+  - team: admin
+    permission: admin
diff --git a/.github/workflows/dependabot.yml b/.github/workflows/dependabot.yml
new file mode 100644
index 0000000..6b46ebb
--- /dev/null
+++ b/.github/workflows/dependabot.yml
@@ -0,0 +1,32 @@
+# Copyright 2022 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.
+
+name: Dependabot
+on: pull_request
+
+permissions:
+  contents: write
+
+jobs:
+  dependabot:
+    runs-on: ubuntu-latest
+    if: ${{ github.actor == 'dependabot[bot]' }}
+    env:
+      PR_URL: ${{github.event.pull_request.html_url}}
+      GITHUB_TOKEN: ${{secrets.SYNCED_GITHUB_TOKEN_REPO}}
+    steps:
+      - name: approve
+        run: gh pr review --approve "$PR_URL"
+      - name: merge
+        run: gh pr merge --auto --squash --delete-branch "$PR_URL"
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 92b75ff..e5e9936 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -21,12 +21,13 @@ jobs:
     runs-on: ubuntu-latest    
     steps:
     - name: Checkout
-      uses: actions/checkout@v2
+      uses: actions/checkout@v3
       with:
         token: ${{ secrets.SYNCED_GITHUB_TOKEN_REPO }} 
     - name: Semantic Release
-      uses: cycjimmy/semantic-release-action@v2
+      uses: cycjimmy/semantic-release-action@v3
       with:
+        semantic_version: 19
         extra_plugins: |
           "@semantic-release/commit-analyzer"
           "@semantic-release/release-notes-generator"
diff --git a/README.md b/README.md
index c134952..c360fc5 100644
--- a/README.md
+++ b/README.md
@@ -3,13 +3,15 @@ Go Client for Google Maps Services
 
 [![Build Status](https://travis-ci.org/googlemaps/google-maps-services-go.svg?branch=master)](https://travis-ci.org/googlemaps/google-maps-services-go)
 [![GoDoc](https://godoc.org/googlemaps.github.io/maps?status.svg)](https://godoc.org/googlemaps.github.io/maps)
+[![Go Report Card](https://goreportcard.com/badge/github.com/googlemaps/google-maps-services-go)](https://goreportcard.com/report/github.com/googlemaps/google-maps-services-go)
+![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/googlemaps/google-maps-services-go)
+[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
 
 ## Description
 
 Use Go? Want to [geocode][Geocoding API] something? Looking for [directions][Directions API]?
 Maybe [matrices of directions][Distance Matrix API]? This library brings the [Google Maps API Web
 Services] to your Go application.
-![Analytics](https://maps-ga-beacon.appspot.com/UA-12846745-20/google-maps-services-go/readme?pixel)
 
 The Go Client for Google Maps Services is a Go Client library for the following Google Maps
 APIs:
@@ -79,7 +81,7 @@ For even more information, see the guide to [API keys][apikey].
 To install the Go Client for Google Maps Services, please execute the following `go get` command.
 
 ```bash
-    go get googlemaps.github.io/maps
+go get googlemaps.github.io/maps
 ```
 
 ## Developer Documentation
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 0000000..6d19135
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,10 @@
+# Report a security issue
+
+To report a security issue, please use https://g.co/vulnz. We use
+https://g.co/vulnz for our intake, and do coordination and disclosure here on
+GitHub (including using GitHub Security Advisory). The Google Security Team will
+respond within 5 working days of your report on g.co/vulnz.
+
+To contact us about other bugs, please open an issue on GitHub.
+
+> **Note**: This file is synchronized from the https://github.com/googlemaps/.github repository.
diff --git a/places.go b/places.go
index d95db03..5f867f4 100644
--- a/places.go
+++ b/places.go
@@ -400,6 +400,14 @@ func (r *PlaceDetailsRequest) params() url.Values {
 		q.Set("region", r.Region)
 	}
 
+	if r.ReviewsNoTranslations {
+		q.Set("reviews_no_translations", "true")
+	}
+
+	if r.ReviewsSort != "" {
+		q.Set("reviews_sort", r.ReviewsSort)
+	}
+
 	return q
 }
 
@@ -413,7 +421,7 @@ type PlaceDetailsRequest struct {
 	Language string
 	// Fields allows you to select which parts of the returned details structure
 	// should be filled in. For more detail, please see the following URL:
-	// https://cloud.google.com/maps-platform/user-guide/product-changes/#places
+	// https://developers.google.com/maps/documentation/places/web-service/details#fields
 	Fields []PlaceDetailsFieldMask
 	// SessionToken is a token that marks this request as part of a Place Autocomplete
 	// Session. Optional.
@@ -422,6 +430,28 @@ type PlaceDetailsRequest struct {
 	// two-character value. Most ccTLD codes are identical to ISO 3166-1 codes, with
 	// some exceptions. This parameter will only influence, not fully restrict, results.
 	Region string
+	// ReviewsNoTranslations specifies whether to translate reviews. Specify
+	// ReviewsNoTranslations=true to disable translation of reviews; specify
+	// ReviewsNoTranslations=false to enable translation of reviews. Reviews
+	// are returned in their original language.
+	//
+	// If omitted, or passed with no value, translation of reviews is enabled. If
+	// the language parameter was specified in the request, use the specified
+	// language as the preferred language for translation. If language is
+	// omitted, the API attempts to use the Accept-Language header as the
+	// preferred language.
+	ReviewsNoTranslations bool
+	// ReviewsSort specifies the sorting method to use when returning reviews.
+	// Can be set to most_relevant (default) or newest.
+	//
+	//For most_relevant (default), reviews are sorted by relevance; the service
+	// will bias the results to return reviews originally written in the
+	// preferred language.
+	// For newest, reviews are sorted in chronological order; the preferred
+	// language does not affect the sort order.
+	// Google recommends that you display how the reviews are being sorted to the
+	// end user.
+	ReviewsSort string
 }
 
 // PlaceDetailsResult is an individual Places API Place Details result
@@ -433,6 +463,20 @@ type PlaceDetailsResult struct {
 	FormattedAddress string `json:"formatted_address,omitempty"`
 	// AdrAddress is the address in the "adr" microformat.
 	AdrAddress string `json:"adr_address,omitempty"`
+	// BusinessStatus is a string indicating the operational status of the
+	// place, if it is a business.
+	BusinessStatus string `json:"business_status,omitempty"`
+	// CurbsidePickup specifies if the business supports curbside pickup.
+	CurbsidePickup bool `json:"curbside_pickup,omitempty"`
+	// Delivery specifies if the business supports delivery.
+	Delivery bool `json:"delivery,omitempty"`
+	// DineIn specifies if the business supports seating options.
+	DineIn bool `json:"dine_in,omitempty"`
+	// EditorialSummary contains a summary of the place. A summary is comprised
+	// of a textual overview, and also includes the language code for these if
+	// applicable. Summary text must be presented as-is and can not be modified
+	// or altered.
+	EditorialSummary *PlaceEditorialSummary `json:"editorial_summary,omitempty"`
 	// FormattedPhoneNumber contains the place's phone number in its local format. For
 	// example, the formatted_phone_number for Google's Sydney, Australia office is
 	// (02) 9374 4000.
@@ -446,54 +490,90 @@ type PlaceDetailsResult struct {
 	// location (geocode) of the place and (optionally) the viewport identifying its
 	// general area of coverage.
 	Geometry AddressGeometry `json:"geometry,omitempty"`
-	// Name contains the human-readable name for the returned result. For establishment
-	// results, this is usually the business name.
-	Name string `json:"name,omitempty"`
 	// Icon contains the URL of a recommended icon which may be displayed to the user
 	// when indicating this result.
 	Icon string `json:"icon,omitempty"`
-	// PlaceID is a textual identifier that uniquely identifies a place.
-	PlaceID string `json:"place_id,omitempty"`
-	// Rating contains the place's rating, from 1.0 to 5.0, based on aggregated user
-	// reviews.
-	Rating float32 `json:"rating,omitempty"`
-	// UserRatingsTotal contains total number of the place's ratings
-	UserRatingsTotal int `json:"user_ratings_total,omitempty"`
-	// Types contains an array of feature types describing the given result.
-	Types []string `json:"types,omitempty"`
+	// Name contains the human-readable name for the returned result. For establishment
+	// results, this is usually the business name.
+	Name string `json:"name,omitempty"`
 	// OpeningHours may contain whether the place is open now or not.
 	OpeningHours *OpeningHours `json:"opening_hours,omitempty"`
-	// Photos is an array of photo objects, each containing a reference to an image.
-	Photos []Photo `json:"photos,omitempty"`
-	// PriceLevel is the price level of the place, on a scale of 0 to 4.
-	PriceLevel int `json:"price_level,omitempty"`
-	// Vicinity contains a feature name of a nearby location.
-	Vicinity string `json:"vicinity,omitempty"`
+	// CurrentOpeningHours may contain the hours of operation for the next seven
+	// days (including today). The time period starts at midnight on the date of
+	// the request and ends at 11:59 pm six days later. This field includes the
+	// special_days subfield of all hours, set for dates that have exceptional
+	// hours.
+	CurrentOpeningHours *OpeningHours `json:"current_opening_hours,omitempty"`
+	// SecondaryOpeningHours may contain an array of entries for the next seven
+	// days including information about secondary hours of a business. Secondary
+	// hours are different from a business's main hours. For example, a
+	// restaurant can specify drive through hours or delivery hours as its
+	// secondary hours. This field populates the type subfield, which draws from
+	// a predefined list of opening hours types (such as DRIVE_THROUGH, PICKUP,
+	// or TAKEOUT) based on the types of the place. This field includes the
+	// special_days subfield of all hours, set for dates that have exceptional
+	// hours.
+	SecondaryOpeningHours []OpeningHours `json:"secondary_opening_hours,omitempty"`
 	// PermanentlyClosed is a boolean flag indicating whether the place has permanently
 	// shut down (value true). If the place is not permanently closed, the flag is
 	// absent from the response.
+	//
+	// Deprecated: Use BusinessStatus instead.
 	PermanentlyClosed bool `json:"permanently_closed,omitempty"`
-	// BusinessStatus is a string indicating the operational status of the
-	// place, if it is a business.
-	BusinessStatus string `json:"business_status,omitempty"`
+	// Photos is an array of photo objects, each containing a reference to an image.
+	Photos []Photo `json:"photos,omitempty"`
+	// PlaceID is a textual identifier that uniquely identifies a place.
+	PlaceID string `json:"place_id,omitempty"`
+	// PriceLevel is the price level of the place, on a scale of 0 to 4.
+	PriceLevel int `json:"price_level,omitempty"`
+	// Rating contains the place's rating, from 1.0 to 5.0, based on aggregated user
+	// reviews.
+	Rating float32 `json:"rating,omitempty"`
+	// Reservable specifies if the place supports reservations.
+	Reservable bool `json:"reservable,omitempty"`
 	// Reviews is an array of up to five reviews. If a language parameter was specified
 	// in the Place Details request, the Places Service will bias the results to prefer
 	// reviews written in that language.
 	Reviews []PlaceReview `json:"reviews,omitempty"`
+	// ServesBeer specifies if the place serves beer.
+	ServesBeer bool `json:"serves_beer,omitempty"`
+	// ServesBreakfast specifies if the place serves breakfast.
+	ServesBreakfast bool `json:"serves_breakfast,omitempty"`
+	// ServesBrunch specifies if the place serves brunch.
+	ServesBrunch bool `json:"serves_brunch,omitempty"`
+	// ServesDinner specifies if the place serves dinner.
+	ServesDinner bool `json:"serves_dinner,omitempty"`
+	// ServesLunch specifies if the place serves lunch.
+	ServesLunch bool `json:"serves_lunch,omitempty"`
+	// ServesVegetarianFood specifies if the place serves vegetarian food.
+	ServesVegetarianFood bool `json:"serves_vegetarian_food,omitempty"`
+	// ServesWine specifies if the place serves wine.
+	ServesWine bool `json:"serves_wine,omitempty"`
+	// Takeout specifies if the business supports takeout.
+	Takeout bool `json:"takeout,omitempty"`
+	// Types contains an array of feature types describing the given result.
+	Types []string `json:"types,omitempty"`
+	// URL contains the URL of the official Google page for this place. This will be the
+	// establishment's Google+ page if the Google+ page exists, otherwise it will be the
+	// Google-owned page that contains the best available information about the place.
+	// Applications must link to or embed this page on any screen that shows detailed
+	// results about the place to the user.
+	URL string `json:"url,omitempty"`
+	// UserRatingsTotal contains total number of the place's ratings
+	UserRatingsTotal int `json:"user_ratings_total,omitempty"`
 	// UTCOffset contains the number of minutes this place’s current timezone is offset
 	// from UTC. For example, for places in Sydney, Australia during daylight saving
 	// time this would be 660 (+11 hours from UTC), and for places in California outside
 	// of daylight saving time this would be -480 (-8 hours from UTC).
 	UTCOffset *int `json:"utc_offset,omitempty"`
+	// Vicinity contains a feature name of a nearby location.
+	Vicinity string `json:"vicinity,omitempty"`
 	// Website lists the authoritative website for this place, such as a business'
 	// homepage.
 	Website string `json:"website,omitempty"`
-	// URL contains the URL of the official Google page for this place. This will be the
-	// establishment's Google+ page if the Google+ page exists, otherwise it will be the
-	// Google-owned page that contains the best available information about the place.
-	// Applications must link to or embed this page on any screen that shows detailed
-	// results about the place to the user.
-	URL string `json:"url,omitempty"`
+	// WheelchairAccessibleEntrance specifies if the place has an entrance that
+	// is wheelchair-accessible.
+	WheelchairAccessibleEntrance bool `json:"wheelchair_accessible_entrance,omitempty"`
 	// HTMLAttributions contain a set of attributions about this listing which must be
 	// displayed to the user.
 	HTMLAttributions []string `json:"html_attributions,omitempty"`
diff --git a/types.go b/types.go
index 78a5ab9..4b40d0a 100644
--- a/types.go
+++ b/types.go
@@ -155,6 +155,17 @@ type Photo struct {
 	HTMLAttributions []string `json:"html_attributions"`
 }
 
+// PlaceEditorialSummary contains a summary of the place. A summary is
+// comprised of a textual overview, and also includes the language code for
+// these if applicable. Summary text must be presented as-is and can not be
+// modified or altered.
+type PlaceEditorialSummary struct {
+	// Language is the language of the previous fields. May not always be present.
+	Language string `json:"language,omitempty"`
+	// Overview is a medium-length textual summary of the place.
+	Overview string `json:"overview,omitempty"`
+}
+
 // Component specifies a key for the parts of a structured address. See
 // https://developers.google.com/maps/documentation/geocoding/intro#ComponentFiltering
 // for more detail.
@@ -502,7 +513,7 @@ func ParseAutocompletePlaceType(placeType string) (AutocompletePlaceType, error)
 
 // PlaceDetailsFieldMask allows you to specify which fields are to be returned with
 // a place details request. Please see the following URL for more detail:
-// https://cloud.google.com/maps-platform/user-guide/product-changes/#places
+// https://developers.google.com/maps/documentation/places/web-service/details#fields
 type PlaceDetailsFieldMask string
 
 // The individual Place Details Field Masks.
@@ -510,6 +521,10 @@ const (
 	PlaceDetailsFieldMaskAddressComponent             = PlaceDetailsFieldMask("address_component")
 	PlaceDetailsFieldMaskADRAddress                   = PlaceDetailsFieldMask("adr_address")
 	PlaceDetailsFieldMaskBusinessStatus               = PlaceDetailsFieldMask("business_status")
+	PlaceDetailsFieldMaskCurbsidePickup               = PlaceDetailsFieldMask("curbside_pickup")
+	PlaceDetailsFieldMaskDelivery                     = PlaceDetailsFieldMask("delivery")
+	PlaceDetailsFieldMaskDineIn                       = PlaceDetailsFieldMask("dine_in")
+	PlaceDetailsFieldMaskEditorialSummary             = PlaceDetailsFieldMask("editorial_summary")
 	PlaceDetailsFieldMaskFormattedAddress             = PlaceDetailsFieldMask("formatted_address")
 	PlaceDetailsFieldMaskFormattedPhoneNumber         = PlaceDetailsFieldMask("formatted_phone_number")
 	PlaceDetailsFieldMaskGeometry                     = PlaceDetailsFieldMask("geometry")
@@ -528,18 +543,30 @@ const (
 	PlaceDetailsFieldMaskInternationalPhoneNumber     = PlaceDetailsFieldMask("international_phone_number")
 	PlaceDetailsFieldMaskName                         = PlaceDetailsFieldMask("name")
 	PlaceDetailsFieldMaskOpeningHours                 = PlaceDetailsFieldMask("opening_hours")
+	PlaceDetailsFieldMaskCurrentOpeningHours          = PlaceDetailsFieldMask("current_opening_hours")
+	PlaceDetailsFieldMaskSecondaryOpeningHours        = PlaceDetailsFieldMask("secondary_opening_hours")
 	PlaceDetailsFieldMaskPermanentlyClosed            = PlaceDetailsFieldMask("permanently_closed")
 	PlaceDetailsFieldMaskPhotos                       = PlaceDetailsFieldMask("photos")
 	PlaceDetailsFieldMaskPlaceID                      = PlaceDetailsFieldMask("place_id")
 	PlaceDetailsFieldMaskPriceLevel                   = PlaceDetailsFieldMask("price_level")
 	PlaceDetailsFieldMaskRatings                      = PlaceDetailsFieldMask("rating")
 	PlaceDetailsFieldMaskUserRatingsTotal             = PlaceDetailsFieldMask("user_ratings_total")
+	PlaceDetailsFieldMaskReservable                   = PlaceDetailsFieldMask("reservable")
 	PlaceDetailsFieldMaskReviews                      = PlaceDetailsFieldMask("reviews")
+	PlaceDetailsFieldMaskServesBeer                   = PlaceDetailsFieldMask("serves_beer")
+	PlaceDetailsFieldMaskServesBreakfast              = PlaceDetailsFieldMask("serves_breakfast")
+	PlaceDetailsFieldMaskServesBrunch                 = PlaceDetailsFieldMask("serves_brunch")
+	PlaceDetailsFieldMaskServesDinner                 = PlaceDetailsFieldMask("serves_dinner")
+	PlaceDetailsFieldMaskServesLunch                  = PlaceDetailsFieldMask("serves_lunch")
+	PlaceDetailsFieldMaskServesVegetarianFood         = PlaceDetailsFieldMask("serves_vegetarian_food")
+	PlaceDetailsFieldMaskServesWine                   = PlaceDetailsFieldMask("serves_wine")
+	PlaceDetailsFieldMaskTakeout                      = PlaceDetailsFieldMask("takeout")
 	PlaceDetailsFieldMaskTypes                        = PlaceDetailsFieldMask("types")
 	PlaceDetailsFieldMaskURL                          = PlaceDetailsFieldMask("url")
 	PlaceDetailsFieldMaskUTCOffset                    = PlaceDetailsFieldMask("utc_offset")
 	PlaceDetailsFieldMaskVicinity                     = PlaceDetailsFieldMask("vicinity")
 	PlaceDetailsFieldMaskWebsite                      = PlaceDetailsFieldMask("website")
+	PlaceDetailsFieldMaskWheelchairAccessibleEntrance = PlaceDetailsFieldMask("wheelchair_accessible_entrance")
 )
 
 // ParsePlaceDetailsFieldMask will parse a string representation of
@@ -552,6 +579,14 @@ func ParsePlaceDetailsFieldMask(placeDetailsFieldMask string) (PlaceDetailsField
 		return PlaceDetailsFieldMaskADRAddress, nil
 	case "business_status":
 		return PlaceDetailsFieldMaskBusinessStatus, nil
+	case "curbside_pickup":
+		return PlaceDetailsFieldMaskCurbsidePickup, nil
+	case "delivery":
+		return PlaceDetailsFieldMaskDelivery, nil
+	case "dine_in":
+		return PlaceDetailsFieldMaskDineIn, nil
+	case "editorial_summary":
+		return PlaceDetailsFieldMaskEditorialSummary, nil
 	case "formatted_address":
 		return PlaceDetailsFieldMaskFormattedAddress, nil
 	case "formatted_phone_number":
@@ -588,6 +623,10 @@ func ParsePlaceDetailsFieldMask(placeDetailsFieldMask string) (PlaceDetailsField
 		return PlaceDetailsFieldMaskName, nil
 	case "opening_hours":
 		return PlaceDetailsFieldMaskOpeningHours, nil
+	case "current_opening_hours":
+		return PlaceDetailsFieldMaskCurrentOpeningHours, nil
+	case "secondary_opening_hours":
+		return PlaceDetailsFieldMaskSecondaryOpeningHours, nil
 	case "permanently_closed":
 		return PlaceDetailsFieldMaskPermanentlyClosed, nil
 	case "photos":
@@ -600,8 +639,26 @@ func ParsePlaceDetailsFieldMask(placeDetailsFieldMask string) (PlaceDetailsField
 		return PlaceDetailsFieldMaskRatings, nil
 	case "user_ratings_total":
 		return PlaceDetailsFieldMaskUserRatingsTotal, nil
+	case "reservable":
+		return PlaceDetailsFieldMaskReservable, nil
 	case "reviews":
 		return PlaceDetailsFieldMaskReviews, nil
+	case "serves_beer":
+		return PlaceDetailsFieldMaskServesBeer, nil
+	case "serves_breakfast":
+		return PlaceDetailsFieldMaskServesBreakfast, nil
+	case "serves_brunch":
+		return PlaceDetailsFieldMaskServesBrunch, nil
+	case "serves_dinner":
+		return PlaceDetailsFieldMaskServesDinner, nil
+	case "serves_lunch":
+		return PlaceDetailsFieldMaskServesLunch, nil
+	case "serves_vegetarian_food":
+		return PlaceDetailsFieldMaskServesVegetarianFood, nil
+	case "serves_wine":
+		return PlaceDetailsFieldMaskServesWine, nil
+	case "takeout":
+		return PlaceDetailsFieldMaskTakeout, nil
 	case "types":
 		return PlaceDetailsFieldMaskTypes, nil
 	case "url":
@@ -612,6 +669,8 @@ func ParsePlaceDetailsFieldMask(placeDetailsFieldMask string) (PlaceDetailsField
 		return PlaceDetailsFieldMaskVicinity, nil
 	case "website":
 		return PlaceDetailsFieldMaskWebsite, nil
+	case "wheelchair_accessible_entrance":
+		return PlaceDetailsFieldMaskWheelchairAccessibleEntrance, nil
 	default:
 		return PlaceDetailsFieldMask(""), fmt.Errorf("Unknown PlaceDetailsFieldMask \"%v\"", placeDetailsFieldMask)
 	}
@@ -666,6 +725,8 @@ const (
 // PlaceSearchFieldMask.
 func ParsePlaceSearchFieldMask(placeSearchFieldMask string) (PlaceSearchFieldMask, error) {
 	switch strings.ToLower(placeSearchFieldMask) {
+	case "business_status":
+		return PlaceSearchFieldMaskBusinessStatus, nil
 	case "formatted_address":
 		return PlaceSearchFieldMaskFormattedAddress, nil
 	case "geometry":


Test patch:
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index b9e75f0..648f2e6 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -18,11 +18,11 @@ jobs:
   build:
     runs-on: ubuntu-latest
     steps:
-    - uses: actions/setup-go@v1
+    - uses: actions/setup-go@v3
       with:
-        go-version: 1.13
+        go-version: 'stable'
       id: go
-    - uses: actions/checkout@v2
+    - uses: actions/checkout@v3
     - run: go build -v ./...
     - run: go test -v -race -coverprofile=coverage.txt -covermode=atomic ./...
-    - uses: codecov/codecov-action@v1
\ No newline at end of file
+    - uses: codecov/codecov-action@v3
diff --git a/places_test.go b/places_test.go
index 3118651..469671a 100644
--- a/places_test.go
+++ b/places_test.go
@@ -651,84 +651,155 @@ func TestPlaceAutocompleteWithStructuredFormatting(t *testing.T) {
 func TestPlaceDetails(t *testing.T) {
 	response := `
 {
-   "html_attributions" : [],
-   "result" : {
-      "address_components" : [],
-      "formatted_address" : "3, Overseas Passenger Terminal, George St & Argyle Street, The Rocks NSW 2000, Australia",
-      "formatted_phone_number" : "(02) 9251 5600",
-      "geometry" : {
-         "location" : {
-            "lat" : -33.858018,
-            "lng" : 151.210091
-         }
-      },
-      "icon" : "https://maps.gstatic.com/mapfiles/place_api/icons/restaurant-71.png",
-      "international_phone_number" : "+61 2 9251 5600",
-      "name" : "Quay",
-      "opening_hours" : {
-         "open_now" : true,
-         "periods" : [
-            {
-               "close" : {
-                  "day" : 1,
-                  "time" : "1700"
-               },
-               "open" : {
-                  "day" : 1,
-                  "time" : "1330"
-               }
+    "html_attributions": [],
+    "result": {
+        "business_status": "OPERATIONAL",
+        "dine_in": true,
+        "formatted_address": "Upper Level Overseas Passenger Terminal, The Rocks NSW 2000, Australia",
+        "geometry": {
+            "location": {
+                "lat": -33.85756870000001,
+                "lng": 151.2100844
+            },
+            "viewport": {
+                "northeast": {
+                    "lat": -33.8561714197085,
+                    "lng": 151.2113682802915
+                },
+                "southwest": {
+                    "lat": -33.85886938029149,
+                    "lng": 151.2086703197085
+                }
             }
-         ],
-         "weekday_text" : [
-            "Monday: 1:30 – 5:00 pm"
-         ]
-      },
-      "photos" : [
-         {
-            "height" : 612,
-            "html_attributions" : [
-               "\u003ca href=\"https://maps.google.com/maps/contrib/107255044321733286691\"\u003eFrom a Google User\u003c/a\u003e"
+        },
+        "name": "Quay Restaurant",
+        "opening_hours": {
+            "open_now": false,
+            "periods": [
+                {
+                    "close": {
+                        "day": 0,
+                        "time": "2045"
+                    },
+                    "open": {
+                        "day": 0,
+                        "time": "1200"
+                    }
+                },
+                {
+                    "close": {
+                        "day": 4,
+                        "time": "2045"
+                    },
+                    "open": {
+                        "day": 4,
+                        "time": "1800"
+                    }
+                },
+                {
+                    "close": {
+                        "day": 5,
+                        "time": "2045"
+                    },
+                    "open": {
+                        "day": 5,
+                        "time": "1800"
+                    }
+                },
+                {
+                    "close": {
+                        "day": 6,
+                        "time": "2045"
+                    },
+                    "open": {
+                        "day": 6,
+                        "time": "1200"
+                    }
+                }
             ],
-            "photo_reference" : "CmRdAAAAm1qTaarpM_sUatFI7JxjwxVTgKCGSjz62q_vHpNMoZDP3PpBHGW-rAHQEEprl_c1MyvXFhvZb2mXj8yhKvnEMsSveb-cMuDaDgS7LS8sPPrMrt5s_Mx0G0ereom3j6KxEhAkaQH1_nWxpl4W2mFZ1CKoGhQV_Jx9MIn0skBS3tRAuIFzgHARww",
-            "width" : 816
-         }
-      ],
-      "place_id" : "ChIJ02qnq0KuEmsRHUJF4zo1x4I",
-      "price_level" : 4,
-      "rating" : 4.1,
-      "reviews" : [
-         {
-            "aspects" : [
-               {
-                  "rating" : 1,
-                  "type" : "overall"
-               }
-			],
-			"profile_photo_url": "https://lh3.googleusercontent.com/-EXtIWgDBHgs/AAAAAAAAAAI/AAAAAAAAAAA/AIcfdXCXHH76RsCp2i2B0qjO1WngDfIrQQ/s120-p-rw-no-mo/photo.jpg",
-            "author_name" : "Rachel Lewis",
-            "author_url" : "https://plus.google.com/114299517944848975298",
-            "language" : "en",
-            "rating" : 3,
-            "text" : "Overall disappointing. This is the second time i've been there and my experience was... Nothing to nibble on for 45 mins and then the bread came. My first entree was the marron which I thought was tasteless - perhaps others would say delicate? but there you go. The XO sea was fantastic. I chose the  vegetarian main dish which was all about the texture which was great but nothing at all outstanding about the dish. My husband and daughter chose the duck for their main course it was the smallest main course i've ever seen - their faces were priceless when it arrived!. Snow egg was beautiful but the granita on the bottom had some solid chunks of hard ice. The service was quite good...",
-            "time" : 1441848853
-         }
-      ],
-      "types" : [ "restaurant", "food", "point_of_interest", "establishment" ],
-      "url" : "https://plus.google.com/105746337161979416551/about?hl=en-US",
-      "user_ratings_total" : 275,
-      "utc_offset" : 660,
-      "vicinity" : "3 Overseas Passenger Terminal, George Street, The Rocks",
-      "website" : "http://www.quay.com.au/"
-   },
-   "status" : "OK"
+            "weekday_text": [
+                "Monday: Closed",
+                "Tuesday: Closed",
+                "Wednesday: Closed",
+                "Thursday: 6:00 – 8:45 PM",
+                "Friday: 6:00 – 8:45 PM",
+                "Saturday: 12:00 – 8:45 PM",
+                "Sunday: 12:00 – 8:45 PM"
+            ]
+        },
+		"secondary_opening_hours": [
+            {
+                "open_now": true,
+                "periods": [
+                    {
+                        "close": {
+                            "day": 0,
+                            "time": "2045"
+                        },
+                        "open": {
+                            "day": 0,
+                            "time": "1200"
+                        }
+                    },
+                    {
+                        "close": {
+                            "day": 4,
+                            "time": "2045"
+                        },
+                        "open": {
+                            "day": 4,
+                            "time": "1800"
+                        }
+                    },
+                    {
+                        "close": {
+                            "day": 5,
+                            "time": "2045"
+                        },
+                        "open": {
+                            "day": 5,
+                            "time": "1800"
+                        }
+                    },
+                    {
+                        "close": {
+                            "day": 6,
+                            "time": "2045"
+                        },
+                        "open": {
+                            "day": 6,
+                            "time": "1200"
+                        }
+                    }
+                ],
+                "type": "KITCHEN",
+                "weekday_text": [
+                    "Monday: 11:30 AM – 2:00 PM, 5:00 – 10:00 PM",
+                    "Tuesday: 11:30 AM – 2:00 PM, 5:00 – 10:00 PM",
+                    "Wednesday: 11:30 AM – 2:00 PM, 5:00 – 10:00 PM",
+                    "Thursday: 11:30 AM – 2:00 PM, 5:00 – 10:00 PM",
+                    "Friday: 11:30 AM – 2:00 PM, 5:00 – 10:00 PM",
+                    "Saturday: 11:30 AM – 2:00 PM, 5:00 – 10:00 PM",
+                    "Sunday: 11:30 AM – 2:00 PM, 5:00 – 9:00 PM"
+                ]
+            }
+	    ],
+        "place_id": "ChIJ4cQcDV2uEmsRMxTEHBIe9ZQ",
+        "serves_dinner": true,
+        "utc_offset": 660,
+        "wheelchair_accessible_entrance": true
+    },
+    "status": "OK"
 }
 `
 	server := mockServer(200, response)
 	defer server.Close()
 	c, _ := NewClient(WithAPIKey(apiKey), WithBaseURL(server.URL))
-	placeID := "ChIJ02qnq0KuEmsRHUJF4zo1x4I"
+	placeID := "ChIJ4cQcDV2uEmsRMxTEHBIe9ZQ"
+	fields := []PlaceDetailsFieldMask{PlaceDetailsFieldMaskBusinessStatus, PlaceDetailsFieldMaskDineIn, PlaceDetailsFieldMaskFormattedAddress, PlaceDetailsFieldMaskGeometry, PlaceDetailsFieldMaskName, PlaceDetailsFieldMaskCurrentOpeningHours, PlaceDetailsFieldMaskSecondaryOpeningHours, PlaceDetailsFieldMaskPlaceID, PlaceDetailsFieldMaskServesDinner, PlaceDetailsFieldMaskUTCOffset, PlaceDetailsFieldMaskWheelchairAccessibleEntrance}
 	r := &PlaceDetailsRequest{
 		PlaceID: placeID,
+		Fields:  fields,
 	}
 
 	resp, err := c.PlaceDetails(context.Background(), r)
@@ -738,48 +809,42 @@ func TestPlaceDetails(t *testing.T) {
 		return
 	}
 
-	formattedAddress := "3, Overseas Passenger Terminal, George St & Argyle Street, The Rocks NSW 2000, Australia"
-	if formattedAddress != resp.FormattedAddress {
-		t.Errorf("expected %+v, was %+v", formattedAddress, resp.FormattedAddress)
-	}
-
-	formattedPhoneNumber := "(02) 9251 5600"
-	if formattedPhoneNumber != resp.FormattedPhoneNumber {
-		t.Errorf("expected %+v, was %+v", formattedPhoneNumber, resp.FormattedPhoneNumber)
+	businessStatus := "OPERATIONAL"
+	if businessStatus != resp.BusinessStatus {
+		t.Errorf("expected %+v, was %+v", businessStatus, resp.BusinessStatus)
 	}
 
-	icon := "https://maps.gstatic.com/mapfiles/place_api/icons/restaurant-71.png"
-	if icon != resp.Icon {
-		t.Errorf("expected %+v, was %+v", icon, resp.Icon)
+	if !*&resp.DineIn {
+		t.Errorf("Expected DineIn to be true")
 	}
 
-	internationalPhoneNumber := "+61 2 9251 5600"
-	if internationalPhoneNumber != resp.InternationalPhoneNumber {
-		t.Errorf("expected %+v, was %+v", internationalPhoneNumber, resp.InternationalPhoneNumber)
+	formattedAddress := "Upper Level Overseas Passenger Terminal, The Rocks NSW 2000, Australia"
+	if formattedAddress != resp.FormattedAddress {
+		t.Errorf("expected %+v, was %+v", formattedAddress, resp.FormattedAddress)
 	}
 
-	name := "Quay"
+	name := "Quay Restaurant"
 	if name != resp.Name {
 		t.Errorf("expected %+v, was %+v", name, resp.Name)
 	}
 
-	if !*resp.OpeningHours.OpenNow {
-		t.Errorf("Expected OpenNow to be true")
+	if resp.OpeningHours.Periods[0].Open.Day != time.Sunday || resp.OpeningHours.Periods[0].Close.Day != time.Sunday {
+		t.Errorf("OpeningHours.Periods[0].Open.Day or Close.Day incorrect")
 	}
 
-	if *resp.UTCOffset != 660 {
-		t.Errorf("Expected UTCOffset to be 660")
+	if resp.OpeningHours.Periods[0].Open.Time != "1200" || resp.OpeningHours.Periods[0].Close.Time != "2045" {
+		t.Errorf("OpeningHours.Periods[0].Open.Time or Close.Time incorrect")
 	}
 
-	if resp.OpeningHours.Periods[0].Open.Day != time.Monday || resp.OpeningHours.Periods[0].Close.Day != time.Monday {
-		t.Errorf("OpeningHours.Periods[0].Open.Day or Close.Day incorrect")
+	if resp.SecondaryOpeningHours[0].Periods[0].Open.Day != time.Sunday || resp.OpeningHours.Periods[0].Close.Day != time.Sunday {
+		t.Errorf("SecondaryOpeningHours[0].Periods[0].Open.Day or Close.Day incorrect")
 	}
 
-	if resp.OpeningHours.Periods[0].Open.Time != "1330" || resp.OpeningHours.Periods[0].Close.Time != "1700" {
-		t.Errorf("OpeningHours.Periods[0].Open.Time or Close.Time incorrect")
+	if resp.SecondaryOpeningHours[0].Periods[0].Open.Time != "1200" || resp.OpeningHours.Periods[0].Close.Time != "2045" {
+		t.Errorf("SecondaryOpeningHours[0].Periods[0].Open.Time or Close.Time incorrect")
 	}
 
-	weekdayText := "Monday: 1:30 – 5:00 pm"
+	weekdayText := "Monday: Closed"
 	if weekdayText != resp.OpeningHours.WeekdayText[0] {
 		t.Errorf("expected %+v, was %+v", weekdayText, resp.OpeningHours.WeekdayText[0])
 	}
@@ -788,89 +853,18 @@ func TestPlaceDetails(t *testing.T) {
 		t.Errorf("expected %+v, was %+v", placeID, resp.PlaceID)
 	}
 
-	authorName := "Rachel Lewis"
-	if authorName != resp.Reviews[0].AuthorName {
-		t.Errorf("expected %+v, was %+v", authorName, resp.Reviews[0].AuthorName)
-	}
-
-	authorProfilePhoto := "https://lh3.googleusercontent.com/-EXtIWgDBHgs/AAAAAAAAAAI/AAAAAAAAAAA/AIcfdXCXHH76RsCp2i2B0qjO1WngDfIrQQ/s120-p-rw-no-mo/photo.jpg"
-	if authorProfilePhoto != resp.Reviews[0].AuthorProfilePhoto {
-		t.Errorf("expected %+v, was %+v", authorProfilePhoto, resp.Reviews[0].AuthorProfilePhoto)
-	}
-
-	authorURL := "https://plus.google.com/114299517944848975298"
-	if authorURL != resp.Reviews[0].AuthorURL {
-		t.Errorf("expected %+v, was %+v", authorURL, resp.Reviews[0].AuthorURL)
-	}
-
-	language := "en"
-	if language != resp.Reviews[0].Language {
-		t.Errorf("expected %+v, was %+v", language, resp.Reviews[0].Language)
-	}
-
-	rating := 3
-	if rating != resp.Reviews[0].Rating {
-		t.Errorf("expected %+v, was %+v", rating, resp.Reviews[0].Rating)
-	}
-
-	text := "Overall disappointing. This is the second time i've been there and my experience was... Nothing to nibble on for 45 mins and then the bread came. My first entree was the marron which I thought was tasteless - perhaps others would say delicate? but there you go. The XO sea was fantastic. I chose the  vegetarian main dish which was all about the texture which was great but nothing at all outstanding about the dish. My husband and daughter chose the duck for their main course it was the smallest main course i've ever seen - their faces were priceless when it arrived!. Snow egg was beautiful but the granita on the bottom had some solid chunks of hard ice. The service was quite good..."
-	if text != resp.Reviews[0].Text {
-		t.Errorf("expected %+v, was %+v", text, resp.Reviews[0].Text)
+	if !*&resp.ServesDinner {
+		t.Errorf("Expected ServesDinner to be true")
 	}
 
-	time := 1441848853
-	if time != resp.Reviews[0].Time {
-		t.Errorf("expected %+v, was %+v", time, resp.Reviews[0].Time)
-	}
-}
-
-func TestPlaceDetailsUTCOffsetAbsent(t *testing.T) {
-	response := `
-{
-   "html_attributions" : [],
-   "result" : {
-      "address_components" : [],
-      "formatted_address" : "3, Overseas Passenger Terminal, George St & Argyle Street, The Rocks NSW 2000, Australia",
-      "formatted_phone_number" : "(02) 9251 5600",
-      "geometry" : {
-         "location" : {
-            "lat" : -33.858018,
-            "lng" : 151.210091
-         }
-      },
-      "icon" : "https://maps.gstatic.com/mapfiles/place_api/icons/restaurant-71.png",
-      "international_phone_number" : "+61 2 9251 5600",
-      "name" : "Quay",
-      "place_id" : "ChIJ02qnq0KuEmsRHUJF4zo1x4I",
-      "price_level" : 4,
-      "rating" : 4.1,
-      "types" : [ "restaurant", "food", "point_of_interest", "establishment" ],
-      "url" : "https://plus.google.com/105746337161979416551/about?hl=en-US",
-      "user_ratings_total" : 275,
-      "vicinity" : "3 Overseas Passenger Terminal, George Street, The Rocks",
-      "website" : "http://www.quay.com.au/"
-   },
-   "status" : "OK"
-}
-`
-	server := mockServer(200, response)
-	defer server.Close()
-	c, _ := NewClient(WithAPIKey(apiKey), WithBaseURL(server.URL))
-	placeID := "ChIJ02qnq0KuEmsRHUJF4zo1x4I"
-	r := &PlaceDetailsRequest{
-		PlaceID: placeID,
+	if *resp.UTCOffset != 660 {
+		t.Errorf("Expected UTCOffset to be 660")
 	}
 
-	resp, err := c.PlaceDetails(context.Background(), r)
-
-	if err != nil {
-		t.Errorf("r.Get returned non nil error: %v", err)
-		return
+	if !*&resp.WheelchairAccessibleEntrance {
+		t.Errorf("Expected WheelchairAccessibleEntrance to be true")
 	}
 
-	if resp.UTCOffset != nil {
-		t.Errorf("Expected UTCOffset to be nil")
-	}
 }
 
 func TestPlaceDetailsMissingPlaceID(t *testing.T) {
@@ -888,33 +882,6 @@ func TestPlaceDetailsMissingPlaceID(t *testing.T) {
 	}
 }
 
-func TestPlacePhoto(t *testing.T) {
-	photoReference := "ThisIsNotAPhotoReference"
-	expectedQuery := "key=AIzaNotReallyAnAPIKey&maxheight=400&maxwidth=400&photoreference=ThisIsNotAPhotoReference"
-
-	server := mockServerForQuery(expectedQuery, 200, "An Image?")
-	defer server.s.Close()
-
-	c, _ := NewClient(WithAPIKey(apiKey), WithBaseURL(server.s.URL))
-
-	r := &PlacePhotoRequest{
-		PhotoReference: photoReference,
-		MaxHeight:      400,
-		MaxWidth:       400,
-	}
-
-	_, err := c.PlacePhoto(context.Background(), r)
-
-	if err != nil {
-		t.Errorf("Unexpected error in constructing request URL: %+v", err)
-	}
-
-	if server.successful != 1 {
-		t.Errorf("Got URL(s) %v, want %s", server.failed, expectedQuery)
-	}
-
-}
-
 func TestPlacePhotoMissingPhotoReference(t *testing.T) {
 	c, _ := NewClient(WithAPIKey(apiKey))
 	r := &PlacePhotoRequest{}
@@ -1108,7 +1075,7 @@ func TestPlaceAutocompleteJsonMarshalLowerCase(t *testing.T) {
 
 func TestFindPlaceFromText(t *testing.T) {
 	expectedQuery := "fields=photos%2Cformatted_address%2Cname%2Copening_hours%2Crating&input=mongolian+grill&inputtype=textquery&key=AIzaNotReallyAnAPIKey&locationbias=circle%3A2000%4047.6918452%2C-122.2226413"
-	response := `	
+	response := `
 {
 	"candidates" : [
 	   {