Skip to content

✨Create new extension - AMP-smartlinks#20494

Merged
alabiaga merged 19 commits intoampproject:masterfrom
hellonarrativ:amp-smartlinks-0.1
Feb 15, 2019
Merged

✨Create new extension - AMP-smartlinks#20494
alabiaga merged 19 commits intoampproject:masterfrom
hellonarrativ:amp-smartlinks-0.1

Conversation

@PhilWinchester
Copy link
Copy Markdown
Contributor

@PhilWinchester PhilWinchester commented Jan 23, 2019

Resolves #19470

What it does

Create an extension that lets Narrativ offer our publishers our Linkmate service in AMP pages. The extension scans the page for any outbound links the publisher wants targeted and sends them to our API for monetization. Upon API response we use the link-rewriter service to map that response to the links in the initial payload. When a user clicks one of the monetized links we swap the href with the monetized link. More about Linkmate here.

@googlebot
Copy link
Copy Markdown

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please visit https://cla.developers.google.com/ to sign.

Once you've signed (or fixed any issues), please reply here (e.g. I signed it!) and we'll verify it.


What to do if you already signed the CLA

Individual signers
Corporate signers

@aghassemi aghassemi requested a review from zhouyx January 24, 2019 16:50
@PhilWinchester PhilWinchester force-pushed the amp-smartlinks-0.1 branch 2 times, most recently from c3d3d94 to 1504d07 Compare January 25, 2019 19:54
@PhilWinchester
Copy link
Copy Markdown
Contributor Author

I signed it!

@SHWinchester
Copy link
Copy Markdown

SHWinchester commented Jan 25, 2019 via email

@PhilWinchester
Copy link
Copy Markdown
Contributor Author

Thanks for the review @honeybadgerdontcare. I addressed your validator comment, please let me know if you spot anything else!

@zhouyx
Copy link
Copy Markdown
Contributor

zhouyx commented Jan 29, 2019

@PhilWinchester Thank you for the PR. I am working on reviewing it, but it's a pretty big one, please allow me some time to review the change.
And + @alabiaga who reviews the amp-skimlink change.

Copy link
Copy Markdown
Contributor

@zhouyx zhouyx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@PhilWinchester Left some comments. Is it possible to reuse the LinkRewrite class that already exists? I found most class can be shared with the amp-skimlink service, please let me know if there's any concern. Thank you.

* @private
*/
initLinkRewriter_() {
const options = {linkSelector: this.linkmateOptions_.linkSelector};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@erwinmombay could you help me understand if closure compiler is smart enough to understand that the linkSelector here equals to the linkSelector here

this.linkSelector_ = options.linkSelector || 'a';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@PhilWinchester So I asked @erwinmombay offline. We don't think that closure compilier is smart enough to understand that the options is the same to the LinkerRewriter options params without a typedef. This won't be an issue right now because all fieldName is reserved today, but it will be an issue when closure compiler start to obfuscated the fieldName.

We can either switch to using a JsonObject. But given only linkSelector is supported, can we instead pass a string to the constructor? If you think that makes sense I'm fine with a following PR to address the comment.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zhouyx
Do you mean doing something like this?

    const options = /** @type {JsonObject} */
      ({'linkSelector': this.linkmateOptions_.linkSelector});

I also assume that this part of the extension will need to be changed to if/when the affiliate link changes are added to the AMP project and the link-rewriter service is deprecated. I'm not sure if that would happen sooner than the closure compiler changes. Thanks for your help!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nvm the link-rewriter code isn't expecting a JsonObject. I think I will follow up later with these changes.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even with the affiliate link changes, we are going to heavily rely on the existing link-rewriter service. As said I'd imaging this class to be kept and reused.

Copy link
Copy Markdown
Contributor

@alabiaga alabiaga left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'll review again once @zhouyx comments about reusing the code from skimlinks extension is address. I know that the individual who wrote that extension initially had the idea and implementation of including that logic into runtime for reuse so maybe it might be worth discussing with him. My worries about importing code from that extension is that now you have this dependency on that extension which might break or change the way your extension behaves if they modify it.

@googlebot
Copy link
Copy Markdown

CLAs look good, thanks!

@zhouyx
Copy link
Copy Markdown
Contributor

zhouyx commented Jan 30, 2019

My worries about importing code from that extension is that now you have this dependency on that extension which might break or change the way your extension behaves if they modify it.

@alabiaga That's a really good point. Can we reach out to the previous contributor to move the code to src/

@PhilWinchester PhilWinchester force-pushed the amp-smartlinks-0.1 branch 2 times, most recently from ba13888 to e888ec5 Compare January 31, 2019 16:10
@PhilWinchester
Copy link
Copy Markdown
Contributor Author

Thanks for the feedback and tips everyone! Any update on what is going to happen with the link-rewriter code?

Copy link
Copy Markdown
Contributor

@honeybadgerdontcare honeybadgerdontcare left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

validation changes look good.

@alabiaga
Copy link
Copy Markdown
Contributor

alabiaga commented Feb 1, 2019

Thanks for the feedback and tips everyone! Any update on what is going to happen with the link-rewriter code?

I reached out to @slocka and awaiting his response. Thanks.

@PhilWinchester
Copy link
Copy Markdown
Contributor Author

The integration test failure in travis seems to be unrelated to my changes (couldn't replicate locally). What's the best way to rerun tests?

@alabiaga
Copy link
Copy Markdown
Contributor

alabiaga commented Feb 1, 2019

The integration test failure in travis seems to be unrelated to my changes (couldn't replicate locally). What's the best way to rerun tests?

I restarted it for you and will monitor it.

@PhilWinchester
Copy link
Copy Markdown
Contributor Author

I'm running into issues with the one of the comments above (#20494 (comment)), when actually triggering the event the key isn't registered in the this.observables_ object. If I understand the code correctly then I am falling into the SandboxEvent buffer and not actually triggering my event. Ignoring the useBody question I mentioned above I am wondering where I am going wrong in setting up this API call. The below snippet is called after viewer.WhenFirstVisible(). Can someone help me understand how I am going about setting CustomEventReporter incorrectly? Also, any advice on useBody and extraUrlParams is greatly appreciated since our API expects the payload to be in the body object.

/**
   * API call to indicate a page load event happened
   * @private
   */
  postPageImpression_() {
    // When using layout='nodisplay' manually trigger CustomEventReporterBuilder
    this.signals().signal(CommonSignals.LOAD_START);
    const builder = new CustomEventReporterBuilder(this.element);
    const payload = this.buildPageImpressionPayload_();

    builder.track('page-impression', ENDPOINTS.PAGE_IMPRESSION_ENDPOINT);
    builder.setTransportConfig(dict({
      'beacon': true,
      'xhrpost': false,
      'image': true,
      // 'useBody': true,
    }));
    // builder.setExtraUrlParams(payload);
    const reporter = builder.build();

    reporter.trigger('page-impression', dict({
      'data': JSON.stringify(payload),
    }));
  }

Separately, any update on the link-rewriter changes and if that is going to be a change I should be waiting for?

@alabiaga
Copy link
Copy Markdown
Contributor

alabiaga commented Feb 6, 2019

@llanka or @zhouyx are best suited to answer your question about that API

Separately, any update on the link-rewriter changes and if that is going to be a change I should be waiting for?

I wouldn't rely on that change to be submitted before submitting this. I would keep in contact with @slocka to see his progression on that rewrite. I would submit this with the dependency on the skimlinks link rewriter logic and follow up with @slocka to make sure that this dependency is removed eventually. With the proper tests in place, you can still be notified on whether a change on their end will require changes to your extensions but that is something you don't want to deal with.

@torch2424
Copy link
Copy Markdown
Contributor

Hello, so I was discussing with @lannka , and we noticed that we are getting a lot more interesting in affiliate linking within AMP. And in fact, we had this proposal in the past, but got de-prioritized: #9276

Could you look through that, and see if it would work for your use case? We were thinking it may be better to make a more general solution on our end, that platforms can integrate with 😄

Thank you!

cc/ @alabiaga

@zhouyx
Copy link
Copy Markdown
Contributor

zhouyx commented Feb 7, 2019

I'm running into issues with the one of the comments above (#20494 (comment)), when actually triggering the event the key isn't registered in the this.observables_ object. If I understand the code correctly then I am falling into the SandboxEvent buffer and not actually triggering my event.

Could you please point me to the this.observables_ object you're referring to.
The event name is sandboxed, so that you only get the custom event of your component, not from other AMP components. The event name will be changed to sandbox-${id}-${eventType}, but the outgoing request will remain the same.

@slocka
Copy link
Copy Markdown

slocka commented Feb 7, 2019

Hello, so I was discussing with @lannka , and we noticed that we are getting a lot more interesting in affiliate linking within AMP. And in fact, we had this proposal in the past, but got de-prioritized: #9276

Could you look through that, and see if it would work for your use case? We were thinking it may be better to make a more general solution on our end, that platforms can integrate with 😄

Thank you!

cc/ @alabiaga

@alabiaga I am happy to move the LinkRewriter related code common to amp-skimlinks and amp-smartlinks to the src folder like it initially was. I would like confirmation that the migration is still worth doing considering @torch2424 last message? Should I wait for more visibility on #9276 before making the migration?

Copy link
Copy Markdown
Contributor

@zhouyx zhouyx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@PhilWinchester Thank you! One last comment from me. Feel free to address in separate PR.

@alabiaga alabiaga merged commit 628e309 into ampproject:master Feb 15, 2019
@rsimha
Copy link
Copy Markdown
Contributor

rsimha commented Feb 15, 2019

@alabiaga Minified compilation was broken by this PR. See https://travis-ci.org/ampproject/amphtml/jobs/493915905#L610

Compiler issues for amp-smartlinks-0.1.js:
extensions/amp-smartlinks/0.1/amp-smartlinks.js:24: WARNING - Failed to load module "../../amp-skimlinks/0.1/link-rewriter/link-rewriter-manager"
import {LinkRewriterManager} from
^

extensions/amp-smartlinks/0.1/amp-smartlinks.js:43: WARNING - Failed to load module "../../amp-skimlinks/0.1/link-rewriter/link-rewriter-manager"
    /** @private {?../../amp-skimlinks/0.1/link-rewriter/link-rewriter-manager.LinkRewriterManager} */
                   ^

extensions/amp-smartlinks/0.1/amp-smartlinks.js:46: WARNING - Failed to load module "../../amp-skimlinks/0.1/link-rewriter/link-rewriter"
    /** @private {?../../amp-skimlinks/0.1/link-rewriter/link-rewriter.LinkRewriter} */
                   ^

extensions/amp-smartlinks/0.1/amp-smartlinks.js:169: WARNING - Failed to load module "../../amp-skimlinks/0.1/link-rewriter/link-rewriter"
   * @return {!../../amp-skimlinks/0.1/link-rewriter/link-rewriter.LinkRewriter}
               ^

extensions/amp-smartlinks/0.1/linkmate.js:21: WARNING - Failed to load module "../../amp-skimlinks/0.1/link-rewriter/two-steps-response"
import {TwoStepsResponse} from
^

extensions/amp-smartlinks/0.1/linkmate.js:62: WARNING - Failed to load module "../../amp-skimlinks/0.1/link-rewriter/two-steps-response"
   * @return {!../../amp-skimlinks/0.1/link-rewriter/two-steps-response.TwoStepsResponse}
               ^

extensions/amp-smartlinks/0.1/linkmate.js:176: WARNING - Failed to load module "../../amp-skimlinks/0.1/link-rewriter/link-rewriter"
   * @return {!../../amp-skimlinks/0.1/link-rewriter/link-rewriter.AnchorReplacementList}
               ^

0 error(s), 7 warning(s)

Sadly, it's too expensive to closure-compile all extensions during PR jobs, so we only detect these breaks on master builds. I'm surprised gulp check-types didn't catch this.

@PhilWinchester
Copy link
Copy Markdown
Contributor Author

PhilWinchester commented Feb 15, 2019

Sorry for breaking things :(
@alabiaga I can replicate locally. I'm not familiar enough with the closure compiler to know where to start on fixing this. Do you have an example to point me in the right direction?

@alabiaga
Copy link
Copy Markdown
Contributor

Not a problem Phil. I am looking into this and will update you and we can merge it again.

@zhouyx
Copy link
Copy Markdown
Contributor

zhouyx commented Feb 15, 2019

@rsimha @alabiaga Do you think it is due to amp-smartlinks trying to import modules from another extension. And there may be a race condition between when these two extensions gets built.

@PhilWinchester No worries, we should document better to always test the compiled version locally.

gulp dist --extensions=<your_extension_name>
gulp serve --compiled

alabiaga added a commit that referenced this pull request Feb 15, 2019
@PhilWinchester
Copy link
Copy Markdown
Contributor Author

Hi @alabiaga & @zhouyx,
Any update on a fix for this issue? Is there something I can do to help out? Would opening up a second PR be helpful in any way?

@alabiaga
Copy link
Copy Markdown
Contributor

@PhilWinchester I spoke with @zhouyx and she has a fix in mind that we are playing around with. Will have an update for you soon. Apologies for the delay.

@alabiaga
Copy link
Copy Markdown
Contributor

@PhilWinchester pls add the following line in https://github.com/ampproject/amphtml/blob/master/build-system/tasks/compile.js#L199

// Needed for smart-links dep on skim-links
'extensions/amp-skimlinks/0.1/**/*.js',

I verified that it prod version of binary will build fine with that change but pls verify yourself as well. Thanks

Thanks to @zhouyx and @erwinmombay for their help on this fix.

noranazmy pushed a commit to noranazmy/amphtml that referenced this pull request Mar 22, 2019
Resolves ampproject#19470

## What it does
Create an extension that lets Narrativ offer our publishers our Linkmate service in AMP pages. The extension scans the page for any outbound links the publisher wants targeted and sends them to our API for monetization. Upon API response we use the `link-rewriter` service to map that response to the links in the initial payload. When a user clicks one of the monetized links we swap the href with the monetized link. More about Linkmate [here](http://docs.narrativ.com/en/stable/linkmate.html#linkmate).
noranazmy pushed a commit to noranazmy/amphtml that referenced this pull request Mar 22, 2019
bramanudom pushed a commit to bramanudom/amphtml that referenced this pull request Mar 22, 2019
Resolves ampproject#19470

## What it does
Create an extension that lets Narrativ offer our publishers our Linkmate service in AMP pages. The extension scans the page for any outbound links the publisher wants targeted and sends them to our API for monetization. Upon API response we use the `link-rewriter` service to map that response to the links in the initial payload. When a user clicks one of the monetized links we swap the href with the monetized link. More about Linkmate [here](http://docs.narrativ.com/en/stable/linkmate.html#linkmate).
bramanudom pushed a commit to bramanudom/amphtml that referenced this pull request Mar 22, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.