google-listings-and-ads
google-listings-and-ads copied to clipboard
Add support for getting price benchmarks & suggestions from the Content API
In order to implement the Price Benchmarks suggestions table described in #2824, we will need to have a REST API endpoint that returns the list of price benchmark suggestions for products in the store.
Acceptance Criteria
- [ ] Price benchmarks can be fetched using a GET request to
/wp-json/wc/gla/mc/price-benchmarks/ - [ ] Price benchmarks are not publicly accessible.
- [ ] Price benchmarks will return a list of object with the following fields:
- Product
- ID
- Thumbnail
- Title
- Effectiveness
- Regular price
- Price on Google
- Price gap
- Suggested price
- Product
- [ ] Price benchmarks will return 10 items and allow additional items to be returned (pagination TBD).
- [ ] Error handling must be included and return an exception response
Implementation Brief
- The REST API endpoint should be implemented in a new
PriceBenchmarkscontroller in/src/API/Site/Controllers/MerchantCenter. GETrequests should make use of theBaseController::get_permission_callback()to ensure this data remains private.- A
get_price_benchmarks_callback()should be used to get and prepare the API response, using the query classes described below. - The query for benchmarks should be handled by a new class in
src/API/Google/QuerycalledMerchantPriceBenchmarksQuerythat extends theMerchantQueryclass. This class can be used to implement the query ofPriceCompetitivenessProductView. See these docs. - The query for price suggestions should be handled by a new class in
src/API/Google/QuerycalledMerchantPriceSuggestionsQuerythat extends theMerchantQueryclass. This class can be used to implement the query ofPriceInsightsProductView. See these docs. - Additional product data like thumbnail, product title, etc. can come from the local Woo DB.
- The query classes should use the
OptionsAwareTraitto be able to pass the merchant center ID to the query like$this->options->get_merchant_id().
Test Coverage
- Add PHPUnit test coverage for the return value of the GET callback.
- Add PHPUnit test coverage for any new service methods used to query Google APIs
@mikkamp curious to get your feedback on the implementation approach described in this one. I'm not sure if there needs to be another service between the API controller and the query classes.
Some other questions I had while thinking through this:
- ~Is there a better capability to check than
manage_optionsfor users who are able to see the plugin settings page in the admin? Thinking specifically for the permissions_callback for the API endpoint.~ - Would it be better to return a truncated product object in the REST responses or just use the IDs to fetch the related product data in a separate request? I assume the former.
I think I've answered my own question about the permissions callback after looking at a few other examples of registered endpoints. I've updated the implementation details to use the BaseController::get_permission_callback method.
I'm also thinking that we might want to go ahead and implement a field to pass a product ID to this endpoint, e.g. /mc/price-benchmarks/(?P<id>[\d]+) to use for the price change modal.
Would it be better to return a truncated product object in the REST responses or just use the IDs to fetch the related product data in a separate request? I assume the former.
It would be better to just need one API request, collecting the needed product details shouldn't add too much overhead. Especially if it's limited to 10 results.
I'm also thinking that we might want to go ahead and implement a field to pass a product ID to this endpoint, e.g. /mc/price-benchmarks/(?P
[\d]+) to use for the price change modal.
+1
Price benchmarks will return 10 items and support standard ?page=, ?per_page= params
We might need to think about this some more, but just want to point out that we had to adjust the logic for other endpoints: https://ads-developers.googleblog.com/2024/07/upcoming-changes-to-page-size-in-google.html
The local endpoint could still provide a per_page parameter, but we don't have anywhere in our extension where we map between a local paginated result and a Google Ads API result with potentially 10,000 rows. So it is possible, but would need some extra engineering time.
Just realized this was for the Content API, not the Ads API. 🤦🏻 You can ignore the last part then about the page size.
What we do have to take into consideration though, is that the Content API works with next_page_token, so it would be simpler to re-use that logic instead of having a page parameter.
That might affect how the UI looks and whether it allows jumping to a page in the middle of the result set.
Thanks for the note about next_page_token, that approach makes sense to me. I don't see any endpoints that already make use of those tokens for loading additional data. Is that correct, or am I missing one?
For the UI that will make use of this data, it currently expects to be able to show paginated results, which I assume is not really doable with the content API, so we'll investigate some alternatives unless you've needed to handle this type of use case before.
Update: Docs for pagination in the Content API are at: https://developers.google.com/shopping-content/guides/reports/paging
I don't see any endpoints that already make use of those tokens for loading additional data. Is that correct, or am I missing one?
It's there in the MerchantReport, but we don't break it down in a table view where we get only a few results per page.
@ankitguptaindia this is ready for testing in the feature/2824-price-benchmarks branch, though in order to verify that the data is being returned as expected, we'll need access to an MC account that has access to Price Competitiveness and Price Insights reporting data.
@joemcgill Follow-up PR #2848 approved and merged.