diff --git a/analytics/pubmatic/logger.go b/analytics/pubmatic/logger.go index 569740069c0..979a9612aa6 100644 --- a/analytics/pubmatic/logger.go +++ b/analytics/pubmatic/logger.go @@ -414,25 +414,30 @@ func getPartnerRecordsByImp(ao analytics.AuctionObject, rCtx *models.RequestCtx) } pr := PartnerRecord{ - PartnerID: partnerID, // prebid biddercode - BidderCode: seat, // pubmatic biddercode: pubmatic2 - Latency1: rCtx.BidderResponseTimeMillis[seat], // it is set inside auctionresponsehook for all bidders - KGPV: kgpv, - KGPSV: kgpsv, - BidID: utils.GetOriginalBidId(bid.ID), - OrigBidID: utils.GetOriginalBidId(bid.ID), - DefaultBidStatus: 0, // this will be always 0 , decide whether to drop this field in future - ServerSide: 1, - MatchedImpression: rCtx.MatchedImpression[seat], - OriginalCPM: models.GetGrossEcpm(bidExt.OriginalBidCPM), - OriginalCur: bidExt.OriginalBidCur, - DealID: bid.DealID, - Nbr: nbr, - Adformat: adFormat, - NetECPM: tracker.Tracker.PartnerInfo.NetECPM, - GrossECPM: tracker.Tracker.PartnerInfo.GrossECPM, - PartnerSize: tracker.Tracker.PartnerInfo.AdSize, - ADomain: tracker.Tracker.PartnerInfo.Advertiser, + PartnerID: partnerID, // prebid biddercode + BidderCode: seat, // pubmatic biddercode: pubmatic2 + Latency1: rCtx.BidderResponseTimeMillis[seat], // it is set inside auctionresponsehook for all bidders + KGPV: kgpv, + KGPSV: kgpsv, + BidID: utils.GetOriginalBidId(bid.ID), + OrigBidID: utils.GetOriginalBidId(bid.ID), + DefaultBidStatus: 0, // this will be always 0 , decide whether to drop this field in future + ServerSide: 1, + MatchedImpression: rCtx.MatchedImpression[seat], + OriginalCPM: models.GetGrossEcpm(bidExt.OriginalBidCPM), + OriginalCur: bidExt.OriginalBidCur, + DealID: bid.DealID, + Nbr: nbr, + Adformat: adFormat, + NetECPM: tracker.Tracker.PartnerInfo.NetECPM, + GrossECPM: tracker.Tracker.PartnerInfo.GrossECPM, + PartnerSize: tracker.Tracker.PartnerInfo.AdSize, + ADomain: tracker.Tracker.PartnerInfo.Advertiser, + MultiBidMultiFloorFlag: tracker.Tracker.PartnerInfo.MultiBidMultiFloorFlag, + } + + if pr.MultiBidMultiFloorFlag == 0 && bidExt.MultiBidMultiFloorValue > 0 { + pr.MultiBidMultiFloorFlag = 1 } if pr.NetECPM == 0 { diff --git a/analytics/pubmatic/logger_test.go b/analytics/pubmatic/logger_test.go index 65d2e6d048e..72001e92346 100644 --- a/analytics/pubmatic/logger_test.go +++ b/analytics/pubmatic/logger_test.go @@ -695,15 +695,16 @@ func TestGetPartnerRecordsByImpForTracker(t *testing.T) { "bid-id-1": { Tracker: models.Tracker{ PartnerInfo: models.Partner{ - Adformat: models.Native, - KGPV: "kgpv", - NetECPM: 10, - GrossECPM: 12, - AdSize: "15x15", - FloorValue: 1, - FloorRuleValue: 2, - Advertiser: "sony.com", - PriceBucket: "10.00", + Adformat: models.Native, + KGPV: "kgpv", + NetECPM: 10, + GrossECPM: 12, + AdSize: "15x15", + FloorValue: 1, + FloorRuleValue: 2, + Advertiser: "sony.com", + PriceBucket: "10.00", + MultiBidMultiFloorFlag: 1, }, LoggerData: models.LoggerData{ KGPSV: "kgpsv", @@ -728,23 +729,24 @@ func TestGetPartnerRecordsByImpForTracker(t *testing.T) { partners: map[string][]PartnerRecord{ "imp1": { { - PartnerID: "pubmatic", - BidderCode: "pubmatic", - PartnerSize: "15x15", - BidID: "bid-id-1", - OrigBidID: "bid-id-1", - DealID: "-1", - ServerSide: 1, - OriginalCur: "USD", - Adformat: models.Native, - NetECPM: 10, - GrossECPM: 12, - FloorValue: 1, - FloorRuleValue: 2, - ADomain: "sony.com", - KGPV: "kgpv", - KGPSV: "kgpsv", - PriceBucket: "10.00", + PartnerID: "pubmatic", + BidderCode: "pubmatic", + PartnerSize: "15x15", + BidID: "bid-id-1", + OrigBidID: "bid-id-1", + DealID: "-1", + ServerSide: 1, + OriginalCur: "USD", + Adformat: models.Native, + NetECPM: 10, + GrossECPM: 12, + FloorValue: 1, + FloorRuleValue: 2, + ADomain: "sony.com", + KGPV: "kgpv", + KGPSV: "kgpsv", + PriceBucket: "10.00", + MultiBidMultiFloorFlag: 1, }, }, }, @@ -1029,6 +1031,7 @@ func TestGetPartnerRecordsByImpForDefaultBids(t *testing.T) { }, }, }, + TagID: "adunit_1234", }, }, }, diff --git a/analytics/pubmatic/record.go b/analytics/pubmatic/record.go index ebdd1a5f9d3..0f8e2692f6d 100644 --- a/analytics/pubmatic/record.go +++ b/analytics/pubmatic/record.go @@ -144,10 +144,11 @@ type PartnerRecord struct { OriginalCur string `json:"ocry"` MetaData *MetaData `json:"md,omitempty"` - FloorValue float64 `json:"fv,omitempty"` - FloorRuleValue float64 `json:"frv,omitempty"` - Nbr *openrtb3.NoBidReason `json:"nbr,omitempty"` // NonBR reason code - PriceBucket string `json:"pb,omitempty"` + FloorValue float64 `json:"fv,omitempty"` + FloorRuleValue float64 `json:"frv,omitempty"` + Nbr *openrtb3.NoBidReason `json:"nbr,omitempty"` // NonBR reason code + PriceBucket string `json:"pb,omitempty"` + MultiBidMultiFloorFlag int `json:"mbmf,omitempty"` } type MetaData struct { diff --git a/modules/pubmatic/openwrap/adapters/bidders.go b/modules/pubmatic/openwrap/adapters/bidders.go index 678dc601ec8..d8feb482c81 100644 --- a/modules/pubmatic/openwrap/adapters/bidders.go +++ b/modules/pubmatic/openwrap/adapters/bidders.go @@ -730,3 +730,22 @@ func builderAidem(params BidderParameters) (json.RawMessage, error) { return jsonStr.Bytes(), nil } + +func builderCompass(params BidderParameters) (json.RawMessage, error) { + jsonStr := bytes.Buffer{} + jsonStr.WriteByte('{') + oneOf := []string{"placementId", "endpointId"} + for _, param := range oneOf { + if key, ok := getString(params.FieldMap[param]); ok { + fmt.Fprintf(&jsonStr, `"%s":"%s"`, param, key) + break + } + } + // len=0 (no mandatory params present) + if jsonStr.Len() == 1 { + return nil, fmt.Errorf(errMandatoryParameterMissingFormat, params.AdapterName, oneOf) + } + + jsonStr.WriteByte('}') + return jsonStr.Bytes(), nil +} diff --git a/modules/pubmatic/openwrap/adapters/bidders_test.go b/modules/pubmatic/openwrap/adapters/bidders_test.go index 08c01d55a5c..52783889c68 100644 --- a/modules/pubmatic/openwrap/adapters/bidders_test.go +++ b/modules/pubmatic/openwrap/adapters/bidders_test.go @@ -3119,3 +3119,50 @@ func Test_builderAidem(t *testing.T) { }) } } + +func TestBuilderCompass(t *testing.T) { + type args struct { + params BidderParameters + } + tests := []struct { + name string + args args + want json.RawMessage + wantErr bool + }{ + { + name: "Valid Scenerio (oneOf placementId or endpointId) is present-placementId", + args: args{params: BidderParameters{FieldMap: JSONObject{"placementId": "dbdsfh"}}}, + want: json.RawMessage(`{"placementId": "dbdsfh"}`), + wantErr: false, + }, + { + name: "Valid Scenerio (oneOf placementId or endpointId) is present-endpointId", + args: args{params: BidderParameters{FieldMap: JSONObject{"endpointId": "dbdsfh"}}}, + want: json.RawMessage(`{"endpointId": "dbdsfh"}`), + wantErr: false, + }, + { + name: "Valid Scenerio (oneOf placementId or endpointId), Both are present", + args: args{params: BidderParameters{FieldMap: JSONObject{"placementId": "sdhks", "endpointId": "sdjksd"}}}, + want: json.RawMessage(`{"placementId": "sdhks"}`), + wantErr: false, + }, + { + name: "Invalid Scenerio (None Of placementId or endpointId) is present", + args: args{params: BidderParameters{FieldMap: JSONObject{}}}, + want: json.RawMessage(``), + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := builderCompass(tt.args.params) + if (err != nil) != tt.wantErr { + t.Errorf("builderCompass() error = %v, wantErr %v", err, tt.wantErr) + return + } + AssertJSON(t, tt.want, got) + }) + } +} diff --git a/modules/pubmatic/openwrap/adapters/builder.go b/modules/pubmatic/openwrap/adapters/builder.go index 23ce21b68b7..c2996005017 100644 --- a/modules/pubmatic/openwrap/adapters/builder.go +++ b/modules/pubmatic/openwrap/adapters/builder.go @@ -59,6 +59,7 @@ func initBidderBuilderFactory() { string(openrtb_ext.BidderKargo): builderKargo, string(openrtb_ext.BidderPGAMSsp): builderPGAMSSP, string(openrtb_ext.BidderAidem): builderAidem, + string(openrtb_ext.BidderCompass): builderCompass, } } diff --git a/modules/pubmatic/openwrap/adapters/tests/s2s_bidders.json b/modules/pubmatic/openwrap/adapters/tests/s2s_bidders.json index 12cefbbf095..9a0d55a1bbe 100644 --- a/modules/pubmatic/openwrap/adapters/tests/s2s_bidders.json +++ b/modules/pubmatic/openwrap/adapters/tests/s2s_bidders.json @@ -136,5 +136,20 @@ "siteId":"abcdefg" } } + }, + { + "name": "compass_json_OneOf - placementId/endpointId", + "args" : { + "adapterName": "compass", + "requestJSON": { + "placementId": "123456", + "endpointId": "abcdefg" + } + }, + "want": { + "expectedJSON": { + "placementId": "123456" + } + } } ] \ No newline at end of file diff --git a/modules/pubmatic/openwrap/auctionresponsehook.go b/modules/pubmatic/openwrap/auctionresponsehook.go index 2d7ecc2a406..700af49c8b1 100644 --- a/modules/pubmatic/openwrap/auctionresponsehook.go +++ b/modules/pubmatic/openwrap/auctionresponsehook.go @@ -167,6 +167,9 @@ func (m OpenWrap) handleAuctionResponseHook( bidExt.CreativeType = models.GetCreativeType(&bid, bidExt, &impCtx) } + if bidExt.CreativeType != string(openrtb_ext.BidTypeBanner) { + bidExt.ClickTrackers = nil + } // set response netecpm and logger/tracker en revShare := models.GetRevenueShare(rctx.PartnerConfigMap[partnerID]) bidExt.NetECPM = models.ToFixed(bid.Price, models.BID_PRECISION) diff --git a/modules/pubmatic/openwrap/auctionresponsehook_test.go b/modules/pubmatic/openwrap/auctionresponsehook_test.go index 4346dc5033b..4201a4e8a59 100644 --- a/modules/pubmatic/openwrap/auctionresponsehook_test.go +++ b/modules/pubmatic/openwrap/auctionresponsehook_test.go @@ -1664,7 +1664,7 @@ func TestOpenWrapHandleAuctionResponseHook(t *testing.T) { ImpID: "Div1", Price: 5, AdM: "
", - Ext: json.RawMessage(`{"bidtype":0,"deal_channel":1,"dspid":6,"origbidcpm":8,"origbidcur":"USD","ibv":true,"prebid":{"bidid":"bb57a9e3-fdc2-4772-8071-112dd7f50a6a","meta":{"adaptercode":"pubmatic","advertiserId":4098,"agencyId":4098,"demandSource":"6","mediaType":"banner","networkId":6},"targeting":{"hb_bidder_pubmatic":"pubmatic","hb_deal_pubmatic":"PUBDEAL1","hb_pb_pubmatic":"8.00","hb_size_pubmatic":"728x90"},"type":"banner","video":{"duration":0,"primary_category":"","vasttagid":""}}}`), + Ext: json.RawMessage(`{"bidtype":0,"deal_channel":1,"dspid":6,"origbidcpm":8,"origbidcur":"USD","ibv":true,"prebid":{"bidid":"bb57a9e3-fdc2-4772-8071-112dd7f50a6a","meta":{"adaptercode":"pubmatic","advertiserId":4098,"agencyId":4098,"demandSource":"6","mediaType":"banner","networkId":6},"targeting":{"hb_bidder_pubmatic":"pubmatic","hb_deal_pubmatic":"PUBDEAL1","hb_pb_pubmatic":"8.00","hb_size_pubmatic":"728x90"},"type":"banner","video":{"duration":0,"primary_category":"","vasttagid":""}},"clicktrackers":["http://clicktracker1.com","http://clicktracker2.com"]}`), }, }, Seat: "pubmatic", @@ -1691,7 +1691,7 @@ func TestOpenWrapHandleAuctionResponseHook(t *testing.T) { DebugMessages: []string{`[{"PubID":5890,"ProfileID":0,"DisplayID":0,"VersionID":0,"DisplayVersionID":0,"SSAuction":0,"SummaryDisable":0,"SSAI":"","PartnerConfigMap":{"-1":{"displayVersionId":"1","refreshInterval":"30","rev_share":"0.5"},"123":{"bidderCode":"pubmatic","kgp":"_AU_@_W_x_H_","partnerId":"123","prebidPartnerName":"pubmatic","serverSideEnabled":"1","timeout":"200"}},"SupportDeals":false,"Platform":"web","LoggerImpressionID":"","ClientConfigFlag":1,"IP":"","TMax":0,"IsTestRequest":0,"ABTestConfig":0,"ABTestConfigApplied":0,"IsCTVRequest":false,"TrackerEndpoint":"","VideoErrorTrackerEndpoint":"","UA":"","Cookies":"","UidCookie":null,"KADUSERCookie":null,"ParsedUidCookie":null,"OriginCookie":"","Debug":true,"Trace":false,"PageURL":"","StartTime":0,"DevicePlatform":0,"Trackers":{"bid-id-1":{"Tracker":{"PubID":5890,"PageURL":"","Timestamp":0,"IID":"","ProfileID":"0","VersionID":"0","SlotID":"","Adunit":"","PartnerInfo":{"PartnerID":"pubmatic","BidderCode":"pubmatic","KGPV":"","GrossECPM":0,"NetECPM":0,"BidID":"bb57a9e3-fdc2-4772-8071-112dd7f50a6a","OrigBidID":"bid-id-1","AdSize":"0x0","AdDuration":0,"Adformat":"banner","ServerSide":1,"Advertiser":"","FloorValue":0,"FloorRuleValue":0,"DealID":"-1"},"RewardedInventory":0,"SURL":"","Platform":0,"SSAI":"","AdPodSlot":0,"TestGroup":0,"Origin":"","FloorSkippedFlag":null,"FloorModelVersion":"","FloorSource":null,"FloorType":0,"CustomDimensions":"","LoggerData":{"KGPSV":"","FloorProvider":"","FloorFetchStatus":null}},"TrackerURL":"https:?adv=\u0026af=banner\u0026aps=0\u0026au=\u0026bc=pubmatic\u0026bidid=bb57a9e3-fdc2-4772-8071-112dd7f50a6a\u0026di=-1\u0026eg=0\u0026en=0\u0026ft=0\u0026iid=\u0026kgpv=\u0026orig=\u0026origbidid=bid-id-1\u0026pdvid=0\u0026pid=0\u0026plt=0\u0026pn=pubmatic\u0026psz=0x0\u0026pubid=5890\u0026purl=\u0026sl=1\u0026slot=\u0026ss=1\u0026tgid=0\u0026tst=0","ErrorURL":"","Price":5,"PriceModel":"CPM","PriceCurrency":""}},"PrebidBidderCode":null,"ImpBidCtx":{"Div1":{"ImpID":"","TagID":"","Div":"","SlotName":"","AdUnitName":"","Secure":0,"BidFloor":0,"BidFloorCur":"","IsRewardInventory":null,"Banner":true,"Video":{"mimes":null},"Native":null,"IncomingSlots":null,"Type":"video","Bidders":{"pubmatic":{"PartnerID":123,"PrebidBidderCode":"pubmatic","MatchedSlot":"","KGP":"","KGPV":"","IsRegex":false,"Params":null,"VASTTagFlag":false,"VASTTagFlags":null}},"NonMapped":null,"NewExt":null,"BidCtx":{"bid-id-1":{"prebid":{"meta":{"adaptercode":"pubmatic","advertiserId":4098,"agencyId":4098,"demandSource":"6","mediaType":"banner","networkId":6},"type":"banner","bidid":"bb57a9e3-fdc2-4772-8071-112dd7f50a6a"},"refreshInterval":30,"crtype":"banner","dspid":6,"netecpm":5,"origbidcpm":8,"origbidcur":"USD","EG":0,"EN":0}},"BannerAdUnitCtx":{"MatchedSlot":"","IsRegex":false,"MatchedRegex":"","SelectedSlotAdUnitConfig":null,"AppliedSlotAdUnitConfig":null,"UsingDefaultConfig":false,"AllowedConnectionTypes":null},"VideoAdUnitCtx":{"MatchedSlot":"","IsRegex":false,"MatchedRegex":"","SelectedSlotAdUnitConfig":null,"AppliedSlotAdUnitConfig":null,"UsingDefaultConfig":false,"AllowedConnectionTypes":null},"BidderError":"","IsAdPodRequest":false}},"Aliases":null,"NewReqExt":null,"ResponseExt":{"responsetimemillis":{"pubmatic":8}},"MarketPlaceBidders":null,"AdapterThrottleMap":null,"AdUnitConfig":null,"Source":"","Origin":"","SendAllBids":false,"WinningBids":{"Div1":{"ID":"bid-id-1","NetEcpm":5,"BidDealTierSatisfied":false,"Nbr":null}},"DroppedBids":null,"DefaultBids":{},"SeatNonBids":{},"BidderResponseTimeMillis":{"pubmatic":8},"Endpoint":"","PubIDStr":"5890","ProfileIDStr":"","MetricsEngine":{},"ReturnAllBidStatus":true,"Sshb":"","DCName":"","CachePutMiss":0,"MatchedImpression":{"pubmatic":0},"CustomDimensions":null}]`}, }, err: nil, - bidResponse: json.RawMessage(`{"id":"12345","seatbid":[{"bid":[{"id":"bid-id-1","impid":"Div1","price":5,"adm":"\u003cimg src=\"http://ads.pubmatic.com/AdTag/728x90.png\"\u003e\u003c/img\u003e\u003cdiv style=\"position:absolute;left:0px;top:0px;visibility:hidden;\"\u003e\u003cimg src=\"https://t.pubmatic.com/wt?adv=\u0026af=banner\u0026aps=0\u0026au=%2F43743431%2FDMDemo\u0026bc=appnexus\u0026bidid=4033c510-6d67-4af6-b53f-682ff1a580c3\u0026di=-1\u0026eg=14\u0026en=14\u0026frv=1.57\u0026ft=0\u0026fv=1.57\u0026iid=429d469d-8cfb-495a-9f0c-5f48aa0ede40\u0026kgpv=\u0026orig=ebay.com\u0026origbidid=718825584\u0026pdvid=1\u0026pid=22503\u0026plt=1\u0026pn=appnexus\u0026psz=728x90\u0026pubid=5890\u0026purl=http%3A%2F%2Febay.com%2Finte%2Fautomation%2Fs2s_activation%2Fbanner-with-gdpr-pubmatic-denied-defaultbidder.html%3Fprofileid%3D22503%26pwtv%3D1%26pwtvc%3D1%26appnexus_banner_fixedbid%3D14%26fixedbid%3D1%26debug%3D1\u0026sl=1\u0026slot=%2F43743431%2FDMDemo\u0026ss=1\u0026tgid=0\u0026tst=1704357774\"\u003e\u003c/div\u003e\u003cdiv style=\"position:absolute;left:0px;top:0px;visibility:hidden;\"\u003e\u003cimg src=\"https:?adv=\u0026af=banner\u0026aps=0\u0026au=\u0026bc=pubmatic\u0026bidid=bb57a9e3-fdc2-4772-8071-112dd7f50a6a\u0026di=-1\u0026eg=0\u0026en=0\u0026ft=0\u0026iid=\u0026kgpv=\u0026orig=\u0026origbidid=bid-id-1\u0026pdvid=0\u0026pid=0\u0026plt=0\u0026pn=pubmatic\u0026psz=0x0\u0026pubid=5890\u0026purl=\u0026sl=1\u0026slot=\u0026ss=1\u0026tgid=0\u0026tst=0\"\u003e\u003c/div\u003e","ext":{"prebid":{"meta":{"adaptercode":"pubmatic","advertiserId":4098,"agencyId":4098,"demandSource":"6","mediaType":"banner","networkId":6},"type":"banner","bidid":"bb57a9e3-fdc2-4772-8071-112dd7f50a6a"},"refreshInterval":30,"crtype":"banner","dspid":6,"netecpm":5,"origbidcpm":8,"origbidcur":"USD","ibv":true}}],"seat":"pubmatic"}],"ext":{"responsetimemillis":{"pubmatic":8},"matchedimpression":{"pubmatic":0}}}`), + bidResponse: json.RawMessage(`{"id":"12345","seatbid":[{"bid":[{"id":"bid-id-1","impid":"Div1","price":5,"adm":"\u003cimg src=\"http://ads.pubmatic.com/AdTag/728x90.png\"\u003e\u003c/img\u003e\u003cdiv style=\"position:absolute;left:0px;top:0px;visibility:hidden;\"\u003e\u003cimg src=\"https://t.pubmatic.com/wt?adv=\u0026af=banner\u0026aps=0\u0026au=%2F43743431%2FDMDemo\u0026bc=appnexus\u0026bidid=4033c510-6d67-4af6-b53f-682ff1a580c3\u0026di=-1\u0026eg=14\u0026en=14\u0026frv=1.57\u0026ft=0\u0026fv=1.57\u0026iid=429d469d-8cfb-495a-9f0c-5f48aa0ede40\u0026kgpv=\u0026orig=ebay.com\u0026origbidid=718825584\u0026pdvid=1\u0026pid=22503\u0026plt=1\u0026pn=appnexus\u0026psz=728x90\u0026pubid=5890\u0026purl=http%3A%2F%2Febay.com%2Finte%2Fautomation%2Fs2s_activation%2Fbanner-with-gdpr-pubmatic-denied-defaultbidder.html%3Fprofileid%3D22503%26pwtv%3D1%26pwtvc%3D1%26appnexus_banner_fixedbid%3D14%26fixedbid%3D1%26debug%3D1\u0026sl=1\u0026slot=%2F43743431%2FDMDemo\u0026ss=1\u0026tgid=0\u0026tst=1704357774\"\u003e\u003c/div\u003e\u003cdiv style=\"position:absolute;left:0px;top:0px;visibility:hidden;\"\u003e\u003cimg src=\"https:?adv=\u0026af=banner\u0026aps=0\u0026au=\u0026bc=pubmatic\u0026bidid=bb57a9e3-fdc2-4772-8071-112dd7f50a6a\u0026di=-1\u0026eg=0\u0026en=0\u0026ft=0\u0026iid=\u0026kgpv=\u0026orig=\u0026origbidid=bid-id-1\u0026pdvid=0\u0026pid=0\u0026plt=0\u0026pn=pubmatic\u0026psz=0x0\u0026pubid=5890\u0026purl=\u0026sl=1\u0026slot=\u0026ss=1\u0026tgid=0\u0026tst=0\"\u003e\u003c/div\u003e","ext":{"prebid":{"meta":{"adaptercode":"pubmatic","advertiserId":4098,"agencyId":4098,"demandSource":"6","mediaType":"banner","networkId":6},"type":"banner","bidid":"bb57a9e3-fdc2-4772-8071-112dd7f50a6a"},"refreshInterval":30,"crtype":"banner","dspid":6,"netecpm":5,"origbidcpm":8,"origbidcur":"USD","ibv":true,"clicktrackers":["http://clicktracker1.com","http://clicktracker2.com"]}}],"seat":"pubmatic"}],"ext":{"responsetimemillis":{"pubmatic":8},"matchedimpression":{"pubmatic":0}}}`), }, }, { @@ -1761,7 +1761,7 @@ func TestOpenWrapHandleAuctionResponseHook(t *testing.T) { ImpID: "Div1", Price: 5, AdM: "", - Ext: json.RawMessage(`{"bidtype":0,"deal_channel":1,"dspid":6,"mbmfv":4,"origbidcpm":8,"origbidcur":"USD","prebid":{"bidid":"bb57a9e3-fdc2-4772-8071-112dd7f50a6a","meta":{"adaptercode":"pubmatic","advertiserId":4098,"agencyId":4098,"demandSource":"6","mediaType":"banner","networkId":6},"targeting":{"hb_bidder_pubmatic":"pubmatic","hb_deal_pubmatic":"PUBDEAL1","hb_pb_pubmatic":"8.00","hb_size_pubmatic":"728x90"},"type":"video","video":{"duration":0,"primary_category":"","vasttagid":""}}}`), + Ext: json.RawMessage(`{"bidtype":0,"deal_channel":1,"dspid":6,"mbmfv":4,"origbidcpm":8,"origbidcur":"USD","prebid":{"bidid":"bb57a9e3-fdc2-4772-8071-112dd7f50a6a","meta":{"adaptercode":"pubmatic","advertiserId":4098,"agencyId":4098,"demandSource":"6","mediaType":"banner","networkId":6},"targeting":{"hb_bidder_pubmatic":"pubmatic","hb_deal_pubmatic":"PUBDEAL1","hb_pb_pubmatic":"8.00","hb_size_pubmatic":"728x90"},"type":"video","video":{"duration":0,"primary_category":"","vasttagid":""}},"clicktrackers":["http://clicktracker1.com","http://clicktracker2.com"]}`), }, }, Seat: "pubmatic", @@ -1785,7 +1785,7 @@ func TestOpenWrapHandleAuctionResponseHook(t *testing.T) { want: want{ result: hookstage.HookResult[hookstage.AuctionResponsePayload]{}, err: nil, - bidResponse: json.RawMessage(`{"id":"12345","seatbid":[{"bid":[{"id":"bid-id-1","impid":"Div1","price":5,"adm":"\u003cVAST version=\"3.0\"\u003e\u003cAd\u003e\u003cWrapper\u003e\u003cImpression\u003e\u003c![CDATA[https:?adv=\u0026af=video\u0026aps=0\u0026au=\u0026bc=pubmatic\u0026bidid=bb57a9e3-fdc2-4772-8071-112dd7f50a6a\u0026di=-1\u0026dur=20\u0026eg=0\u0026en=0\u0026frv=4\u0026ft=0\u0026fv=4\u0026iid=\u0026kgpv=\u0026orig=\u0026origbidid=bid-id-1\u0026pdvid=0\u0026pid=0\u0026plt=0\u0026pn=pubmatic\u0026psz=0x0\u0026pubid=5890\u0026purl=\u0026sl=1\u0026slot=\u0026ss=1\u0026tgid=0\u0026tst=0]]\u003e\u003c/Impression\u003e\u003cExtensions\u003e\u003cExtension\u003e\u003cPricing model=\"CPM\" currency=\"USD\"\u003e\u003c![CDATA[5]]\u003e\u003c/Pricing\u003e\u003c/Extension\u003e\u003c/Extensions\u003e\u003c/Wrapper\u003e\u003c/Ad\u003e\u003c/VAST\u003e","ext":{"prebid":{"meta":{"adaptercode":"pubmatic","advertiserId":4098,"agencyId":4098,"demandSource":"6","mediaType":"banner","networkId":6},"type":"video","video":{"duration":20,"primary_category":"","vasttagid":""},"bidid":"bb57a9e3-fdc2-4772-8071-112dd7f50a6a"},"refreshInterval":30,"crtype":"video","video":{"minduration":10,"maxduration":20,"skip":1,"skipmin":1,"skipafter":2,"battr":[1],"playbackmethod":[1]},"dspid":6,"netecpm":5,"origbidcpm":8,"origbidcur":"USD"}}],"seat":"pubmatic"}],"ext":{"responsetimemillis":{"pubmatic":8},"matchedimpression":{"pubmatic":0}}}`), + bidResponse: json.RawMessage(`{"id":"12345","seatbid":[{"bid":[{"id":"bid-id-1","impid":"Div1","price":5,"adm":"\u003cVAST version=\"3.0\"\u003e\u003cAd\u003e\u003cWrapper\u003e\u003cImpression\u003e\u003c![CDATA[https:?adv=\u0026af=video\u0026aps=0\u0026au=\u0026bc=pubmatic\u0026bidid=bb57a9e3-fdc2-4772-8071-112dd7f50a6a\u0026di=-1\u0026dur=20\u0026eg=0\u0026en=0\u0026frv=4\u0026ft=0\u0026fv=4\u0026iid=\u0026kgpv=\u0026mbmf=1\u0026orig=\u0026origbidid=bid-id-1\u0026pdvid=0\u0026pid=0\u0026plt=0\u0026pn=pubmatic\u0026psz=0x0\u0026pubid=5890\u0026purl=\u0026sl=1\u0026slot=\u0026ss=1\u0026tgid=0\u0026tst=0]]\u003e\u003c/Impression\u003e\u003cExtensions\u003e\u003cExtension\u003e\u003cPricing model=\"CPM\" currency=\"USD\"\u003e\u003c![CDATA[5]]\u003e\u003c/Pricing\u003e\u003c/Extension\u003e\u003c/Extensions\u003e\u003c/Wrapper\u003e\u003c/Ad\u003e\u003c/VAST\u003e","ext":{"prebid":{"meta":{"adaptercode":"pubmatic","advertiserId":4098,"agencyId":4098,"demandSource":"6","mediaType":"banner","networkId":6},"type":"video","video":{"duration":20,"primary_category":"","vasttagid":""},"bidid":"bb57a9e3-fdc2-4772-8071-112dd7f50a6a"},"refreshInterval":30,"crtype":"video","video":{"minduration":10,"maxduration":20,"skip":1,"skipmin":1,"skipafter":2,"battr":[1],"playbackmethod":[1]},"dspid":6,"netecpm":5,"origbidcpm":8,"origbidcur":"USD"}}],"seat":"pubmatic"}],"ext":{"responsetimemillis":{"pubmatic":8},"matchedimpression":{"pubmatic":0}}}`), }, }, } diff --git a/modules/pubmatic/openwrap/beforevalidationhook.go b/modules/pubmatic/openwrap/beforevalidationhook.go index 8fb761d9368..fa2a971cd94 100644 --- a/modules/pubmatic/openwrap/beforevalidationhook.go +++ b/modules/pubmatic/openwrap/beforevalidationhook.go @@ -854,6 +854,11 @@ func setImpBidFloorParams(rCtx models.RequestCtx, adUnitCfg *modelsAdunitConfig. bidfloorcur = *adUnitCfg.BidFloorCur } } + + if bidfloor > 0 && len(bidfloorcur) == 0 { + bidfloorcur = models.USD + } + return bidfloor, bidfloorcur } diff --git a/modules/pubmatic/openwrap/beforevalidationhook_test.go b/modules/pubmatic/openwrap/beforevalidationhook_test.go index 7b9b7d41a4b..42939e037dc 100644 --- a/modules/pubmatic/openwrap/beforevalidationhook_test.go +++ b/modules/pubmatic/openwrap/beforevalidationhook_test.go @@ -7108,6 +7108,19 @@ func TestSetImpBidFloorParams(t *testing.T) { expBidfloor: 2.6, expBidfloorCur: "USD", }, + { + name: "bidfloor_is_present_but_bidfloorcur_is_not_present_set_default_currency_USD", + args: args{ + adUnitCfg: &adunitconfig.AdConfig{ + BidFloor: ptrutil.ToPtr(2.0), + }, + imp: &openrtb2.Imp{ + BidFloor: 2.6, + }, + }, + expBidfloor: 2.6, + expBidfloorCur: "USD", + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/modules/pubmatic/openwrap/models/response.go b/modules/pubmatic/openwrap/models/response.go index c6b0ff4acaf..60a6fdf6fcd 100644 --- a/modules/pubmatic/openwrap/models/response.go +++ b/modules/pubmatic/openwrap/models/response.go @@ -30,6 +30,7 @@ type BidExt struct { AdPod *AdpodBidExt `json:"adpod,omitempty"` MultiBidMultiFloorValue float64 `json:"-"` InBannerVideo bool `json:"ibv,omitempty"` + ClickTrackers []string `json:"clicktrackers,omitempty"` } type AdpodBidExt struct { diff --git a/modules/pubmatic/openwrap/models/tracker.go b/modules/pubmatic/openwrap/models/tracker.go index 74822a37cb3..54c0eaaed89 100644 --- a/modules/pubmatic/openwrap/models/tracker.go +++ b/modules/pubmatic/openwrap/models/tracker.go @@ -46,22 +46,23 @@ type Tracker struct { // Partner partner information to be logged in tracker object type Partner struct { - PartnerID string - BidderCode string - KGPV string - GrossECPM float64 - NetECPM float64 - BidID string - OrigBidID string - AdSize string - AdDuration int - Adformat string - ServerSide int - Advertiser string - FloorValue float64 - FloorRuleValue float64 - DealID string - PriceBucket string + PartnerID string + BidderCode string + KGPV string + GrossECPM float64 + NetECPM float64 + BidID string + OrigBidID string + AdSize string + AdDuration int + Adformat string + ServerSide int + Advertiser string + FloorValue float64 + FloorRuleValue float64 + DealID string + PriceBucket string + MultiBidMultiFloorFlag int } // LoggerData: this data to be needed in logger diff --git a/modules/pubmatic/openwrap/models/tracking.go b/modules/pubmatic/openwrap/models/tracking.go index 0c202f5d613..104552b9c3d 100644 --- a/modules/pubmatic/openwrap/models/tracking.go +++ b/modules/pubmatic/openwrap/models/tracking.go @@ -5,53 +5,54 @@ import "github.com/prebid/prebid-server/v2/openrtb_ext" // impression tracker url parameters const ( // constants for query parameter names for tracker call - TRKPubID = "pubid" - TRKPageURL = "purl" - TRKTimestamp = "tst" - TRKIID = "iid" - TRKProfileID = "pid" - TRKVersionID = "pdvid" - TRKIP = "ip" - TRKUserAgent = "ua" - TRKSlotID = "slot" - TRKAdunit = "au" - TRKRewardedInventory = "rwrd" - TRKPartnerID = "pn" - TRKBidderCode = "bc" - TRKKGPV = "kgpv" - TRKGrossECPM = "eg" - TRKNetECPM = "en" - TRKBidID = "bidid" - TRKOrigBidID = "origbidid" - TRKQMARK = "?" - TRKAmpersand = "&" - TRKSSAI = "ssai" - TRKPlatform = "plt" - TRKAdSize = "psz" - TRKTestGroup = "tgid" - TRKAdvertiser = "adv" - TRKPubDomain = "orig" - TRKServerSide = "ss" - TRKAdformat = "af" - TRKAdDuration = "dur" - TRKAdPodExist = "aps" - TRKFloorType = "ft" - TRKFloorModelVersion = "fmv" - TRKFloorProvider = "fp" - TRKFloorSkippedFlag = "fskp" - TRKFloorSource = "fsrc" - TRKFloorValue = "fv" - TRKFloorRuleValue = "frv" - TRKServerLogger = "sl" - TRKDealID = "di" - TRKCustomDimensions = "cds" - TRKATTS = "atts" - TRKProfileType = "pt" - TRKProfileTypePlatform = "ptp" - TRKAppPlatform = "ap" - TRKAppIntegrationPath = "aip" - TRKAppSubIntegrationPath = "asip" - TRKPriceBucket = "pb" + TRKPubID = "pubid" + TRKPageURL = "purl" + TRKTimestamp = "tst" + TRKIID = "iid" + TRKProfileID = "pid" + TRKVersionID = "pdvid" + TRKIP = "ip" + TRKUserAgent = "ua" + TRKSlotID = "slot" + TRKAdunit = "au" + TRKRewardedInventory = "rwrd" + TRKPartnerID = "pn" + TRKBidderCode = "bc" + TRKKGPV = "kgpv" + TRKGrossECPM = "eg" + TRKNetECPM = "en" + TRKBidID = "bidid" + TRKOrigBidID = "origbidid" + TRKQMARK = "?" + TRKAmpersand = "&" + TRKSSAI = "ssai" + TRKPlatform = "plt" + TRKAdSize = "psz" + TRKTestGroup = "tgid" + TRKAdvertiser = "adv" + TRKPubDomain = "orig" + TRKServerSide = "ss" + TRKAdformat = "af" + TRKAdDuration = "dur" + TRKAdPodExist = "aps" + TRKFloorType = "ft" + TRKFloorModelVersion = "fmv" + TRKFloorProvider = "fp" + TRKFloorSkippedFlag = "fskp" + TRKFloorSource = "fsrc" + TRKFloorValue = "fv" + TRKFloorRuleValue = "frv" + TRKServerLogger = "sl" + TRKDealID = "di" + TRKCustomDimensions = "cds" + TRKATTS = "atts" + TRKProfileType = "pt" + TRKProfileTypePlatform = "ptp" + TRKAppPlatform = "ap" + TRKAppIntegrationPath = "aip" + TRKAppSubIntegrationPath = "asip" + TRKPriceBucket = "pb" + TRKMultiBidMultiFloorFlag = "mbmf" ) // video error tracker url parameters diff --git a/modules/pubmatic/openwrap/tracker/create.go b/modules/pubmatic/openwrap/tracker/create.go index 8354fd7030a..5537b8c6a31 100644 --- a/modules/pubmatic/openwrap/tracker/create.go +++ b/modules/pubmatic/openwrap/tracker/create.go @@ -88,7 +88,7 @@ func createTrackers(rctx models.RequestCtx, trackers map[string]models.OWTracker floorValue, floorRuleValue = float64(0), float64(0) partnerID = seatBid.Seat isRewardInventory, adduration = 0, 0 - dspId int + dspId, mbmfFlag int eg, en float64 ) @@ -107,6 +107,10 @@ func createTrackers(rctx models.RequestCtx, trackers map[string]models.OWTracker // TODO do most calculation in wt // marketplace/alternatebiddercodes feature bidExt := bidCtx.BidExt + if bidExt.MultiBidMultiFloorValue > 0 { + mbmfFlag = 1 + } + if bidExt.Prebid != nil { if bidExt.Prebid.Video != nil && bidExt.Prebid.Video.Duration > 0 { adduration = bidExt.Prebid.Video.Duration @@ -167,20 +171,21 @@ func createTrackers(rctx models.RequestCtx, trackers map[string]models.OWTracker tracker.RewardedInventory = isRewardInventory tracker.PartnerInfo = models.Partner{ - PartnerID: partnerID, - BidderCode: seatBid.Seat, - BidID: utils.GetOriginalBidId(bid.ID), - OrigBidID: utils.GetOriginalBidId(bid.ID), - KGPV: kgpv, - NetECPM: en, - GrossECPM: eg, - AdSize: models.GetSizeForPlatform(bid.W, bid.H, rctx.Platform), - AdDuration: adduration, - Adformat: adformat, - ServerSide: 1, - FloorValue: floorValue, - FloorRuleValue: floorRuleValue, - DealID: "-1", + PartnerID: partnerID, + BidderCode: seatBid.Seat, + BidID: utils.GetOriginalBidId(bid.ID), + OrigBidID: utils.GetOriginalBidId(bid.ID), + KGPV: kgpv, + NetECPM: en, + GrossECPM: eg, + AdSize: models.GetSizeForPlatform(bid.W, bid.H, rctx.Platform), + AdDuration: adduration, + Adformat: adformat, + ServerSide: 1, + FloorValue: floorValue, + FloorRuleValue: floorRuleValue, + DealID: "-1", + MultiBidMultiFloorFlag: mbmfFlag, } if rctx.PriceGranularity != nil { tracker.PartnerInfo.PriceBucket = exchange.GetPriceBucketOW(bid.Price, *rctx.PriceGranularity) @@ -293,6 +298,9 @@ func constructTrackerURL(rctx models.RequestCtx, tracker models.Tracker) string if tracker.PartnerInfo.PriceBucket != "" { v.Set(models.TRKPriceBucket, tracker.PartnerInfo.PriceBucket) } + if tracker.PartnerInfo.MultiBidMultiFloorFlag == 1 { + v.Set(models.TRKMultiBidMultiFloorFlag, strconv.Itoa(tracker.PartnerInfo.MultiBidMultiFloorFlag)) + } //ProfileMetadata parameters if rctx.ProfileType > 0 { diff --git a/modules/pubmatic/openwrap/tracker/create_test.go b/modules/pubmatic/openwrap/tracker/create_test.go index 6b899335acd..3e5f7c89086 100644 --- a/modules/pubmatic/openwrap/tracker/create_test.go +++ b/modules/pubmatic/openwrap/tracker/create_test.go @@ -267,6 +267,149 @@ func Test_createTrackers(t *testing.T) { }, }, }, + { + name: "response with all details and multibid-multifloor feature enabled", + args: args{ + trackers: map[string]models.OWTracker{}, + rctx: func() models.RequestCtx { + testRctx := rctx + testRctx.StartTime = startTime + pg, _ := openrtb_ext.NewPriceGranularityFromLegacyID("med") + testRctx.PriceGranularity = &pg + testRctx.AppLovinMax = models.AppLovinMax{ + MultiFloorsConfig: models.MultiFloorsConfig{ + Enabled: true, + Config: models.ApplovinAdUnitFloors{ + "adunit-1": []float64{1.2, 1.3, 1.4}, + }, + }, + } + testRctx.ImpBidCtx = map[string]models.ImpCtx{ + "impID-1": { + TagID: "adunit-1", + AdUnitName: "adunit-1", + SlotName: "impID-1_adunit-1", + Bidders: map[string]models.PartnerData{ + "pubmatic": { + MatchedSlot: "matchedSlot", + PrebidBidderCode: "prebidBidderCode", + KGP: "_AU_@_W_x_H_", + }, + "pubmatic2": { + MatchedSlot: "matchedSlot2", + PrebidBidderCode: "prebidBidderCode2", + KGP: "_AU_@_W_x_H_", + }, + }, + BidFloor: 5.5, + BidFloorCur: "EUR", + BidCtx: map[string]models.BidCtx{ + "bidID-1": { + EG: 8.7, + EN: 8.7, + BidExt: models.BidExt{ + OriginalBidCPMUSD: 0, + ExtBid: openrtb_ext.ExtBid{ + Prebid: &openrtb_ext.ExtBidPrebid{ + BidId: "bidID-1", + Video: &openrtb_ext.ExtBidPrebidVideo{ + Duration: 20, + }, + Meta: &openrtb_ext.ExtBidPrebidMeta{ + AdapterCode: "pubmatic", + }, + Floors: &openrtb_ext.ExtBidPrebidFloors{ + FloorRule: "rule1", + FloorValue: 6.4, + FloorRuleValue: 4.4, + }, + Type: models.Banner, + }, + }, + MultiBidMultiFloorValue: 4.5, + }, + }, + }, + }, + } + testRctx.DeviceCtx.Ext = func() *models.ExtDevice { + extDevice := models.ExtDevice{} + extDevice.UnmarshalJSON([]byte(`{"atts":1}`)) + return &extDevice + }() + return testRctx + }(), + bidResponse: &openrtb2.BidResponse{ + SeatBid: []openrtb2.SeatBid{ + { + Bid: []openrtb2.Bid{ + { + ID: "bidID-1", + ImpID: "impID-1", + Price: 8.7, + W: 250, + H: 300, + ADomain: []string{"domain.com"}, + DealID: "deal-id-1", + }, + }, + Seat: "pubmatic", + }, + }, + Cur: models.USD, + }, + pmMkt: map[string]pubmaticMarketplaceMeta{}, + }, + want: map[string]models.OWTracker{ + "bidID-1": { + Tracker: models.Tracker{ + PubID: 5890, + PageURL: "abc.com", + Timestamp: startTime, + IID: "loggerIID", + ProfileID: "1234", + VersionID: "1", + Adunit: "adunit-1", + SlotID: "impID-1_adunit-1", + PartnerInfo: models.Partner{ + PartnerID: "prebidBidderCode", + BidderCode: "pubmatic", + KGPV: "adunit-1@250x300", + GrossECPM: 8.7, + NetECPM: 8.7, + BidID: "bidID-1", + OrigBidID: "bidID-1", + AdSize: "250x300", + AdDuration: 20, + Adformat: "banner", + ServerSide: 1, + Advertiser: "domain.com", + FloorValue: 4.5, + FloorRuleValue: 4.5, + DealID: "deal-id-1", + PriceBucket: "8.60", + MultiBidMultiFloorFlag: 1, + }, + Platform: 5, + SSAI: "mediatailor", + AdPodSlot: 0, + TestGroup: 1, + Origin: "publisher.com", + ImpID: "impID-1", + LoggerData: models.LoggerData{ + KGPSV: "adunit-1@250x300", + }, + CustomDimensions: "author=henry", + ATTS: ptrutil.ToPtr(float64(openrtb_ext.IOSAppTrackingStatusRestricted)), + }, + TrackerURL: "https:?adv=domain.com&af=banner&aps=0&atts=1&au=adunit-1&bc=pubmatic&bidid=bidID-1&cds=author%3Dhenry&di=deal-id-1&dur=20&eg=8.7&en=8.7&frv=4.5&ft=0&fv=4.5&iid=loggerIID&kgpv=adunit-1%40250x300&mbmf=1&orig=publisher.com&origbidid=bidID-1&pb=8.60&pdvid=1&pid=1234&plt=5&pn=prebidBidderCode&psz=250x300&pubid=5890&purl=abc.com&sl=1&slot=impID-1_adunit-1&ss=1&ssai=mediatailor&tgid=1&tst=" + strconv.FormatInt(startTime, 10), + Price: 8.7, + PriceModel: "CPM", + PriceCurrency: "USD", + BidType: "banner", + }, + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -559,6 +702,53 @@ func TestConstructTrackerURL(t *testing.T) { }, want: "//t.pubmatic.com/wt?adv=&af=&aip=3&ap=5&aps=0&asip=8&au=&bc=&bidid=&di=&eg=0&en=0&ft=0&iid=&kgpv=&orig=&origbidid=&pdvid=&pid=&plt=0&pn=&psz=&pt=1&ptp=4&pubid=0&purl=&sl=1&slot=&ss=0&tgid=0&tst=0", }, + { + name: "all_floors_details_in_tracker_multiBidMultiFloor_enabled", + args: args{ + rctx: models.RequestCtx{ + TrackerEndpoint: "//t.pubmatic.com/wt", + Platform: models.PLATFORM_APP, + }, + tracker: models.Tracker{ + PubID: 12345, + PageURL: "www.abc.com", + IID: "98765", + ProfileID: "123", + VersionID: "1", + SlotID: "1234_1234", + Adunit: "adunit", + Platform: 1, + Origin: "www.publisher.com", + TestGroup: 1, + AdPodSlot: 0, + FloorSkippedFlag: ptrutil.ToPtr(0), + FloorModelVersion: "test version", + FloorSource: ptrutil.ToPtr(1), + FloorType: 1, + CustomDimensions: "traffic=media;age=23", + PartnerInfo: models.Partner{ + PartnerID: "AppNexus", + BidderCode: "AppNexus1", + BidID: "6521", + OrigBidID: "6521", + GrossECPM: 4.3, + NetECPM: 2.5, + KGPV: "adunit@300x250", + AdDuration: 10, + Adformat: models.Banner, + AdSize: "300x250", + ServerSide: 1, + Advertiser: "fb.com", + DealID: "420", + FloorValue: 4.5, + FloorRuleValue: 4.5, + PriceBucket: "2.50", + MultiBidMultiFloorFlag: 1, + }, + }, + }, + want: "//t.pubmatic.com/wt?adv=fb.com&af=banner&aps=0&au=adunit&bc=AppNexus1&bidid=6521&cds=traffic=media;age=23&di=420&dur=10&eg=4.3&en=2.5&fmv=test version&frv=4.5&fskp=0&fsrc=1&ft=1&fv=4.5&iid=98765&kgpv=adunit@300x250&mbmf=1&orig=www.publisher.com&origbidid=6521&pb=2.50&pdvid=1&pid=123&plt=1&pn=AppNexus&psz=300x250&pubid=12345&purl=www.abc.com&sl=1&slot=1234_1234&ss=1&tgid=1&tst=0", + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) {