14
14
#include " bat/ads/ads_history.h"
15
15
#include " bat/ads/confirmation_type.h"
16
16
#include " bat/ads/ad_notification_info.h"
17
-
17
+ # include " bat/ads/purchase_intent_signal_history.h "
18
18
#include " bat/ads/internal/ads_impl.h"
19
19
#include " bat/ads/internal/classification_helper.h"
20
20
#include " bat/ads/internal/locale_helper.h"
41
41
#include " bat/ads/internal/frequency_capping/permission_rules/ads_per_day_frequency_cap.h"
42
42
#include " bat/ads/internal/frequency_capping/permission_rules/ads_per_hour_frequency_cap.h"
43
43
#include " bat/ads/internal/sorts/ads_history_sort_factory.h"
44
+ #include " bat/ads/internal/purchase_intent/purchase_intent_signal_info.h"
45
+ #include " bat/ads/internal/purchase_intent/purchase_intent_classifier.h"
44
46
45
47
#include " base/guid.h"
46
48
#include " base/rand_util.h"
@@ -89,6 +91,9 @@ AdsImpl::AdsImpl(AdsClient* ads_client)
89
91
ad_conversions_(std::make_unique<AdConversions>(
90
92
this , ads_client, client_.get())),
91
93
user_model_(nullptr ),
94
+ purchase_intent_classifier_(std::make_unique<PurchaseIntentClassifier>(
95
+ kPurchaseIntentSignalLevel , kPurchaseIntentClassificationThreshold ,
96
+ kPurchaseIntentSignalDecayTimeWindow )),
92
97
is_initialized_(false ),
93
98
is_confirmations_ready_(false ),
94
99
sustained_ad_notification_interaction_timer_id_(0 ),
@@ -658,6 +663,8 @@ void AdsImpl::OnPageLoaded(
658
663
659
664
CheckAdConversion (url);
660
665
666
+ ExtractPurchaseIntentSignal (url);
667
+
661
668
if (helper::Uri::MatchesDomainOrHost (url,
662
669
last_shown_ad_notification_.target_url )) {
663
670
BLOG (INFO) << " Site visited " << url
@@ -704,6 +711,39 @@ void AdsImpl::OnPageLoaded(
704
711
<< previous_tab_url_;
705
712
}
706
713
714
+ void AdsImpl::ExtractPurchaseIntentSignal (
715
+ const std::string& url) {
716
+ if (!ShouldClassifyPagesIfTargeted ()) {
717
+ return ;
718
+ }
719
+
720
+ if (!TestSearchState (url) &&
721
+ helper::Uri::MatchesDomainOrHost (url, previous_tab_url_)) {
722
+ return ;
723
+ }
724
+
725
+ PurchaseIntentSignalInfo purchase_intent_signal =
726
+ purchase_intent_classifier_->ExtractIntentSignal (url);
727
+
728
+ if (purchase_intent_signal.segments .empty () &&
729
+ purchase_intent_signal.timestamp_in_seconds == 0 ) {
730
+ return ;
731
+ }
732
+
733
+ GeneratePurchaseIntentSignalHistoryEntry (purchase_intent_signal);
734
+ BLOG (INFO) << " Purchase intent signal extracted for " << url;
735
+ }
736
+
737
+ void AdsImpl::GeneratePurchaseIntentSignalHistoryEntry (
738
+ const PurchaseIntentSignalInfo& purchase_intent_signal) {
739
+ for (const auto & segment : purchase_intent_signal.segments ) {
740
+ PurchaseIntentSignalHistory history;
741
+ history.timestamp_in_seconds = purchase_intent_signal.timestamp_in_seconds ;
742
+ history.weight = purchase_intent_signal.weight ;
743
+ client_->AppendToPurchaseIntentSignalHistoryForSegment (segment, history);
744
+ }
745
+ }
746
+
707
747
void AdsImpl::CheckAdConversion (
708
748
const std::string& url) {
709
749
DCHECK (!url.empty ());
@@ -838,8 +878,8 @@ std::string AdsImpl::ClassifyPage(
838
878
return winning_category;
839
879
}
840
880
841
- std::vector<std::string> AdsImpl::GetWinningCategories () {
842
- std::vector<std::string> winning_categories;
881
+ WinningCategoryList AdsImpl::GetWinningCategories () {
882
+ WinningCategoryList winning_categories;
843
883
844
884
if (!ShouldClassifyPagesIfTargeted ()) {
845
885
return winning_categories;
@@ -929,6 +969,22 @@ AdsImpl::GetPageScoreCache() const {
929
969
return page_score_cache_;
930
970
}
931
971
972
+ PurchaseIntentWinningCategoryList
973
+ AdsImpl::GetWinningPurchaseIntentCategories () {
974
+ PurchaseIntentWinningCategoryList winning_categories;
975
+
976
+ PurchaseIntentSignalSegmentHistoryMap purchase_intent_signal_history =
977
+ client_->GetPurchaseIntentSignalHistory ();
978
+ if (purchase_intent_signal_history.empty ()) {
979
+ return winning_categories;
980
+ }
981
+
982
+ winning_categories = purchase_intent_classifier_->GetWinningCategories (
983
+ purchase_intent_signal_history, kPurchaseIntentMaxSegments );
984
+
985
+ return winning_categories;
986
+ }
987
+
932
988
void AdsImpl::TestShoppingData (
933
989
const std::string& url) {
934
990
if (!IsInitialized ()) {
@@ -1088,12 +1144,24 @@ void AdsImpl::ServeAdNotificationIfReady(
1088
1144
}
1089
1145
}
1090
1146
1091
- auto categories = GetWinningCategories ();
1147
+ CategoryList categories = GetCategoriesToServeAd ();
1092
1148
ServeAdNotificationFromCategories (categories);
1093
1149
}
1094
1150
1151
+ CategoryList AdsImpl::GetCategoriesToServeAd () {
1152
+ CategoryList categories;
1153
+ WinningCategoryList contextual_categories = GetWinningCategories ();
1154
+ categories.insert (categories.end (),
1155
+ contextual_categories.begin (), contextual_categories.end ());
1156
+ PurchaseIntentWinningCategoryList purchase_intent_categories =
1157
+ GetWinningPurchaseIntentCategories ();
1158
+ categories.insert (categories.end (),
1159
+ purchase_intent_categories.begin (), purchase_intent_categories.end ());
1160
+ return categories;
1161
+ }
1162
+
1095
1163
void AdsImpl::ServeAdNotificationFromCategories (
1096
- const std::vector<std::string> & categories) {
1164
+ const CategoryList & categories) {
1097
1165
std::string catalog_id = bundle_->GetCatalogId ();
1098
1166
if (catalog_id.empty ()) {
1099
1167
FailedToServeAdNotification (" No ad catalog" );
@@ -1118,7 +1186,7 @@ void AdsImpl::ServeAdNotificationFromCategories(
1118
1186
1119
1187
void AdsImpl::OnServeAdNotificationFromCategories (
1120
1188
const Result result,
1121
- const std::vector<std::string> & categories,
1189
+ const CategoryList & categories,
1122
1190
const CreativeAdNotificationList& ads) {
1123
1191
auto eligible_ads = GetEligibleAds (ads);
1124
1192
if (!eligible_ads.empty ()) {
@@ -1132,6 +1200,8 @@ void AdsImpl::OnServeAdNotificationFromCategories(
1132
1200
BLOG (INFO) << " " << category;
1133
1201
}
1134
1202
1203
+ // TODO(https://github.com/brave/brave-browser/issues/8486): Brave Ads
1204
+ // Purchase Intent segments should not fall back to parent segments
1135
1205
if (ServeAdNotificationFromParentCategories (categories)) {
1136
1206
return ;
1137
1207
}
@@ -1140,8 +1210,8 @@ void AdsImpl::OnServeAdNotificationFromCategories(
1140
1210
}
1141
1211
1142
1212
bool AdsImpl::ServeAdNotificationFromParentCategories (
1143
- const std::vector<std::string> & categories) {
1144
- std::vector<std::string> parent_categories;
1213
+ const CategoryList & categories) {
1214
+ CategoryList parent_categories;
1145
1215
for (const auto & category : categories) {
1146
1216
auto pos = category.find_last_of (kCategoryDelimiter );
1147
1217
if (pos == std::string::npos) {
0 commit comments