4242import org .prebid .server .proto .openrtb .ext .request .pubmatic .ExtImpPubmaticKeyVal ;
4343import org .prebid .server .proto .openrtb .ext .response .BidType ;
4444import org .prebid .server .proto .openrtb .ext .response .ExtBidPrebid ;
45+ import org .prebid .server .proto .openrtb .ext .response .ExtBidPrebidMeta ;
4546import org .prebid .server .proto .openrtb .ext .response .ExtBidPrebidVideo ;
4647import org .prebid .server .proto .openrtb .ext .response .ExtIgi ;
4748import org .prebid .server .proto .openrtb .ext .response .ExtIgiIgs ;
@@ -504,6 +505,7 @@ public CompositeBidderResponse makeBidderResponse(BidderCall<BidRequest> httpCal
504505 return CompositeBidderResponse .builder ()
505506 .bids (extractBids (bidResponse , errors ))
506507 .igi (extractIgi (bidResponse ))
508+ .errors (errors )
507509 .build ();
508510 } catch (DecodeException | PreBidException e ) {
509511 return CompositeBidderResponse .withError (BidderError .badServerResponse (e .getMessage ()));
@@ -523,6 +525,7 @@ private List<BidderBid> bidsFromResponse(PubmaticBidResponse bidResponse, List<B
523525 .filter (Objects ::nonNull )
524526 .flatMap (Collection ::stream )
525527 .map (bid -> resolveBidderBid (bid , bidResponse .getCur (), bidderErrors ))
528+ .filter (Objects ::nonNull )
526529 .toList ();
527530 }
528531
@@ -533,21 +536,22 @@ private BidderBid resolveBidderBid(Bid bid, String currency, List<BidderError> b
533536 : null ;
534537
535538 final PubmaticBidExt pubmaticBidExt = parseBidExt (bid .getExt (), bidderErrors );
536- final Integer duration = getDuration (pubmaticBidExt );
537- final BidType bidType = getBidType (pubmaticBidExt );
539+ final BidType bidType = getBidType (bid , bidderErrors );
540+
541+ if (bidType == null ) {
542+ return null ;
543+ }
538544
539545 final String bidAdm = bid .getAdm ();
540546 final String resolvedAdm = bidAdm != null && bidType == BidType .xNative
541547 ? resolveNativeAdm (bidAdm , bidderErrors )
542548 : bidAdm ;
543549
544- final Bid updatedBid = firstCat != null || duration != null || resolvedAdm != null
545- ? bid .toBuilder ()
550+ final Bid updatedBid = bid .toBuilder ()
546551 .cat (firstCat )
547552 .adm (resolvedAdm != null ? resolvedAdm : bidAdm )
548- .ext (duration != null ? updateBidExtWithExtPrebid (duration , bid .getExt ()) : bid .getExt ())
549- .build ()
550- : bid ;
553+ .ext (updateBidExtWithExtPrebid (pubmaticBidExt , bidType , bid .getExt ()))
554+ .build ();
551555
552556 return BidderBid .builder ()
553557 .bid (updatedBid )
@@ -567,22 +571,17 @@ private PubmaticBidExt parseBidExt(ObjectNode bidExt, List<BidderError> errors)
567571 }
568572 }
569573
570- private static Integer getDuration (PubmaticBidExt bidExt ) {
571- return Optional .ofNullable (bidExt )
572- .map (PubmaticBidExt ::getVideo )
573- .map (VideoCreativeInfo ::getDuration )
574- .orElse (null );
575- }
576-
577- private static BidType getBidType (PubmaticBidExt bidExt ) {
578- final int bidType = Optional .ofNullable (bidExt )
579- .map (PubmaticBidExt ::getBidType )
580- .orElse (0 );
581-
582- return switch (bidType ) {
583- case 1 -> BidType .video ;
584- case 2 -> BidType .xNative ;
585- default -> BidType .banner ;
574+ private static BidType getBidType (Bid bid , List <BidderError > errors ) {
575+ return switch (bid .getMtype ()) {
576+ case 1 -> BidType .banner ;
577+ case 2 -> BidType .video ;
578+ case 3 -> BidType .audio ;
579+ case 4 -> BidType .xNative ;
580+ case null , default -> {
581+ errors .add (BidderError .badServerResponse ("failed to parse bid mtype (%d) for impression id %s"
582+ .formatted (bid .getMtype (), bid .getImpid ())));
583+ yield null ;
584+ }
586585 };
587586 }
588587
@@ -603,9 +602,33 @@ private String resolveNativeAdm(String adm, List<BidderError> bidderErrors) {
603602 return null ;
604603 }
605604
606- private ObjectNode updateBidExtWithExtPrebid (Integer duration , ObjectNode extBid ) {
607- final ExtBidPrebid extBidPrebid = ExtBidPrebid .builder ().video (ExtBidPrebidVideo .of (duration , null )).build ();
608- return extBid .set (PREBID , mapper .mapper ().valueToTree (extBidPrebid ));
605+ private ObjectNode updateBidExtWithExtPrebid (PubmaticBidExt pubmaticBidExt , BidType type , ObjectNode extBid ) {
606+ final Integer duration = getDuration (pubmaticBidExt );
607+ final boolean inBannerVideo = getInBannerVideo (pubmaticBidExt );
608+
609+ final ExtBidPrebid extBidPrebid = ExtBidPrebid .builder ()
610+ .video (duration != null ? ExtBidPrebidVideo .of (duration , null ) : null )
611+ .meta (ExtBidPrebidMeta .builder ()
612+ .mediaType (inBannerVideo ? BidType .video .getName () : type .getName ())
613+ .build ())
614+ .build ();
615+
616+ return extBid != null
617+ ? extBid .set (PREBID , mapper .mapper ().valueToTree (extBidPrebid ))
618+ : mapper .mapper ().createObjectNode ().set (PREBID , mapper .mapper ().valueToTree (extBidPrebid ));
619+ }
620+
621+ private static Integer getDuration (PubmaticBidExt bidExt ) {
622+ return Optional .ofNullable (bidExt )
623+ .map (PubmaticBidExt ::getVideo )
624+ .map (VideoCreativeInfo ::getDuration )
625+ .orElse (null );
626+ }
627+
628+ private static boolean getInBannerVideo (PubmaticBidExt bidExt ) {
629+ return Optional .ofNullable (bidExt )
630+ .map (PubmaticBidExt ::getInBannerVideo )
631+ .orElse (false );
609632 }
610633
611634 private static Integer getDealPriority (PubmaticBidExt bidExt ) {
0 commit comments