diff --git a/adapters/intertech/intertech.go b/adapters/intertech/intertech.go
new file mode 100644
index 00000000000..ae491995a76
--- /dev/null
+++ b/adapters/intertech/intertech.go
@@ -0,0 +1,226 @@
+package intertech
+
+import (
+ "fmt"
+ "net/http"
+ "net/url"
+ "strconv"
+ "strings"
+
+ "github.com/prebid/openrtb/v20/openrtb2"
+ "github.com/prebid/prebid-server/v3/adapters"
+ "github.com/prebid/prebid-server/v3/config"
+ "github.com/prebid/prebid-server/v3/errortypes"
+ "github.com/prebid/prebid-server/v3/openrtb_ext"
+ "github.com/prebid/prebid-server/v3/util/jsonutil"
+)
+
+const (
+ pageIDMacro = "{{page_id}}"
+ impIDMacro = "{{imp_id}}"
+)
+
+type adapter struct {
+ endpoint string
+}
+
+func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) {
+ bidder := &adapter{
+ endpoint: config.Endpoint,
+ }
+ return bidder, nil
+}
+
+func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
+ var errs []error
+ var requests []*adapters.RequestData
+
+ referer := getReferer(request)
+ cur := getCur(request)
+
+ for _, imp := range request.Imp {
+ extImp, err := parseAndValidateImpExt(imp)
+ if err != nil {
+ errs = append(errs, err)
+ continue
+ }
+
+ modifiedImp, err := modifyImp(imp)
+ if err != nil {
+ errs = append(errs, err)
+ continue
+ }
+
+ modifiedUrl := a.modifyUrl(extImp, referer, cur)
+
+ modRequest := *request
+ modRequest.Imp = []openrtb2.Imp{modifiedImp}
+
+ reqData, err := buildRequestData(modRequest, modifiedUrl)
+ if err != nil {
+ errs = append(errs, err)
+ continue
+ }
+
+ requests = append(requests, reqData)
+ }
+
+ return requests, errs
+}
+
+func parseAndValidateImpExt(imp openrtb2.Imp) (openrtb_ext.ExtImpIntertech, error) {
+ var bidderExt adapters.ExtImpBidder
+ if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil {
+ return openrtb_ext.ExtImpIntertech{}, &errortypes.BadInput{
+ Message: fmt.Sprintf("imp #%s: unable to parse bidder ext: %s", imp.ID, err),
+ }
+ }
+
+ var extImp openrtb_ext.ExtImpIntertech
+ if err := jsonutil.Unmarshal(bidderExt.Bidder, &extImp); err != nil {
+ return openrtb_ext.ExtImpIntertech{}, &errortypes.BadInput{
+ Message: fmt.Sprintf("imp #%s: unable to parse intertech ext: %s", imp.ID, err),
+ }
+ }
+
+ return extImp, nil
+}
+
+func modifyImp(imp openrtb2.Imp) (openrtb2.Imp, error) {
+ if imp.Banner != nil {
+ banner, err := updateBanner(imp.Banner)
+ if err != nil {
+ return openrtb2.Imp{}, &errortypes.BadInput{
+ Message: fmt.Sprintf("imp #%s: %s", imp.ID, err.Error()),
+ }
+ }
+ imp.Banner = banner
+ }
+ return imp, nil
+}
+
+func updateBanner(banner *openrtb2.Banner) (*openrtb2.Banner, error) {
+ bannerCopy := *banner
+ if bannerCopy.W == nil || bannerCopy.H == nil || *bannerCopy.W == 0 || *bannerCopy.H == 0 {
+ if len(bannerCopy.Format) > 0 {
+ w := bannerCopy.Format[0].W
+ h := bannerCopy.Format[0].H
+ bannerCopy.W = &w
+ bannerCopy.H = &h
+ } else {
+ return nil, fmt.Errorf("Invalid sizes provided for Banner")
+ }
+ }
+ return &bannerCopy, nil
+}
+
+func (a *adapter) modifyUrl(extImp openrtb_ext.ExtImpIntertech, referer, cur string) string {
+ pageStr := strconv.Itoa(extImp.PageID)
+ impStr := strconv.Itoa(extImp.ImpID)
+
+ resolvedUrl := strings.ReplaceAll(a.endpoint, pageIDMacro, url.QueryEscape(pageStr))
+ resolvedUrl = strings.ReplaceAll(resolvedUrl, impIDMacro, url.QueryEscape(impStr))
+
+ if referer != "" {
+ resolvedUrl += "&target-ref=" + url.QueryEscape(referer)
+ }
+
+ if cur != "" {
+ resolvedUrl += "&ssp-cur=" + cur
+ }
+
+ return resolvedUrl
+}
+
+func buildRequestData(bidRequest openrtb2.BidRequest, uri string) (*adapters.RequestData, error) {
+ body, err := jsonutil.Marshal(bidRequest)
+ if err != nil {
+ return nil, err
+ }
+
+ headers := http.Header{}
+ headers.Add("Content-Type", "application/json;charset=utf-8")
+ headers.Add("Accept", "application/json")
+
+ if bidRequest.Device != nil {
+ if bidRequest.Device.UA != "" {
+ headers.Add("User-Agent", bidRequest.Device.UA)
+ }
+ if bidRequest.Device.IP != "" {
+ headers.Add("X-Forwarded-For", bidRequest.Device.IP)
+ headers.Add("X-Real-Ip", bidRequest.Device.IP)
+ }
+ if bidRequest.Device.Language != "" {
+ headers.Add("Accept-Language", bidRequest.Device.Language)
+ }
+ }
+ return &adapters.RequestData{
+ Method: http.MethodPost,
+ Uri: uri,
+ Body: body,
+ Headers: headers,
+ ImpIDs: openrtb_ext.GetImpIDs(bidRequest.Imp),
+ }, nil
+}
+
+func getReferer(request *openrtb2.BidRequest) string {
+ if request.Site != nil {
+ return request.Site.Page
+ }
+ return ""
+}
+
+func getCur(request *openrtb2.BidRequest) string {
+ if len(request.Cur) > 0 {
+ return request.Cur[0]
+ }
+ return ""
+}
+
+func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) {
+ if adapters.IsResponseStatusCodeNoContent(responseData) {
+ return nil, nil
+ }
+
+ if err := adapters.CheckResponseStatusCodeForErrors(responseData); err != nil {
+ return nil, []error{err}
+ }
+
+ var response openrtb2.BidResponse
+ if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil {
+ return nil, []error{err}
+ }
+
+ bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp))
+ if len(response.Cur) != 0 {
+ bidResponse.Currency = response.Cur
+ }
+
+ for _, seatBid := range response.SeatBid {
+ for i := range seatBid.Bid {
+ bid := seatBid.Bid[i]
+ bidType, err := getBidType(bid)
+ if err != nil {
+ return nil, []error{err}
+ }
+
+ b := &adapters.TypedBid{
+ Bid: &seatBid.Bid[i],
+ BidType: bidType,
+ }
+ bidResponse.Bids = append(bidResponse.Bids, b)
+ }
+ }
+ return bidResponse, nil
+}
+
+func getBidType(bid openrtb2.Bid) (openrtb_ext.BidType, error) {
+ switch bid.MType {
+ case openrtb2.MarkupBanner:
+ return openrtb_ext.BidTypeBanner, nil
+ case openrtb2.MarkupNative:
+ return openrtb_ext.BidTypeNative, nil
+ }
+
+ return "", fmt.Errorf("could not define media type for impression: %s", bid.ImpID)
+}
diff --git a/adapters/intertech/intertech_test.go b/adapters/intertech/intertech_test.go
new file mode 100644
index 00000000000..952b2a4431c
--- /dev/null
+++ b/adapters/intertech/intertech_test.go
@@ -0,0 +1,21 @@
+package intertech
+
+import (
+ "testing"
+
+ "github.com/prebid/prebid-server/v3/adapters/adapterstest"
+ "github.com/prebid/prebid-server/v3/config"
+ "github.com/prebid/prebid-server/v3/openrtb_ext"
+)
+
+func TestJsonSamples(t *testing.T) {
+ bidder, buildErr := Builder(openrtb_ext.BidderIntertech, config.Adapter{
+ Endpoint: "https://test.intertech.com/ssp?pid={{page_id}}&imp={{imp_id}}"}, config.Server{
+ ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"})
+
+ if buildErr != nil {
+ t.Fatalf("Builder returned unexpected error %v", buildErr)
+ }
+
+ adapterstest.RunJSONBidderTest(t, "intertechtest", bidder)
+}
diff --git a/adapters/intertech/intertechtest/exemplary/simple-banner-muli-format.json b/adapters/intertech/intertechtest/exemplary/simple-banner-muli-format.json
new file mode 100644
index 00000000000..39f12626289
--- /dev/null
+++ b/adapters/intertech/intertechtest/exemplary/simple-banner-muli-format.json
@@ -0,0 +1,115 @@
+{
+ "mockBidRequest": {
+ "id": "request-id-1",
+ "device": {
+ "ip": "123.123.123.123",
+ "ua": "Mozilla/5.0 (X11; Linux x86_64)"
+ },
+ "site": {
+ "page": "http://bannercheck.com"
+ },
+ "imp": [
+ {
+ "id": "imp-id-1",
+ "tagid": "tag-id-1",
+ "banner": {
+ "format": [
+ { "w": 728, "h": 90 },
+ { "w": 300, "h": 250 }
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "page_id": 1111,
+ "imp_id": 2222
+ }
+ }
+ }
+ ],
+ "cur": ["USD"]
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "https://test.intertech.com/ssp?pid=1111&imp=2222&target-ref=http%3A%2F%2Fbannercheck.com&ssp-cur=USD",
+ "body": {
+ "id": "request-id-1",
+ "imp": [
+ {
+ "id": "imp-id-1",
+ "tagid": "tag-id-1",
+ "banner": {
+ "w": 728,
+ "h": 90,
+ "format": [
+ { "w": 728, "h": 90 },
+ { "w": 300, "h": 250 }
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "page_id": 1111,
+ "imp_id": 2222
+ }
+ }
+ }
+ ],
+ "site": {
+ "page": "http://bannercheck.com"
+ },
+ "device": {
+ "ip": "123.123.123.123",
+ "ua": "Mozilla/5.0 (X11; Linux x86_64)"
+ },
+ "cur": ["USD"]
+ },
+ "impIDs": ["imp-id-1"]
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "request-id-1",
+ "cur": "USD",
+ "seatbid": [
+ {
+ "seat": "intertech",
+ "bid": [
+ {
+ "id": "bid-id-1",
+ "impid": "imp-id-1",
+ "price": 0.7,
+ "adm": "
Test Banner 728x90
",
+ "cid": "campaign-id-1",
+ "crid": "creative-id-1",
+ "w": 728,
+ "h": 90,
+ "mtype": 1
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ ],
+ "expectedBidResponses": [
+ {
+ "bids": [
+ {
+ "bid": {
+ "id": "bid-id-1",
+ "impid": "imp-id-1",
+ "price": 0.7,
+ "adm": "Test Banner 728x90
",
+ "cid": "campaign-id-1",
+ "crid": "creative-id-1",
+ "w": 728,
+ "h": 90,
+ "mtype": 1
+ },
+ "type": "banner"
+ }
+ ]
+ }
+ ]
+}
diff --git a/adapters/intertech/intertechtest/exemplary/simple-banner.json b/adapters/intertech/intertechtest/exemplary/simple-banner.json
new file mode 100644
index 00000000000..dc0473465af
--- /dev/null
+++ b/adapters/intertech/intertechtest/exemplary/simple-banner.json
@@ -0,0 +1,119 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "device": {
+ "ip": "123.123.123.123",
+ "ua": "Mozilla/5.0 (iPad; CPU OS 10_3 like Mac OS X)",
+ "language": "en-US"
+ },
+ "site": {
+ "page": "mypage"
+ },
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "tagid": "test-tag",
+ "banner": {
+ "w": 300,
+ "h": 250
+ },
+ "ext": {
+ "bidder": {
+ "page_id": 1001,
+ "imp_id": 2002
+ }
+ }
+ }
+ ],
+ "cur": ["USD"]
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "https://test.intertech.com/ssp?pid=1001&imp=2002&target-ref=mypage&ssp-cur=USD",
+ "headers": {
+ "Content-Type": ["application/json;charset=utf-8"],
+ "Accept": ["application/json"],
+ "Accept-Language": ["en-US"],
+ "User-Agent": ["Mozilla/5.0 (iPad; CPU OS 10_3 like Mac OS X)"],
+ "X-Forwarded-For": ["123.123.123.123"],
+ "X-Real-Ip": ["123.123.123.123"]
+ },
+ "body": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "tagid": "test-tag",
+ "banner": {
+ "w": 300,
+ "h": 250
+ },
+ "ext": {
+ "bidder": {
+ "page_id": 1001,
+ "imp_id": 2002
+ }
+ }
+ }
+ ],
+ "site": {
+ "page": "mypage"
+ },
+ "device": {
+ "ip": "123.123.123.123",
+ "ua": "Mozilla/5.0 (iPad; CPU OS 10_3 like Mac OS X)",
+ "language": "en-US"
+ },
+ "cur": ["USD"]
+ },
+ "impIDs": ["test-imp-id"]
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "test-request-id",
+ "cur": "USD",
+ "seatbid": [
+ {
+ "seat": "intertech",
+ "bid": [
+ {
+ "id": "test_bid_id",
+ "impid": "test-imp-id",
+ "price": 0.5,
+ "adm": "Test Ad
",
+ "cid": "test_cid",
+ "crid": "test_crid",
+ "w": 300,
+ "h": 250,
+ "mtype": 1
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ ],
+ "expectedBidResponses": [
+ {
+ "bids": [
+ {
+ "bid": {
+ "id": "test_bid_id",
+ "impid": "test-imp-id",
+ "price": 0.5,
+ "adm": "Test Ad
",
+ "cid": "test_cid",
+ "crid": "test_crid",
+ "w": 300,
+ "h": 250,
+ "mtype": 1
+ },
+ "type": "banner"
+ }
+ ]
+ }
+ ]
+}
diff --git a/adapters/intertech/intertechtest/exemplary/simple-native.json b/adapters/intertech/intertechtest/exemplary/simple-native.json
new file mode 100644
index 00000000000..a9336b8ffb1
--- /dev/null
+++ b/adapters/intertech/intertechtest/exemplary/simple-native.json
@@ -0,0 +1,103 @@
+{
+ "mockBidRequest": {
+ "id": "test-native-request-id",
+ "device": {
+ "ip": "123.123.123.123",
+ "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X)"
+ },
+ "site": {
+ "page": "nativepage"
+ },
+ "imp": [
+ {
+ "id": "test-native-imp-id",
+ "tagid": "test-native-tag",
+ "native": {
+ "request": "{\"ver\":\"1.2\",\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":25}}],\"eventtrackers\":[{\"event\":1,\"method\":1}],\"ver\":\"1.2\"}"
+ },
+ "ext": {
+ "bidder": {
+ "page_id": 3003,
+ "imp_id": 4004
+ }
+ }
+ }
+ ],
+ "cur": ["USD"]
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "https://test.intertech.com/ssp?pid=3003&imp=4004&target-ref=nativepage&ssp-cur=USD",
+ "body": {
+ "id": "test-native-request-id",
+ "imp": [
+ {
+ "id": "test-native-imp-id",
+ "tagid": "test-native-tag",
+ "native": {
+ "request": "{\"ver\":\"1.2\",\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":25}}],\"eventtrackers\":[{\"event\":1,\"method\":1}],\"ver\":\"1.2\"}"
+ },
+ "ext": {
+ "bidder": {
+ "page_id": 3003,
+ "imp_id": 4004
+ }
+ }
+ }
+ ],
+ "site": {
+ "page": "nativepage"
+ },
+ "device": {
+ "ip": "123.123.123.123",
+ "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X)"
+ },
+ "cur": ["USD"]
+ },
+ "impIDs": ["test-native-imp-id"]
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "test-native-request-id",
+ "cur": "USD",
+ "seatbid": [
+ {
+ "seat": "intertech",
+ "bid": [
+ {
+ "id": "test_native_bid_id",
+ "impid": "test-native-imp-id",
+ "price": 1.0,
+ "adm": "{\"native\":{\"ver\":\"1.2\",\"assets\":[{\"id\":1,\"title\":{\"text\":\"Test Native Title\"}}],\"link\":{\"url\":\"http://example.com\"},\"imptrackers\":[\"http://example.com/imp\"]}}",
+ "cid": "test_native_cid",
+ "crid": "test_native_crid",
+ "mtype": 4
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ ],
+ "expectedBidResponses": [
+ {
+ "bids": [
+ {
+ "bid": {
+ "id": "test_native_bid_id",
+ "impid": "test-native-imp-id",
+ "price": 1.0,
+ "adm": "{\"native\":{\"ver\":\"1.2\",\"assets\":[{\"id\":1,\"title\":{\"text\":\"Test Native Title\"}}],\"link\":{\"url\":\"http://example.com\"},\"imptrackers\":[\"http://example.com/imp\"]}}",
+ "cid": "test_native_cid",
+ "crid": "test_native_crid",
+ "mtype": 4
+ },
+ "type": "native"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/adapters/intertech/intertechtest/supplemental/bad_media_type.json b/adapters/intertech/intertechtest/supplemental/bad_media_type.json
new file mode 100644
index 00000000000..4e1074f136c
--- /dev/null
+++ b/adapters/intertech/intertechtest/supplemental/bad_media_type.json
@@ -0,0 +1,100 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "device": {
+ "ip": "123.123.123.123",
+ "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
+ },
+ "site": {
+ "page": "http://example.com"
+ },
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "tagid": "test-tag",
+ "banner": {
+ "format": [
+ { "w": 300, "h": 250 }
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "page_id": 3003,
+ "imp_id": 5005
+ }
+ }
+ }
+ ],
+ "cur": ["USD"]
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "https://test.intertech.com/ssp?pid=3003&imp=5005&target-ref=http%3A%2F%2Fexample.com&ssp-cur=USD",
+ "body": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "tagid": "test-tag",
+ "banner": {
+ "w": 300,
+ "h": 250,
+ "format": [
+ { "w": 300, "h": 250 }
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "page_id": 3003,
+ "imp_id": 5005
+ }
+ }
+ }
+ ],
+ "site": {
+ "page": "http://example.com"
+ },
+ "device": {
+ "ip": "123.123.123.123",
+ "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
+ },
+ "cur": ["USD"]
+ },
+ "impIDs": ["test-imp-id"]
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "test-request-id",
+ "cur": "USD",
+ "seatbid": [
+ {
+ "seat": "intertech",
+ "bid": [
+ {
+ "id": "test_bid_id",
+ "impid": "test-imp-id",
+ "price": 0.5,
+ "adm": "Test Ad
",
+ "cid": "test_cid",
+ "crid": "test_crid",
+ "w": 300,
+ "h": 250,
+ "mtype": 2
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ ],
+ "expectedMakeBidsErrors": [
+ {
+ "value": "could not define media type for impression: test-imp-id",
+ "comparison": "literal"
+ }
+ ]
+ }
+
\ No newline at end of file
diff --git a/adapters/intertech/intertechtest/supplemental/bad_response.json b/adapters/intertech/intertechtest/supplemental/bad_response.json
new file mode 100644
index 00000000000..6ca58d71dd9
--- /dev/null
+++ b/adapters/intertech/intertechtest/supplemental/bad_response.json
@@ -0,0 +1,79 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "device": {
+ "ip": "123.123.123.123",
+ "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
+ },
+ "site": {
+ "page": "http://example.com"
+ },
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "tagid": "test-tag",
+ "banner": {
+ "format": [
+ { "w": 300, "h": 250 }
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "page_id": 1001,
+ "imp_id": 2002
+ }
+ }
+ }
+ ],
+ "cur": ["USD"]
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "https://test.intertech.com/ssp?pid=1001&imp=2002&target-ref=http%3A%2F%2Fexample.com&ssp-cur=USD",
+ "body": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "tagid": "test-tag",
+ "banner": {
+ "w": 300,
+ "h": 250,
+ "format": [
+ { "w": 300, "h": 250 }
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "page_id": 1001,
+ "imp_id": 2002
+ }
+ }
+ }
+ ],
+ "site": {
+ "page": "http://example.com"
+ },
+ "device": {
+ "ip": "123.123.123.123",
+ "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
+ },
+ "cur": ["USD"]
+ },
+ "impIDs": ["test-imp-id"]
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": ""
+ }
+ }
+ ],
+ "expectedMakeBidsErrors": [
+ {
+ "value": "expect { or n, but found \"",
+ "comparison": "literal"
+ }
+ ]
+ }
+
\ No newline at end of file
diff --git a/adapters/intertech/intertechtest/supplemental/invalid-banner-size.json b/adapters/intertech/intertechtest/supplemental/invalid-banner-size.json
new file mode 100644
index 00000000000..49d6a4996cf
--- /dev/null
+++ b/adapters/intertech/intertechtest/supplemental/invalid-banner-size.json
@@ -0,0 +1,35 @@
+{
+ "mockBidRequest": {
+ "id": "test-invalid-sizes-request-id",
+ "device": {
+ "ip": "123.123.123.123",
+ "ua": "Mozilla/5.0 (X11; Linux x86_64)"
+ },
+ "site": {
+ "page": "http://no-size-banner.com"
+ },
+ "imp": [
+ {
+ "id": "test-imp-no-size",
+ "tagid": "no-size-tag",
+ "banner": {
+ "format": []
+ },
+ "ext": {
+ "bidder": {
+ "page_id": 1111,
+ "imp_id": 9999
+ }
+ }
+ }
+ ],
+ "cur": ["USD"]
+ },
+ "httpCalls": [],
+ "expectedMakeRequestsErrors": [
+ {
+ "value": "imp #test-imp-no-size: Invalid sizes provided for Banner",
+ "comparison": "literal"
+ }
+ ]
+}
diff --git a/adapters/intertech/intertechtest/supplemental/invalid-bidder.json b/adapters/intertech/intertechtest/supplemental/invalid-bidder.json
new file mode 100644
index 00000000000..0f530a0e68c
--- /dev/null
+++ b/adapters/intertech/intertechtest/supplemental/invalid-bidder.json
@@ -0,0 +1,28 @@
+{
+ "mockBidRequest": {
+ "id": "test-req-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "format": [
+ {
+ "w": 300,
+ "h": 250
+ }
+ ]
+ },
+ "ext": {
+ "bidder": "badBidder"
+ }
+ }
+ ]
+ },
+
+ "expectedMakeRequestsErrors": [
+ {
+ "value": "imp #test-imp-id: unable to parse intertech ext: expect { or n, but found \"",
+ "comparison": "literal"
+ }
+ ]
+}
diff --git a/adapters/intertech/intertechtest/supplemental/invalid-ext.json b/adapters/intertech/intertechtest/supplemental/invalid-ext.json
new file mode 100644
index 00000000000..4c8eb9c9c7c
--- /dev/null
+++ b/adapters/intertech/intertechtest/supplemental/invalid-ext.json
@@ -0,0 +1,30 @@
+{
+ "mockBidRequest": {
+ "id": "test-req-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "format": [
+ {
+ "w": 300,
+ "h": 250
+ }
+ ]
+ },
+ "ext": 123
+ }
+ ]
+ },
+
+ "httpCalls": [],
+
+ "expectedBidResponses": [],
+
+ "expectedMakeRequestsErrors": [
+ {
+ "value": "imp #test-imp-id: unable to parse bidder ext: expect { or n, but found 1",
+ "comparison": "literal"
+ }
+ ]
+}
diff --git a/adapters/intertech/intertechtest/supplemental/no-cur-req.json b/adapters/intertech/intertechtest/supplemental/no-cur-req.json
new file mode 100644
index 00000000000..a6101b6023c
--- /dev/null
+++ b/adapters/intertech/intertechtest/supplemental/no-cur-req.json
@@ -0,0 +1,71 @@
+{
+ "mockBidRequest": {
+ "id": "test-no-cur-request-id",
+ "device": {
+ "ip": "123.123.123.123",
+ "ua": "Mozilla/5.0 (X11; Linux x86_64)"
+ },
+ "site": {
+ "page": "http://example-nocur.com"
+ },
+ "imp": [
+ {
+ "id": "test-imp-no-cur",
+ "tagid": "no-cur-tag",
+ "banner": {
+ "format": [
+ { "w": 300, "h": 250 }
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "page_id": 1111,
+ "imp_id": 2222
+ }
+ }
+ }
+ ]
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "https://test.intertech.com/ssp?pid=1111&imp=2222&target-ref=http%3A%2F%2Fexample-nocur.com",
+ "body": {
+ "id": "test-no-cur-request-id",
+ "imp": [
+ {
+ "id": "test-imp-no-cur",
+ "tagid": "no-cur-tag",
+ "banner": {
+ "w": 300,
+ "h": 250,
+ "format": [
+ { "w": 300, "h": 250 }
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "page_id": 1111,
+ "imp_id": 2222
+ }
+ }
+ }
+ ],
+ "site": {
+ "page": "http://example-nocur.com"
+ },
+ "device": {
+ "ip": "123.123.123.123",
+ "ua": "Mozilla/5.0 (X11; Linux x86_64)"
+ }
+ },
+ "impIDs": ["test-imp-no-cur"]
+ },
+ "mockResponse": {
+ "status": 204,
+ "body": {}
+ }
+ }
+ ],
+ "expectedBidResponses": []
+}
diff --git a/adapters/intertech/intertechtest/supplemental/no-device.json b/adapters/intertech/intertechtest/supplemental/no-device.json
new file mode 100644
index 00000000000..8f811e0709c
--- /dev/null
+++ b/adapters/intertech/intertechtest/supplemental/no-device.json
@@ -0,0 +1,105 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-no-device",
+ "site": {
+ "page": "mypage"
+ },
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "tagid": "test-tag",
+ "banner": {
+ "w": 300,
+ "h": 250
+ },
+ "ext": {
+ "bidder": {
+ "page_id": 1001,
+ "imp_id": 2002
+ }
+ }
+ }
+ ],
+ "cur": ["USD"]
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "https://test.intertech.com/ssp?pid=1001&imp=2002&target-ref=mypage&ssp-cur=USD",
+ "headers": {
+ "Content-Type": ["application/json;charset=utf-8"],
+ "Accept": ["application/json"]
+ },
+ "body": {
+ "id": "test-request-no-device",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "tagid": "test-tag",
+ "banner": {
+ "w": 300,
+ "h": 250
+ },
+ "ext": {
+ "bidder": {
+ "page_id": 1001,
+ "imp_id": 2002
+ }
+ }
+ }
+ ],
+ "site": {
+ "page": "mypage"
+ },
+ "cur": ["USD"]
+ },
+ "impIDs": ["test-imp-id"]
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "test-request-no-device",
+ "cur": "USD",
+ "seatbid": [
+ {
+ "seat": "intertech",
+ "bid": [
+ {
+ "id": "test_bid_id",
+ "impid": "test-imp-id",
+ "price": 0.5,
+ "adm": "Test Ad
",
+ "cid": "test_cid",
+ "crid": "test_crid",
+ "w": 300,
+ "h": 250,
+ "mtype": 1
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ ],
+ "expectedBidResponses": [
+ {
+ "bids": [
+ {
+ "bid": {
+ "id": "test_bid_id",
+ "impid": "test-imp-id",
+ "price": 0.5,
+ "adm": "Test Ad
",
+ "cid": "test_cid",
+ "crid": "test_crid",
+ "w": 300,
+ "h": 250,
+ "mtype": 1
+ },
+ "type": "banner"
+ }
+ ]
+ }
+ ]
+}
diff --git a/adapters/intertech/intertechtest/supplemental/no-site-req.json b/adapters/intertech/intertechtest/supplemental/no-site-req.json
new file mode 100644
index 00000000000..9d4901994bb
--- /dev/null
+++ b/adapters/intertech/intertechtest/supplemental/no-site-req.json
@@ -0,0 +1,67 @@
+{
+ "mockBidRequest": {
+ "id": "test-no-site-request-id",
+ "device": {
+ "ip": "123.123.123.123",
+ "ua": "Mozilla/5.0 (X11; Linux x86_64)"
+ },
+ "imp": [
+ {
+ "id": "test-imp-no-site",
+ "tagid": "no-site-tag",
+ "banner": {
+ "format": [
+ { "w": 300, "h": 250 }
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "page_id": 3003,
+ "imp_id": 5005
+ }
+ }
+ }
+ ],
+ "cur": ["USD"]
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "https://test.intertech.com/ssp?pid=3003&imp=5005&ssp-cur=USD",
+ "body": {
+ "id": "test-no-site-request-id",
+ "imp": [
+ {
+ "id": "test-imp-no-site",
+ "tagid": "no-site-tag",
+ "banner": {
+ "w": 300,
+ "h": 250,
+ "format": [
+ { "w": 300, "h": 250 }
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "page_id": 3003,
+ "imp_id": 5005
+ }
+ }
+ }
+ ],
+ "device": {
+ "ip": "123.123.123.123",
+ "ua": "Mozilla/5.0 (X11; Linux x86_64)"
+ },
+ "cur": ["USD"]
+ },
+ "impIDs": ["test-imp-no-site"]
+ },
+ "mockResponse": {
+ "status": 204,
+ "body": {}
+ }
+ }
+ ],
+ "expectedBidResponses": []
+}
diff --git a/adapters/intertech/intertechtest/supplemental/status-204.json b/adapters/intertech/intertechtest/supplemental/status-204.json
new file mode 100644
index 00000000000..8225c9ea57d
--- /dev/null
+++ b/adapters/intertech/intertechtest/supplemental/status-204.json
@@ -0,0 +1,73 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "device": {
+ "ip": "123.123.123.123",
+ "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
+ },
+ "site": {
+ "page": "http://example.com"
+ },
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "tagid": "test-tag",
+ "banner": {
+ "format": [
+ { "w": 300, "h": 250 }
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "page_id": 1001,
+ "imp_id": 2002
+ }
+ }
+ }
+ ],
+ "cur": ["USD"]
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "https://test.intertech.com/ssp?pid=1001&imp=2002&target-ref=http%3A%2F%2Fexample.com&ssp-cur=USD",
+ "body": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "tagid": "test-tag",
+ "banner": {
+ "w": 300,
+ "h": 250,
+ "format": [
+ { "w": 300, "h": 250 }
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "page_id": 1001,
+ "imp_id": 2002
+ }
+ }
+ }
+ ],
+ "site": {
+ "page": "http://example.com"
+ },
+ "device": {
+ "ip": "123.123.123.123",
+ "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
+ },
+ "cur": ["USD"]
+ },
+ "impIDs": ["test-imp-id"]
+ },
+ "mockResponse": {
+ "status": 204,
+ "body": {}
+ }
+ }
+ ],
+ "expectedBidResponses": []
+}
diff --git a/adapters/intertech/intertechtest/supplemental/status-not-200.json b/adapters/intertech/intertechtest/supplemental/status-not-200.json
new file mode 100644
index 00000000000..58317e359fd
--- /dev/null
+++ b/adapters/intertech/intertechtest/supplemental/status-not-200.json
@@ -0,0 +1,78 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "device": {
+ "ip": "123.123.123.123",
+ "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
+ },
+ "site": {
+ "page": "http://mypage.com"
+ },
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "tagid": "test-tag",
+ "banner": {
+ "format": [
+ { "w": 300, "h": 250 }
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "page_id": 1001,
+ "imp_id": 2002
+ }
+ }
+ }
+ ],
+ "cur": ["USD"]
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "https://test.intertech.com/ssp?pid=1001&imp=2002&target-ref=http%3A%2F%2Fmypage.com&ssp-cur=USD",
+ "body": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "tagid": "test-tag",
+ "banner": {
+ "w": 300,
+ "h": 250,
+ "format": [
+ { "w": 300, "h": 250 }
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "page_id": 1001,
+ "imp_id": 2002
+ }
+ }
+ }
+ ],
+ "site": {
+ "page": "http://mypage.com"
+ },
+ "device": {
+ "ip": "123.123.123.123",
+ "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
+ },
+ "cur": ["USD"]
+ },
+ "impIDs": ["test-imp-id"]
+ },
+ "mockResponse": {
+ "status": 404,
+ "body": {}
+ }
+ }
+ ],
+ "expectedMakeBidsErrors": [
+ {
+ "value": "Unexpected status code: 404. Run with request.debug = 1 for more info",
+ "comparison": "literal"
+ }
+ ]
+}
diff --git a/adapters/intertech/params_test.go b/adapters/intertech/params_test.go
new file mode 100644
index 00000000000..eb7bb0aba4e
--- /dev/null
+++ b/adapters/intertech/params_test.go
@@ -0,0 +1,48 @@
+package intertech
+
+import (
+ "encoding/json"
+ "testing"
+
+ "github.com/prebid/prebid-server/v3/openrtb_ext"
+)
+
+func TestValidParams(t *testing.T) {
+ validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params")
+ if err != nil {
+ t.Fatalf("Failed to fetch the json schema. %v", err)
+ }
+
+ for _, p := range validParams {
+ if err := validator.Validate(openrtb_ext.BidderIntertech, json.RawMessage(p)); err != nil {
+ t.Errorf("Schema rejected valid params: %s", p)
+ }
+ }
+}
+
+func TestInvalidParams(t *testing.T) {
+ validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params")
+ if err != nil {
+ t.Fatalf("Failed to fetch the json schema. %v", err)
+ }
+
+ for _, p := range invalidParams {
+ if err := validator.Validate(openrtb_ext.BidderIntertech, json.RawMessage(p)); err == nil {
+ t.Errorf("Schema allowed invalid params: %s", p)
+ }
+ }
+}
+
+var validParams = []string{
+ `{"page_id": 123, "imp_id": 456}`,
+ `{"page_id": 1, "imp_id": 1}`,
+ `{"page_id": 999, "imp_id": 999}`,
+}
+
+var invalidParams = []string{
+ `{"page_id": "abc", "imp_id": 1}`,
+ `{"page_id": "1", "imp_id": abc}`,
+ `{"page_id": "123123"}`,
+ `{"imp_id": "123"}`,
+ `{}`,
+}
diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go
index 67e28286f03..a0f0ada560d 100755
--- a/exchange/adapter_builders.go
+++ b/exchange/adapter_builders.go
@@ -110,6 +110,7 @@ import (
"github.com/prebid/prebid-server/v3/adapters/infytv"
"github.com/prebid/prebid-server/v3/adapters/inmobi"
"github.com/prebid/prebid-server/v3/adapters/interactiveoffers"
+ "github.com/prebid/prebid-server/v3/adapters/intertech"
"github.com/prebid/prebid-server/v3/adapters/invibes"
"github.com/prebid/prebid-server/v3/adapters/iqx"
"github.com/prebid/prebid-server/v3/adapters/iqzone"
@@ -340,6 +341,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder {
openrtb_ext.BidderInfyTV: infytv.Builder,
openrtb_ext.BidderInMobi: inmobi.Builder,
openrtb_ext.BidderInteractiveoffers: interactiveoffers.Builder,
+ openrtb_ext.BidderIntertech: intertech.Builder,
openrtb_ext.BidderInvibes: invibes.Builder,
openrtb_ext.BidderIQX: iqx.Builder,
openrtb_ext.BidderIQZone: iqzone.Builder,
diff --git a/macros/macros.go b/macros/macros.go
index 2b0e29d6238..1fff558b39c 100644
--- a/macros/macros.go
+++ b/macros/macros.go
@@ -17,6 +17,7 @@ type EndpointTemplateParams struct {
GvlID string
PageID string
SupplyId string
+ ImpID string
SspId string
SspID string
SeatID string
diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go
index f7706ce5c25..94fe8932e84 100644
--- a/openrtb_ext/bidders.go
+++ b/openrtb_ext/bidders.go
@@ -127,6 +127,7 @@ var coreBidderNames []BidderName = []BidderName{
BidderInfyTV,
BidderInMobi,
BidderInteractiveoffers,
+ BidderIntertech,
BidderInvibes,
BidderIQX,
BidderIQZone,
@@ -456,6 +457,7 @@ const (
BidderInfyTV BidderName = "infytv"
BidderInMobi BidderName = "inmobi"
BidderInteractiveoffers BidderName = "interactiveoffers"
+ BidderIntertech BidderName = "intertech"
BidderInvibes BidderName = "invibes"
BidderIQX BidderName = "iqx"
BidderIQZone BidderName = "iqzone"
diff --git a/openrtb_ext/imp_intertech.go b/openrtb_ext/imp_intertech.go
new file mode 100644
index 00000000000..7c0bc955c5a
--- /dev/null
+++ b/openrtb_ext/imp_intertech.go
@@ -0,0 +1,6 @@
+package openrtb_ext
+
+type ExtImpIntertech struct {
+ PageID int `json:"page_id"`
+ ImpID int `json:"imp_id"`
+}
diff --git a/static/bidder-info/intertech.yaml b/static/bidder-info/intertech.yaml
new file mode 100644
index 00000000000..bf4b52bc382
--- /dev/null
+++ b/static/bidder-info/intertech.yaml
@@ -0,0 +1,15 @@
+# This adapter is ported from PBS-Java to PBS-Go by Prebid. Please open a GitHub issue instead of
+# directly contacting the maintainer for technical issues.
+endpoint: https://prebid.intertechsrvcs.com/prebid/{{.PageID}}?imp-id={{.ImpID}}&ssp-id=10500
+endpointCompression: GZIP
+maintainer:
+ email: prebid@intertechsrvcs.com
+capabilities:
+ site:
+ mediaTypes:
+ - banner
+ - native
+userSync:
+ redirect:
+ url: https://prebid.intertechsrvcs.com/mapuid/intertech/?ssp-id=10500&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&location=
+ userMacro: "{UID}"
\ No newline at end of file
diff --git a/static/bidder-params/intertech.json b/static/bidder-params/intertech.json
new file mode 100644
index 00000000000..8b1e3daa6cd
--- /dev/null
+++ b/static/bidder-params/intertech.json
@@ -0,0 +1,21 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "title": "Intertech Adapter Params",
+ "description": "A schema which validates params accepted by the Intertech adapter",
+ "type": "object",
+ "properties": {
+ "page_id": {
+ "type": "integer",
+ "minLength": 1,
+ "description": "Special Page Id provided by Intertech Manager"
+ },
+ "imp_id": {
+ "type": "integer",
+ "minLength": 1,
+ "description": "Special identifier provided by Intertech Manager"
+ }
+ },
+ "required":
+ ["page_id",
+ "imp_id"]
+}
\ No newline at end of file