-
Notifications
You must be signed in to change notification settings - Fork 3.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jridgewell Did we require https
in urls
? If not we should use assertHttpsUrl
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: please use json['country']
to avoid the name minimize.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
extensions/amp-geo/0.1/amp-geo.js
Outdated
); | ||
return null; | ||
} | ||
return json.country.toLowerCase(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: same here, json['country']
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
@@ -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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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;
}
....
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
extensions/amp-geo/0.1/amp-geo.js
Outdated
method: 'GET', | ||
credentials: 'omit', | ||
}) | ||
.then(res => res.json()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jridgewell Curious does xhr request timeout by default? Should we add a timeout here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Timeout introduced in latest commit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
extensions/amp-geo/0.1/amp-geo.js
Outdated
return null; | ||
} | ||
|
||
if (!isSecureUrlDeprecated(url)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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: