amp-geo: Fall back to API for country#26407
Conversation
If country code is not available in a prerendered body's classes or in
amp-geo-0.1.js itself, support falling back to an API request if the
publisher must provide (cdn.ampproject.org will not host a general
country code API).
Allow case insensitive country code in JSON schema (country is most
often presented in uppercase when ISO 3166-1 table is referenced).
JSON schema of Geo API response - version 0.1:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"country": {
"type": "string",
"title": "ISO 3166-1 alpha-2 (case insensitive) country code of client request",
"default": "",
"pattern": "^[a-zA-Z]{2}$"
}
},
"required": [
"country"
]
}
Sample response:
{
"country": "de"
}
temp
temp
|
@Gregable @sebastianbenz @zhouyx @jridgewell - I believe this PR matches the amp-geo API design we discussed (relates to #25873). If any of you have time for a review (or could recommend a reviewer) it would be appreciated. |
|
Thank you @mdmower, as mentioned in the meeting, one thing that we are actively working on is to add more granular geo detection support to amp-geo. Thoughts on supporting ISO 3166-2 format in the future using the same API? |
@zhouyx The JSON schema could either be modified to allow ISO 3166-1 or ISO 3166-2 in a single property (instead of |
|
I prefer the second optional Two concerns I have. These concerns are not blocking this change. But I want to come up with a solution to the first concern when we launch US-CA support.
Thanks |
|
@zhouyx Thanks for the details. I believe this JSON example would satisfy your requirements. Special cases:
Confidence ranges from 0.0 to 1.0 and the sum of all confidences for countries or subdivisions should not exceed 1.0 (but can be less than 1.0). For example, if an API supports only country lookup and has no support for confidence levels or subdivisions, it would report: Let me know if you think a schema that fits this model would be preferable at start, or if it should be introduced later as "Version 0.2". |
|
Thank you for the proposal! I have reached out to the team who provides the amp-geo service, because I don't feel comfortable finalizing the endpoint design before we have a complete story from them. A few concerns we have today
there won't be another entry with confidence level 0.2. Also the confidence level will likely only applies to region value. Because we don't have the design finalized. Let's only focus on country and us-ca for now. What about this region not supported region supported, and in us-ca region supported, not in us-ca. or can't verify region We are still deciding if region value should be "ca" or "us-ca", let's only get "country" support in this PR. |
extensions/amp-geo/0.1/amp-geo.js
Outdated
| * @return {Promise<(string|null)>} | ||
| */ | ||
| fetchCountry_() { | ||
| if (typeof urls.geoApi !== 'string') { |
There was a problem hiding this comment.
@jridgewell Did we require https in urls? If not we should use assertHttpsUrl
There was a problem hiding this comment.
HTTPS sounds like a good requirement to protect user privacy (physical location). assertHttpsUrl is geared more towards AMPHTML elements that have disallowed src attribute values. I opted for isSecureUrlDeprecated, which also makes allowances for localhost testing, since it is a bit more generic and less tied to AmpDoc.
extensions/amp-geo/0.1/amp-geo.js
Outdated
| }) | ||
| .then(res => res.json()) | ||
| .then(json => { | ||
| if (!/^[a-z]{2}$/i.test(json.country)) { |
There was a problem hiding this comment.
nit: please use json['country'] to avoid the name minimize.
extensions/amp-geo/0.1/amp-geo.js
Outdated
| ); | ||
| return null; | ||
| } | ||
| return json.country.toLowerCase(); |
There was a problem hiding this comment.
nit: same here, json['country']
| @@ -199,14 +202,97 @@ export class AmpGeo extends AMP.BaseElement { | |||
| this.mode_ = mode.GEO_HOT_PATCH; | |||
| this.country_ = trimmedCountryMatch[1]; | |||
| } else if (trimmedCountryMatch[0] === '' && !getMode(this.win).localDev) { | |||
There was a problem hiding this comment.
nit: I'd prefer to handle one mode in one if statement block. Can we please change the logic to
else if (...) {
this.mode_ = mode.GEO_HOT_PATCH;
} else if (trimmedCountryMatch[0] === '' && urls.geoApi) {
this.mode_ = mode.GEO_API;
} else if (!getMode(this.win).localDev) {
this.error_ = true;
}
....
extensions/amp-geo/0.1/amp-geo.js
Outdated
| method: 'GET', | ||
| credentials: 'omit', | ||
| }) | ||
| .then(res => res.json()) |
There was a problem hiding this comment.
@jridgewell Curious does xhr request timeout by default? Should we add a timeout here?
There was a problem hiding this comment.
Timeout introduced in latest commit.
There was a problem hiding this comment.
hmmm 60 seconds timeout. @jridgewell what's the typical timeout value applied by AMP runtime?
- Code style preferences - Require HTTPS and non-ampproject-cdn API URL - Timeout API request after 60 seconds - Add timeout test - Cleanup test output of new tests
extensions/amp-geo/0.1/amp-geo.js
Outdated
| return null; | ||
| } | ||
|
|
||
| if (isProxyOrigin(url)) { |
There was a problem hiding this comment.
ProxyOrigin doesn't work the same reason any random url doesn't work. I don't think we need a special check for this. Let me know if you think differently.
There was a problem hiding this comment.
Admittedly, there's not much reason for this check. It can be removed. I will wait for a final decision on isSecureUrlDeprecated/assertHttpsUrl before pushing a new change.
There was a problem hiding this comment.
I don't think it's needed.
| @@ -199,14 +202,97 @@ export class AmpGeo extends AMP.BaseElement { | |||
| this.mode_ = mode.GEO_HOT_PATCH; | |||
| this.country_ = trimmedCountryMatch[1]; | |||
| } else if (trimmedCountryMatch[0] === '' && !getMode(this.win).localDev) { | |||
extensions/amp-geo/0.1/amp-geo.js
Outdated
| return null; | ||
| } | ||
|
|
||
| if (!isSecureUrlDeprecated(url)) { |
There was a problem hiding this comment.
Hmmm the function name tells me that it's deprecated : )
#isSecureUrlDeprecated() doesn't handle the relative url case //, but #assertHttpsUrl() does.
The elementContext and sourceName makes the #assertHttpsUrl() looks like it's tied to AMP elements. But they are used only as error message. A better name is probably context instead of elementContext. What about
assertHttpsUrl(url, 'geoApiUrl', 'AMP_CONFIG urls')
There was a problem hiding this comment.
I'm not convinced assertHttpsUrl() is the right choice. It's a wrapper for isSecureUrlDeprecated(url) || /^(\/\/)/.test(url). Given the privacy implications of user location, do you really want to allow relative protocol? It seems more reasonable to directly make use of isSecureUrlDeprecated which requires HTTPS even if an AMP page is served from HTTP.
There was a problem hiding this comment.
The reason it's deprecated is because it doesn't work properly in the different ampdoc modes. Use Services.urlFor's isSecure() instead.
- Prefer Services.Url.isSecure to test if a string URL is HTTPS - Remove unnecessary check for isProxyOrigin - Remove unreachable code
|
Thank you both for the reviews. Modifications made. |
zhouyx
left a comment
There was a problem hiding this comment.
LGTM with one minor request. Thanks!
extensions/amp-geo/0.1/amp-geo.js
Outdated
| * @param {*} url | ||
| * @return {?string} | ||
| */ | ||
| validateApiUrl(url) { |
There was a problem hiding this comment.
nit: let's make it a private method please. Thanks
|
Are we ok with waiting to document this feature until #25873 is ready? Availability of self-hosting is when this feature becomes useful. |
|
That's sounds like the optimal approach. SGTM Thanks |
* master: Launch `amp-next-page` v2 & clean up experiment (ampproject#27035) ✨Implement Display Locking on amp-accordion (ampproject#25867) 📖<amp-next-page> documentation and validation (ampproject#26841) Improve visibility event tests (ampproject#26847) amp-geo: Fall back to API for country (ampproject#26407) ✨ Add customization options to <amp-story-quiz> (ampproject#26714) navigation: Minor test improvements (ampproject#26926) ♻️ Alias video.fullscreen action for symmetry with interface names (ampproject#27017) ✨ Implements `amp-analytics` support for `amp-next-page` (ampproject#26451) ✨ amp-video-iframe integration: global jwplayer() singleton by default (ampproject#26969) Fix unit tests broken by ampproject#26687 (ampproject#27000) Filter redirect info from emails (ampproject#27012) 📖 Make amp-bind doc valid, fix amp-form stories filter (ampproject#27003) url-replacements: Minor test improvement (ampproject#26930) viewport: Minor test improvement (ampproject#26931) amp-consent fullscreen warning (ampproject#26467) dep-check: USE CAPS FOR IMPORTANCE (ampproject#26993) fix img url (ampproject#26987) # Conflicts: # extensions/amp-next-page/amp-next-page.md
If country code is not available in a prerendered body's classes or in
amp-geo-0.1.js itself, support falling back to an API request. The
publisher must provide the API endpoint; cdn.ampproject.org will
not host a general country code API.
Allow case insensitive country code in JSON schema (country is most
often presented in uppercase when ISO 3166-1 table is referenced).
JSON schema of Geo API response - version 0.1:
Sample response: