# Minimal OpenRTB 2.6 bidder in Node.js

The code from the tutorial at https://rtblint.org/learn/build-a-bidder-node/.

It accepts OpenRTB 2.6 bid requests on `POST /bid`, validates them with
[rtblint-core](https://www.npmjs.com/package/rtblint-core), bids on the first
banner or video impression it has a creative for, and logs win notices on
`/win`. It uses `node:http` and nothing else.

## Requirements

Node.js 22 or later.

## Run

```sh
npm install
node server.mjs
```

The server listens on port 8080. Set `PORT` to change it and `PUBLIC_URL` to
the address exchanges reach you on, because it is written into `nurl`.

## Send a request

```sh
curl -s -X POST http://localhost:8080/bid \
  -H 'content-type: application/json' \
  --data @sample-request.json -o response.json -w '%{http_code}\n'
```

Status codes:

- `200` with a BidResponse: a bid.
- `200` with `{"id": "...", "nbr": 2}`: the request failed validation.
- `204` with no body: no bid (no matching imp, floor above the cap, blocked
  advertiser domain, currency other than USD, or the tmax budget ran out).
- `400` with no body: the body was not JSON or was larger than 256 KB.

## Check the response against the request

```sh
node --input-type=module -e '
import { readFileSync } from "node:fs";
import { validateResponseAgainstRequest } from "rtblint-core";

const [response, request] = process.argv.slice(1).map((f) => readFileSync(f, "utf8"));
const report = validateResponseAgainstRequest(response, request, "2.6-202606");
console.log(JSON.stringify(report, null, 2));
process.exit(report.valid ? 0 : 1);
' response.json sample-request.json
```

It prints the report and exits 0 when the response is valid for that request.

## Simulate a win notice

The exchange replaces the macros in `nurl` before calling it. To do the same
by hand:

```sh
jq -r '.seatbid[0].bid[0].nurl' response.json \
  | sed -e 's/${AUCTION_ID}/8f2b6c1e-4d7a-4a51-9b3e-2c0d5f7a9e10/' \
        -e 's/${AUCTION_IMP_ID}/1/' \
        -e 's/${AUCTION_PRICE}/1.23/' \
  | xargs curl -s -o /dev/null -w '%{http_code}\n'
```

The server logs one JSON line per win notice.

## Scope

This is a starting point for learning the protocol, not a production bidder.
