Skip to content

Commit

Permalink
Merge pull request #3221 from mhkawano/rewarded_logging
Browse files Browse the repository at this point in the history
Add Rewarded Ad logging
  • Loading branch information
mhkawano authored Sep 29, 2023
2 parents 9e23ed8 + 016afe1 commit 36250b6
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 3 deletions.
44 changes: 41 additions & 3 deletions src/runtime/audience-action-local-flow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* limitations under the License.
*/

import {AnalyticsEvent} from '../proto/api_messages';
import {AudienceActionFlow, TYPE_REWARDED_AD} from './audience-action-flow';
import {AutoPromptType} from '../api/basic-subscriptions';
import {
Expand All @@ -26,6 +27,7 @@ import {
SUBSCRIPTION_ICON,
} from './audience-action-local-ui';
import {ClientConfigManager} from './client-config-manager';
import {ClientEventManager} from './client-event-manager';
import {Constants} from '../utils/constants';
import {Deps} from './deps';
import {Message} from '../proto/api_messages';
Expand Down Expand Up @@ -74,6 +76,7 @@ export class AudienceActionLocalFlow implements AudienceActionFlow {
private readonly clientConfigManager_: ClientConfigManager;
private readonly doc_: Document;
private readonly fetcher_: XhrFetcher;
private readonly eventManager_: ClientEventManager;
// Used by rewarded ads to check if the ready callback has been called.
private rewardedReadyCalled_ = false;
// Ad slot used to host the rewarded ad.
Expand All @@ -91,13 +94,15 @@ export class AudienceActionLocalFlow implements AudienceActionFlow {
) {
this.clientConfigManager_ = deps_.clientConfigManager();

this.doc_ = this.deps_.doc().getRootNode();
this.doc_ = deps_.doc().getRootNode();

this.prompt_ = createElement(this.doc_, 'div', {});

this.wrapper_ = this.createWrapper_();

this.fetcher_ = new XhrFetcher(this.deps_.win());
this.fetcher_ = new XhrFetcher(deps_.win());

this.eventManager_ = deps_.eventManager();
}

private createWrapper_(): HTMLElement {
Expand Down Expand Up @@ -153,6 +158,8 @@ export class AudienceActionLocalFlow implements AudienceActionFlow {
}

private async initRewardedAdWall_() {
this.eventManager_.logSwgEvent(AnalyticsEvent.IMPRESSION_REWARDED_AD);

const config = await this.getConfig_();

const validRewardedAdParams =
Expand All @@ -175,6 +182,9 @@ export class AudienceActionLocalFlow implements AudienceActionFlow {
}, this.gptTimeoutMs_);
});
} else {
this.eventManager_.logSwgEvent(
AnalyticsEvent.EVENT_REWARDED_AD_CONFIG_ERROR
);
this.renderErrorView_();
}
}
Expand Down Expand Up @@ -211,6 +221,9 @@ export class AudienceActionLocalFlow implements AudienceActionFlow {
googletag.enableServices();
googletag.display(this.rewardedSlot_);
} else {
this.eventManager_.logSwgEvent(
AnalyticsEvent.EVENT_REWARDED_AD_PAGE_ERROR
);
this.renderErrorView_();
}
}
Expand All @@ -220,6 +233,9 @@ export class AudienceActionLocalFlow implements AudienceActionFlow {
const googletag = this.deps_.win().googletag;
this.renderErrorView_();
googletag.destroySlots([this.rewardedSlot_!]);
this.eventManager_.logSwgEvent(
AnalyticsEvent.EVENT_REWARDED_AD_GPT_ERROR
);
resolve(true);
// TODO: mhkawano - Launch payflow if monetized, cancel if not.
}
Expand Down Expand Up @@ -293,6 +309,8 @@ export class AudienceActionLocalFlow implements AudienceActionFlow {
this.prompt_
.querySelector('.rewarded-ad-sign-in-button')
?.addEventListener('click', this.signinRewardedAdWall_.bind(this));

this.eventManager_.logSwgEvent(AnalyticsEvent.EVENT_REWARDED_AD_READY);
}

private rewardedSlotClosed_() {
Expand All @@ -304,6 +322,10 @@ export class AudienceActionLocalFlow implements AudienceActionFlow {
this.params_.onCancel();
}
}
this.eventManager_.logSwgEvent(
AnalyticsEvent.ACTION_REWARDED_AD_CLOSE_AD,
/* isFromUserAction */ true
);
}

private rewardedSlotGranted_() {
Expand All @@ -329,6 +351,7 @@ export class AudienceActionLocalFlow implements AudienceActionFlow {
});
const googletag = this.deps_.win().googletag;
googletag.destroySlots([this.rewardedSlot_!]);
this.eventManager_.logSwgEvent(AnalyticsEvent.EVENT_REWARDED_AD_GRANTED);
this.complete_();
}

Expand All @@ -339,12 +362,20 @@ export class AudienceActionLocalFlow implements AudienceActionFlow {
if (this.params_.onCancel) {
this.params_.onCancel();
}
this.eventManager_.logSwgEvent(
AnalyticsEvent.ACTION_REWARDED_AD_CLOSE,
/* isFromUserAction */ true
);
}

private supportRewardedAdWall_() {
removeElement(this.wrapper_);
const googletag = this.deps_.win().googletag;
googletag.destroySlots([this.rewardedSlot_!]);
this.eventManager_.logSwgEvent(
AnalyticsEvent.ACTION_REWARDED_AD_SUPPORT,
/* isFromUserAction */ true
);
this.params_.monetizationFunction!();
}

Expand All @@ -353,7 +384,10 @@ export class AudienceActionLocalFlow implements AudienceActionFlow {
'rewarded-ad-view-ad-button'
);
viewButton.item(0)?.setAttribute('disabled', 'true');

this.eventManager_.logSwgEvent(
AnalyticsEvent.ACTION_REWARDED_AD_VIEW,
/* isFromUserAction */ true
);
this.makeRewardedVisible_!();
}

Expand All @@ -365,6 +399,10 @@ export class AudienceActionLocalFlow implements AudienceActionFlow {
this.closeRewardedAdWall_.bind(this)
);
this.deps_.callbacks().triggerLoginRequest({linkRequested: false});
this.eventManager_.logSwgEvent(
AnalyticsEvent.ACTION_REWARDED_AD_SIGN_IN,
/* isFromUserAction */ true
);
}

private buildEndpointUrl_(endpoint: string, queryParams: string[][]): string {
Expand Down
51 changes: 51 additions & 0 deletions src/runtime/audience-action-local-flows-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* limitations under the License.
*/

import {AnalyticsEvent} from '../proto/api_messages';
import {AudienceActionLocalFlow} from './audience-action-local-flow';
import {AutoPromptType} from '../api/basic-subscriptions';
import {ConfiguredRuntime} from './runtime';
Expand All @@ -39,6 +40,7 @@ const DEFAULT_CONFIG = `

describes.realWin('AudienceActionLocalFlow', (env) => {
let runtime;
let eventManager;

beforeEach(() => {
runtime = new ConfiguredRuntime(
Expand All @@ -52,6 +54,10 @@ describes.realWin('AudienceActionLocalFlow', (env) => {
/* clientOptions= */ {}
);
env.win.localStorage.getItem = () => 'abc';
eventManager = {
logSwgEvent: sandbox.spy(),
};
runtime.eventManager = () => eventManager;
});

describe('start', () => {
Expand Down Expand Up @@ -164,6 +170,15 @@ describes.realWin('AudienceActionLocalFlow', (env) => {
expect(
env.win.googletag.destroySlots
).to.be.calledOnce.calledWithExactly([rewardedSlot]);
expect(eventManager.logSwgEvent).to.be.calledWith(
AnalyticsEvent.IMPRESSION_REWARDED_AD
);
expect(eventManager.logSwgEvent).to.be.calledWith(
AnalyticsEvent.EVENT_REWARDED_AD_READY
);
expect(eventManager.logSwgEvent).to.be.calledWith(
AnalyticsEvent.ACTION_REWARDED_AD_SUPPORT
);
});

it('renders contribution', async () => {
Expand Down Expand Up @@ -196,6 +211,15 @@ describes.realWin('AudienceActionLocalFlow', (env) => {
expect(
env.win.googletag.destroySlots
).to.be.calledOnce.calledWithExactly([rewardedSlot]);
expect(eventManager.logSwgEvent).to.be.calledWith(
AnalyticsEvent.IMPRESSION_REWARDED_AD
);
expect(eventManager.logSwgEvent).to.be.calledWith(
AnalyticsEvent.EVENT_REWARDED_AD_READY
);
expect(eventManager.logSwgEvent).to.be.calledWith(
AnalyticsEvent.ACTION_REWARDED_AD_SUPPORT
);
});

it('renders isClosable == true', async () => {
Expand Down Expand Up @@ -227,6 +251,9 @@ describes.realWin('AudienceActionLocalFlow', (env) => {
env.win.googletag.destroySlots
).to.be.calledOnce.calledWithExactly([rewardedSlot]);
expect(params.onCancel).to.be.calledOnce.calledWithExactly();
expect(eventManager.logSwgEvent).to.be.calledWith(
AnalyticsEvent.ACTION_REWARDED_AD_CLOSE
);
});

it('renders isClosable == false', async () => {
Expand Down Expand Up @@ -270,6 +297,9 @@ describes.realWin('AudienceActionLocalFlow', (env) => {
expect(loginSpy).to.be.calledOnce.calledWithExactly({
linkRequested: false,
});
expect(eventManager.logSwgEvent).to.be.calledWith(
AnalyticsEvent.ACTION_REWARDED_AD_SIGN_IN
);
});

it('fails to render with bad config', async () => {
Expand Down Expand Up @@ -298,6 +328,9 @@ describes.realWin('AudienceActionLocalFlow', (env) => {

const errorPrompt = wrapper.shadowRoot.querySelector('.prompt');
expect(errorPrompt.innerHTML).contains('Something went wrong.');
expect(eventManager.logSwgEvent).to.be.calledWith(
AnalyticsEvent.EVENT_REWARDED_AD_CONFIG_ERROR
);
});

it('fails to render with bad ad slot', async () => {
Expand All @@ -310,6 +343,9 @@ describes.realWin('AudienceActionLocalFlow', (env) => {

const errorPrompt = state.wrapper.shadowRoot.querySelector('.prompt');
expect(errorPrompt.innerHTML).contains('Something went wrong.');
expect(eventManager.logSwgEvent).to.be.calledWith(
AnalyticsEvent.EVENT_REWARDED_AD_PAGE_ERROR
);
});

it('fails to render with gpt.js timeout', async () => {
Expand All @@ -322,6 +358,9 @@ describes.realWin('AudienceActionLocalFlow', (env) => {

const errorPrompt = state.wrapper.shadowRoot.querySelector('.prompt');
expect(errorPrompt.innerHTML).contains('Something went wrong.');
expect(eventManager.logSwgEvent).to.be.calledWith(
AnalyticsEvent.EVENT_REWARDED_AD_GPT_ERROR
);
});

it('renders thanks with rewardedSlotGranted', async () => {
Expand Down Expand Up @@ -349,6 +388,9 @@ describes.realWin('AudienceActionLocalFlow', (env) => {
expect(env.win.fetch).to.be.calledWith(
'https://news.google.com/swg/_/api/v1/publication/pub1/completeaudienceaction?sut=abc&configurationId=xyz&audienceActionType=TYPE_REWARDED_AD'
);
expect(eventManager.logSwgEvent).to.be.calledWith(
AnalyticsEvent.EVENT_REWARDED_AD_GRANTED
);
});

it('closes on thanks', async () => {
Expand Down Expand Up @@ -397,6 +439,9 @@ describes.realWin('AudienceActionLocalFlow', (env) => {
env.win.googletag.destroySlots
).to.be.calledOnce.calledWithExactly([rewardedSlot]);
expect(params.onCancel).to.be.calledOnce.calledWithExactly();
expect(eventManager.logSwgEvent).to.be.calledWith(
AnalyticsEvent.ACTION_REWARDED_AD_CLOSE_AD
);
});

it('renders with rewardedSlotClosed for locked content', async () => {
Expand All @@ -419,6 +464,9 @@ describes.realWin('AudienceActionLocalFlow', (env) => {
expect(
env.win.googletag.destroySlots
).to.be.calledOnce.calledWithExactly([rewardedSlot]);
expect(eventManager.logSwgEvent).to.be.calledWith(
AnalyticsEvent.ACTION_REWARDED_AD_CLOSE_AD
);
});

it('shows an ad', async () => {
Expand All @@ -444,6 +492,9 @@ describes.realWin('AudienceActionLocalFlow', (env) => {
expect(
readyEventArg.makeRewardedVisible
).to.be.calledOnce.calledWithExactly();
expect(eventManager.logSwgEvent).to.be.calledWith(
AnalyticsEvent.ACTION_REWARDED_AD_VIEW
);
});
});
});
Expand Down
6 changes: 6 additions & 0 deletions src/runtime/auto-prompt-manager-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4071,6 +4071,12 @@ describes.realWin('AutoPromptManager', (env) => {
expect(autoPromptManager.interventionDisplayed_.type).to.equal(
'TYPE_SUBSCRIPTION'
);
await eventManagerCallback({
eventType: AnalyticsEvent.EVENT_REWARDED_AD_GPT_MISSING_ERROR,
eventOriginator: EventOriginator.SWG_CLIENT,
isFromUserAction: null,
additionalParameters: null,
});
});
});

Expand Down
5 changes: 5 additions & 0 deletions src/runtime/auto-prompt-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1094,6 +1094,11 @@ export class AutoPromptManager {
} else if (actionType === TYPE_REWARDED_ADS) {
// Because we have fetched the article endpoint googletag.cmd should already exist.
const googletagExists = !!this.deps_.win().googletag?.cmd;
if (!googletagExists) {
this.eventManager_.logSwgEvent(
AnalyticsEvent.EVENT_REWARDED_AD_GPT_MISSING_ERROR
);
}
return googletagExists;
}
return true;
Expand Down

0 comments on commit 36250b6

Please sign in to comment.