Skip to content
This repository has been archived by the owner on Dec 22, 2022. It is now read-only.

Commit

Permalink
[Sharethrough] Add new Sharethrough Adapter (prebid#903)
Browse files Browse the repository at this point in the history
* wip

* wip

* wip

* exploration for sharethrough prebid-server

* WIP: updating sharethrough adapter to latest prebid version

Co-authored-by: Chris Nguyen <cnguyen@sharethrough.com>

* WIP: adding butler params to the request

#164291358

Co-authored-by: Josh Becker <jbecker@sharethrough.com>

* Manage bid sizes

[#164291358]

Co-authored-by: Josh Becker <jbecker@sharethrough.com>

* Manage GDPR

[#164291358]

Co-authored-by: Josh Becker <jbecker@sharethrough.com>

* Populate prebid-server version if provided

[#164291358]

Co-authored-by: Josh Becker <jbecker@sharethrough.com>

* Refactor gdpr data extraction from request

[#164291358]

Co-authored-by: Eddy Pechuzal <epechuzal@sharethrough.com>

* Add instant play capability

[#164291358]

Co-authored-by: Eddy Pechuzal <epechuzal@sharethrough.com>

* Split in multiple files

[#164291358]

Co-authored-by: Eddy Pechuzal <epechuzal@sharethrough.com>

* Add s2s-win beacon
todo? replace server name by server id?

[#164291358]

Co-authored-by: Eddy Pechuzal <epechuzal@sharethrough.com>

* Removing `server` param in s2s-win beacon (will be added in imp req)

[#164291358]

* Clean up code + enable syncer (#4)

[#165257793]

* Proper error handling (#6)

* Proper error handling

[#165745574]

* Address review (baby clean up) + catch error that was missed

[#165745574]

* Implement Unit Tests (#7)

* Proper error handling

[#165745574]

* Address review (baby clean up) + catch error that was missed

[#165745574]

* Implement unit tests for utils

[#165891351]

* Add UT for utils + butler

[#165891351]

Co-authored-by: Michael Duran <mduran@sharethrough.com>

* Attempt for testing Bidder interface function implementations

[#165891351]

Co-authored-by: Michael Duran <mduran@sharethrough.com>

* Finalizing Unit tests

[#165891351]

Co-authored-by: Chris Nguyen <cnguyen@sharethrough.com>
Co-authored-by: Josh Becker <jbecker@sharethrough.com>

* Fixing sharethrough.yaml capabilities

[#165891351]

Co-authored-by: Josh Becker <jbecker@sharethrough.com>

* Send supplyId to imp req instead of hbSource (#5)

[#165477915]

* Finalize PR (#8)

[#164911891]

Co-authored-by: Josh Becker <jbecker@sharethrough.com>

* Remove test setting

* Add Sharethrough in syncer_test

* Update deserializing of third party partners

* Refactor/optimize UserAgent parsing (#9)

following josephveach's review in prebid#903

* Addressing June 3rd review from prebid#903

Optimizations, clean up suggested by @mansinahar

* Addressing June 4th review from prebid#903 (#10)

* Addressing June 4th review from prebid#903

Clean up canAutoPlayVideo + hardcode bhVersion to unknown for now...

* Removing hbVersion butler param since it's not accessible

* Fix adMarkup error handling
  • Loading branch information
maphe authored and hhhjort committed Jun 5, 2019
1 parent f9bcf84 commit ef433c9
Show file tree
Hide file tree
Showing 19 changed files with 1,758 additions and 0 deletions.
191 changes: 191 additions & 0 deletions adapters/sharethrough/butler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
package sharethrough

import (
"encoding/json"
"fmt"
"github.com/mxmCherry/openrtb"
"github.com/prebid/prebid-server/adapters"
"github.com/prebid/prebid-server/errortypes"
"github.com/prebid/prebid-server/openrtb_ext"
"net/http"
"net/url"
"regexp"
"strconv"
)

type StrAdSeverParams struct {
Pkey string
BidID string
ConsentRequired bool
ConsentString string
InstantPlayCapable bool
Iframe bool
Height uint64
Width uint64
}

type StrOpenRTBInterface interface {
requestFromOpenRTB(openrtb.Imp, *openrtb.BidRequest) (*adapters.RequestData, error)
responseToOpenRTB(openrtb_ext.ExtImpSharethroughResponse, *adapters.RequestData) (*adapters.BidderResponse, []error)
}

type StrAdServerUriInterface interface {
buildUri(StrAdSeverParams) string
parseUri(string) (*StrAdSeverParams, error)
}

type UserAgentParsers struct {
ChromeVersion *regexp.Regexp
ChromeiOSVersion *regexp.Regexp
SafariVersion *regexp.Regexp
}

type StrUriHelper struct {
BaseURI string
}

type StrOpenRTBTranslator struct {
UriHelper StrAdServerUriInterface
Util UtilityInterface
UserAgentParsers UserAgentParsers
}

func (s StrOpenRTBTranslator) requestFromOpenRTB(imp openrtb.Imp, request *openrtb.BidRequest) (*adapters.RequestData, error) {
headers := http.Header{}
headers.Add("Content-Type", "text/plain;charset=utf-8")
headers.Add("Accept", "application/json")

var strImpExt adapters.ExtImpBidder
if err := json.Unmarshal(imp.Ext, &strImpExt); err != nil {
return nil, err
}
var strImpParams openrtb_ext.ExtImpSharethroughExt
if err := json.Unmarshal(strImpExt.Bidder, &strImpParams); err != nil {
return nil, err
}

pKey := strImpParams.Pkey

var height, width uint64
if len(strImpParams.IframeSize) >= 2 {
height, width = uint64(strImpParams.IframeSize[0]), uint64(strImpParams.IframeSize[1])
} else {
height, width = s.Util.getPlacementSize(imp.Banner.Format)
}

return &adapters.RequestData{
Method: "POST",
Uri: s.UriHelper.buildUri(StrAdSeverParams{
Pkey: pKey,
BidID: imp.ID,
ConsentRequired: s.Util.gdprApplies(request),
ConsentString: s.Util.gdprConsentString(request),
Iframe: strImpParams.Iframe,
Height: height,
Width: width,
InstantPlayCapable: s.Util.canAutoPlayVideo(request.Device.UA, s.UserAgentParsers),
}),
Body: nil,
Headers: headers,
}, nil
}

func (s StrOpenRTBTranslator) responseToOpenRTB(strResp openrtb_ext.ExtImpSharethroughResponse, btlrReq *adapters.RequestData) (*adapters.BidderResponse, []error) {
var errs []error
bidResponse := adapters.NewBidderResponse()

bidResponse.Currency = "USD"
typedBid := &adapters.TypedBid{BidType: openrtb_ext.BidTypeNative}

if len(strResp.Creatives) == 0 {
errs = append(errs, &errortypes.BadInput{Message: "No creative provided"})
return nil, errs
}
creative := strResp.Creatives[0]

btlrParams, parseHBUriErr := s.UriHelper.parseUri(btlrReq.Uri)
if parseHBUriErr != nil {
errs = append(errs, &errortypes.BadInput{Message: parseHBUriErr.Error()})
return nil, errs
}

adm, admErr := s.Util.getAdMarkup(strResp, btlrParams)
if admErr != nil {
errs = append(errs, &errortypes.BadServerResponse{Message: admErr.Error()})
return nil, errs
}

bid := &openrtb.Bid{
AdID: strResp.AdServerRequestID,
ID: strResp.BidID,
ImpID: btlrParams.BidID,
Price: creative.CPM,
CID: creative.Metadata.CampaignKey,
CrID: creative.Metadata.CreativeKey,
DealID: creative.Metadata.DealID,
AdM: adm,
H: btlrParams.Height,
W: btlrParams.Width,
}

typedBid.Bid = bid
bidResponse.Bids = append(bidResponse.Bids, typedBid)

return bidResponse, errs
}

func (h StrUriHelper) buildUri(params StrAdSeverParams) string {
v := url.Values{}
v.Set("placement_key", params.Pkey)
v.Set("bidId", params.BidID)
v.Set("consent_required", fmt.Sprintf("%t", params.ConsentRequired))
v.Set("consent_string", params.ConsentString)

v.Set("instant_play_capable", fmt.Sprintf("%t", params.InstantPlayCapable))
v.Set("stayInIframe", fmt.Sprintf("%t", params.Iframe))
v.Set("height", strconv.FormatUint(params.Height, 10))
v.Set("width", strconv.FormatUint(params.Width, 10))

v.Set("supplyId", supplyId)
v.Set("strVersion", strVersion)

return h.BaseURI + "?" + v.Encode()
}

func (h StrUriHelper) parseUri(uri string) (*StrAdSeverParams, error) {
btlrUrl, err := url.Parse(uri)
if err != nil {
return nil, err
}

params := btlrUrl.Query()
height, err := strconv.ParseUint(params.Get("height"), 10, 64)
if err != nil {
return nil, err
}

width, err := strconv.ParseUint(params.Get("width"), 10, 64)
if err != nil {
return nil, err
}

stayInIframe, err := strconv.ParseBool(params.Get("stayInIframe"))
if err != nil {
stayInIframe = false
}

consentRequired, err := strconv.ParseBool(params.Get("consent_required"))
if err != nil {
consentRequired = false
}

return &StrAdSeverParams{
Pkey: params.Get("placement_key"),
BidID: params.Get("bidId"),
Iframe: stayInIframe,
Height: height,
Width: width,
ConsentRequired: consentRequired,
ConsentString: params.Get("consent_string"),
}, nil
}
Loading

0 comments on commit ef433c9

Please sign in to comment.