Skip to content

Commit

Permalink
Merge pull request #8640 from /issues/15491
Browse files Browse the repository at this point in the history
Add custom conversion ID patterns for Verifiable Advertiser Conversions
  • Loading branch information
moritzhaller authored Apr 29, 2021
2 parents 672849f + 978142a commit 791a6c5
Show file tree
Hide file tree
Showing 16 changed files with 641 additions and 37 deletions.
2 changes: 2 additions & 0 deletions components/brave_ads/test/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ source_set("brave_ads_unit_tests") {
"//brave/vendor/bat-native-ads/src/bat/ads/internal/features/ad_serving/ad_serving_features_unittest.cc",
"//brave/vendor/bat-native-ads/src/bat/ads/internal/features/anti_targeting/anti_targeting_features_unittest.cc",
"//brave/vendor/bat-native-ads/src/bat/ads/internal/features/bandits/epsilon_greedy_bandit_features_unittest.cc",
"//brave/vendor/bat-native-ads/src/bat/ads/internal/features/conversions/conversions_features_unittest.cc",
"//brave/vendor/bat-native-ads/src/bat/ads/internal/features/purchase_intent/purchase_intent_features_unittest.cc",
"//brave/vendor/bat-native-ads/src/bat/ads/internal/features/text_classification/text_classification_features_unittest.cc",
"//brave/vendor/bat-native-ads/src/bat/ads/internal/features/user_activity/user_activity_features_unittest.cc",
Expand Down Expand Up @@ -129,6 +130,7 @@ source_set("brave_ads_unit_tests") {
"//brave/vendor/bat-native-ads/src/bat/ads/internal/resources/behavioral/bandits/epsilon_greedy_bandit_resource_unittest.cc",
"//brave/vendor/bat-native-ads/src/bat/ads/internal/resources/behavioral/purchase_intent/purchase_intent_resource_unittest.cc",
"//brave/vendor/bat-native-ads/src/bat/ads/internal/resources/contextual/text_classification/text_classification_resource_unittest.cc",
"//brave/vendor/bat-native-ads/src/bat/ads/internal/resources/conversions/conversions_resource_unittest.cc",
"//brave/vendor/bat-native-ads/src/bat/ads/internal/resources/frequency_capping/anti_targeting_resource_unittest.cc",
"//brave/vendor/bat-native-ads/src/bat/ads/internal/security/conversions/conversions_util_unittest.cc",
"//brave/vendor/bat-native-ads/src/bat/ads/internal/security/crypto_util_unittest.cc",
Expand Down
6 changes: 6 additions & 0 deletions vendor/bat-native-ads/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,8 @@ source_set("ads") {
"src/bat/ads/internal/features/anti_targeting/anti_targeting_features.h",
"src/bat/ads/internal/features/bandits/epsilon_greedy_bandit_features.cc",
"src/bat/ads/internal/features/bandits/epsilon_greedy_bandit_features.h",
"src/bat/ads/internal/features/conversions/conversions_features.cc",
"src/bat/ads/internal/features/conversions/conversions_features.h",
"src/bat/ads/internal/features/features.cc",
"src/bat/ads/internal/features/features.h",
"src/bat/ads/internal/features/features_util.cc",
Expand Down Expand Up @@ -552,6 +554,10 @@ source_set("ads") {
"src/bat/ads/internal/resources/behavioral/purchase_intent/purchase_intent_resource.h",
"src/bat/ads/internal/resources/contextual/text_classification/text_classification_resource.cc",
"src/bat/ads/internal/resources/contextual/text_classification/text_classification_resource.h",
"src/bat/ads/internal/resources/conversions/conversion_id_pattern_info.cc",
"src/bat/ads/internal/resources/conversions/conversion_id_pattern_info.h",
"src/bat/ads/internal/resources/conversions/conversions_resource.cc",
"src/bat/ads/internal/resources/conversions/conversions_resource.h",
"src/bat/ads/internal/resources/country_components.h",
"src/bat/ads/internal/resources/frequency_capping/anti_targeting_info.cc",
"src/bat/ads/internal/resources/frequency_capping/anti_targeting_info.h",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"locale": "us",
"version": 1,
"timestamp": "2021-04-26 09:00:00",
"conversion_id_patterns": {
"https://brave.com/foobar": {
"id_pattern": "<div.*id=\"conversion-id\".*>(.*)<\/div>",
"search_in": "html"
},
"https://brave.com/foobar?conversion_id=*": {
"id_pattern": "conversion_id\\=(.*)",
"search_in": "url"
}
}
}
8 changes: 7 additions & 1 deletion vendor/bat-native-ads/src/bat/ads/internal/ads_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include "bat/ads/internal/resources/behavioral/bandits/epsilon_greedy_bandit_resource.h"
#include "bat/ads/internal/resources/behavioral/purchase_intent/purchase_intent_resource.h"
#include "bat/ads/internal/resources/contextual/text_classification/text_classification_resource.h"
#include "bat/ads/internal/resources/conversions/conversions_resource.h"
#include "bat/ads/internal/resources/country_components.h"
#include "bat/ads/internal/resources/frequency_capping/anti_targeting_resource.h"
#include "bat/ads/internal/resources/language_components.h"
Expand Down Expand Up @@ -126,6 +127,7 @@ void AdsImpl::ChangeLocale(const std::string& locale) {
text_classification_resource_->Load();
purchase_intent_resource_->Load();
anti_targeting_resource_->Load();
conversions_resource_->Load();
}

void AdsImpl::OnAdsSubdivisionTargetingCodeHasChanged() {
Expand All @@ -150,7 +152,8 @@ void AdsImpl::OnHtmlLoaded(const int32_t tab_id,

const std::string original_url = redirect_chain.front();
ad_transfer_->MaybeTransferAd(tab_id, original_url);
conversions_->MaybeConvert(redirect_chain, html);
conversions_->MaybeConvert(redirect_chain, html,
conversions_resource_->get());
}

void AdsImpl::OnTextLoaded(const int32_t tab_id,
Expand Down Expand Up @@ -274,6 +277,7 @@ void AdsImpl::OnResourceComponentUpdated(const std::string& id) {
} else if (kComponentCountryIds.find(id) != kComponentCountryIds.end()) {
purchase_intent_resource_->Load();
anti_targeting_resource_->Load();
conversions_resource_->Load();
} else {
BLOG(0, "Unknown resource for " << id);
}
Expand Down Expand Up @@ -424,6 +428,8 @@ void AdsImpl::set(privacy::TokenGeneratorInterface* token_generator) {

anti_targeting_resource_ = std::make_unique<resource::AntiTargeting>();

conversions_resource_ = std::make_unique<resource::Conversions>();

ad_targeting_ = std::make_unique<AdTargeting>();
subdivision_targeting_ =
std::make_unique<ad_targeting::geographic::SubdivisionTargeting>();
Expand Down
2 changes: 2 additions & 0 deletions vendor/bat-native-ads/src/bat/ads/internal/ads_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class SubdivisionTargeting;

namespace resource {
class AntiTargeting;
class Conversions;
class EpsilonGreedyBandit;
class PurchaseIntent;
class TextClassification;
Expand Down Expand Up @@ -202,6 +203,7 @@ class AdsImpl : public Ads,
std::unique_ptr<ad_targeting::processor::PurchaseIntent>
purchase_intent_processor_;
std::unique_ptr<resource::AntiTargeting> anti_targeting_resource_;
std::unique_ptr<resource::Conversions> conversions_resource_;
std::unique_ptr<ad_targeting::geographic::SubdivisionTargeting>
subdivision_targeting_;
std::unique_ptr<AdTargeting> ad_targeting_;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "bat/ads/internal/database/tables/ad_events_database_table.h"
#include "bat/ads/internal/database/tables/conversion_queue_database_table.h"
#include "bat/ads/internal/database/tables/conversions_database_table.h"
#include "bat/ads/internal/features/conversions/conversions_features.h"
#include "bat/ads/internal/logging.h"
#include "bat/ads/internal/time_formatting_util.h"
#include "bat/ads/internal/url_util.h"
Expand All @@ -34,8 +35,8 @@ namespace {
const int64_t kConvertAfterSeconds =
base::Time::kHoursPerDay * base::Time::kSecondsPerHour;
const int64_t kDebugConvertAfterSeconds = 10 * base::Time::kSecondsPerMinute;

const int64_t kExpiredConvertAfterSeconds = 1 * base::Time::kSecondsPerMinute;
const char kSearchInUrl[] = "url";

bool HasObservationWindowForAdEventExpired(const int observation_window,
const AdEventInfo& ad_event) {
Expand Down Expand Up @@ -83,14 +84,41 @@ bool DoesConfirmationTypeMatchConversionType(
}
}

std::string ExtractVerifiableConversionIdFromHtml(const std::string& html) {
re2::StringPiece text_string_piece(html);
RE2 r("<meta.*name=\"ad-conversion-id\".*content=\"(.*)\".*>");
std::string ExtractConversionIdFromText(
const std::string& html,
const std::vector<std::string>& redirect_chain,
const std::string& conversion_url_pattern,
const ConversionIdPatternMap& conversion_id_patterns) {
std::string conversion_id;
std::string conversion_id_pattern =
features::GetGetDefaultConversionIdPattern();
std::string text = html;

const auto iter = conversion_id_patterns.find(conversion_url_pattern);
if (iter != conversion_id_patterns.end()) {
const ConversionIdPatternInfo conversion_id_pattern_info = iter->second;
if (conversion_id_pattern_info.search_in == kSearchInUrl) {
const auto url_iter = std::find_if(
redirect_chain.begin(), redirect_chain.end(),
[=](const std::string& url) {
return DoesUrlMatchPattern(url, conversion_url_pattern);
});

if (url_iter == redirect_chain.end()) {
return conversion_id;
}

text = *url_iter;
}

conversion_id_pattern = conversion_id_pattern_info.id_pattern;
}

std::string verifiable_conversion_id;
RE2::FindAndConsume(&text_string_piece, r, &verifiable_conversion_id);
re2::StringPiece text_string_piece(text);
RE2 r(conversion_id_pattern);
RE2::FindAndConsume(&text_string_piece, r, &conversion_id);

return verifiable_conversion_id;
return conversion_id;
}

std::set<std::string> GetConvertedCreativeSets(const AdEventList& ad_events) {
Expand Down Expand Up @@ -155,8 +183,10 @@ void Conversions::RemoveObserver(ConversionsObserver* observer) {
observers_.RemoveObserver(observer);
}

void Conversions::MaybeConvert(const std::vector<std::string>& redirect_chain,
const std::string& html) {
void Conversions::MaybeConvert(
const std::vector<std::string>& redirect_chain,
const std::string& html,
const ConversionIdPatternMap& conversion_id_patterns) {
if (!ShouldAllow()) {
BLOG(1, "Conversions are not allowed");
return;
Expand All @@ -168,7 +198,7 @@ void Conversions::MaybeConvert(const std::vector<std::string>& redirect_chain,
return;
}

CheckRedirectChain(redirect_chain, html);
CheckRedirectChain(redirect_chain, html, conversion_id_patterns);
}

void Conversions::StartTimerIfReady() {
Expand Down Expand Up @@ -202,7 +232,8 @@ bool Conversions::ShouldAllow() const {

void Conversions::CheckRedirectChain(
const std::vector<std::string>& redirect_chain,
const std::string& html) {
const std::string& html,
const ConversionIdPatternMap& conversion_id_patterns) {
BLOG(1, "Checking URL for conversions");

database::table::AdEvents ad_events_database_table;
Expand Down Expand Up @@ -254,8 +285,9 @@ void Conversions::CheckRedirectChain(
creative_set_ids.insert(ad_event.creative_set_id);

VerifiableConversionInfo verifiable_conversion;
verifiable_conversion.id =
ExtractVerifiableConversionIdFromHtml(html);
verifiable_conversion.id = ExtractConversionIdFromText(
html, redirect_chain, conversion.url_pattern,
conversion_id_patterns);
verifiable_conversion.public_key = conversion.advertiser_public_key;

Convert(ad_event, verifiable_conversion);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "bat/ads/internal/conversions/conversion_queue_item_info.h"
#include "bat/ads/internal/conversions/conversions_observer.h"
#include "bat/ads/internal/conversions/verifiable_conversion_info.h"
#include "bat/ads/internal/resources/conversions/conversion_id_pattern_info.h"
#include "bat/ads/internal/security/conversions/verifiable_conversion_envelope_info.h"
#include "bat/ads/internal/timer.h"

Expand All @@ -34,7 +35,8 @@ class Conversions {
bool ShouldAllow() const;

void MaybeConvert(const std::vector<std::string>& redirect_chain,
const std::string& html);
const std::string& html,
const ConversionIdPatternMap& conversion_id_patterns);

void StartTimerIfReady();

Expand All @@ -44,7 +46,8 @@ class Conversions {
Timer timer_;

void CheckRedirectChain(const std::vector<std::string>& redirect_chain,
const std::string& html);
const std::string& html,
const ConversionIdPatternMap& conversion_id_patterns);

void Convert(const AdEventInfo& ad_event,
const VerifiableConversionInfo& verifiable_conversion);
Expand Down
Loading

0 comments on commit 791a6c5

Please sign in to comment.