WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions modules/scope3/rtd/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,56 @@ func (m *Module) HandleAuctionResponseHook(
payload.BidResponse.Ext = extResp
}

// also add to seatbid[].bid[]
for idx, seatBid := range payload.BidResponse.SeatBid {
for idy, bid := range seatBid.Bid {
if bid.Ext == nil {
bid.Ext = json.RawMessage("{}")
}

var bidExtMap map[string]interface{}
if err = jsonutil.Unmarshal(bid.Ext, &bidExtMap); err != nil {
bidExtMap = make(map[string]interface{})
}

// Add segments as individual targeting keys for GAM integration
if m.cfg.AddToTargeting {
prebidMap, ok := bidExtMap["prebid"].(map[string]interface{})
if !ok {
prebidMap = make(map[string]interface{})
bidExtMap["prebid"] = prebidMap
}
targetingMap, ok := prebidMap["targeting"].(map[string]interface{})
if !ok {
targetingMap = make(map[string]interface{})
prebidMap["targeting"] = targetingMap
}
// Add each segment as individual targeting key
for _, segment := range segments {
if strings.HasPrefix(segment, scope3MacroKeyPlusSeparator) {
macroKeyVal := strings.Split(segment, scope3MacroSeparator)
if len(macroKeyVal) != 2 {
continue
}
targetingMap[macroKeyVal[0]] = macroKeyVal[1]
} else {
targetingMap[segment] = "true"
}
}
}

// Always add to a dedicated scope3 section for publisher flexibility
bidExtMap["scope3"] = map[string]interface{}{
"segments": segments,
}

bidExtResp, err := jsonutil.Marshal(bidExtMap)
if err == nil {
payload.BidResponse.SeatBid[idx].Bid[idy].Ext = bidExtResp
}
}
}

return payload, nil
},
hookstage.MutationUpdate,
Expand Down
40 changes: 40 additions & 0 deletions modules/scope3/rtd/module_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,19 @@ func TestScope3APIIntegrationWithTargeting(t *testing.T) {
BidResponse: &openrtb2.BidResponse{
ID: "test-response",
Ext: json.RawMessage(`{}`),
SeatBid: []openrtb2.SeatBid{
{
Seat: "test-seat",
Bid: []openrtb2.Bid{
{
ID: "test-bid-1",
ImpID: "test-imp-1",
Price: 1.0,
Ext: json.RawMessage(`{}`),
},
},
},
},
},
}

Expand Down Expand Up @@ -319,6 +332,33 @@ func TestScope3APIIntegrationWithTargeting(t *testing.T) {
assert.Equal(t, "true", targetingData["test_segment_1"])
assert.Equal(t, "true", targetingData["test_segment_2"])
assert.Equal(t, "test-macro", targetingData["scope3_macro"])

// check seatbid
assert.Len(t, modifiedPayload.BidResponse.SeatBid, 1)
assert.Len(t, modifiedPayload.BidResponse.SeatBid[0].Bid, 1)

// Parse the modified response
var extBidMap map[string]interface{}
err = json.Unmarshal(modifiedPayload.BidResponse.SeatBid[0].Bid[0].Ext, &extBidMap)
require.NoError(t, err)

// Verify scope3 section exists
scope3DataSeatBid, exists := extBidMap["scope3"].(map[string]interface{})
require.True(t, exists)
segmentsSeatBid, exists := scope3DataSeatBid["segments"].([]interface{})
require.True(t, exists)
assert.Len(t, segmentsSeatBid, 3)

// Verify targeting section exists (add_to_targeting: true)
prebidDataSeatBid, exists := extBidMap["prebid"].(map[string]interface{})
require.True(t, exists)
targetingDataSeatBid, exists := prebidDataSeatBid["targeting"].(map[string]interface{})
require.True(t, exists)

// Check individual targeting keys
assert.Equal(t, "true", targetingDataSeatBid["test_segment_1"])
assert.Equal(t, "true", targetingDataSeatBid["test_segment_2"])
assert.Equal(t, "test-macro", targetingDataSeatBid["scope3_macro"])
}

func TestScope3APIIntegrationWithExistingPrebidTargeting(t *testing.T) {
Expand Down
Loading