Module: ZeroClick::Sellers::PageViews
- Defined in:
- lib/zeroclick/sellers/page_views.rb
Overview
POST /v1/page-views: one fire-and-forget marketing page-view beacon.
As in Usage and Agentify, building the payload and interpreting the response are separate from transport, so what a response MEANS is decided in one pure place. Unlike the usage endpoints the API answers 204 with no body, so the success path parses nothing — see #interpret_report.
The visitor's user-agent/accept/IP are forwarded so the API can classify the viewer and derive the shared viewer id; they are consumed there and never stored raw. Only the path is ever sent, never the query.
Constant Summary collapse
- REPORT_PATH =
"/v1/page-views"- REPRESENTATIONS =
What the site actually served for a page-content request: the agent markdown variant, or the normal HTML.
%w[html markdown].freeze
Class Method Summary collapse
-
.build_payload(seller:, path:, status: nil, duration_ms: nil, representation: nil, journey_id: nil, captured_at: nil, user_agent: nil, accept: nil, client_ip: nil, country: nil, referrer_host: nil) ⇒ Object
Build the wire body: camelCase string keys, every absent optional key omitted.
-
.interpret_report(status, _body) ⇒ Object
A 204 carries no body, so there is nothing to parse; a non-2xx is the only failure a well-formed beacon can hit here.
Class Method Details
.build_payload(seller:, path:, status: nil, duration_ms: nil, representation: nil, journey_id: nil, captured_at: nil, user_agent: nil, accept: nil, client_ip: nil, country: nil, referrer_host: nil) ⇒ Object
Build the wire body: camelCase string keys, every absent optional key
omitted. seller is the seller's public id and path must be an
absolute path, both rejected before any request leaves the process.
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/zeroclick/sellers/page_views.rb', line 30 def build_payload(seller:, path:, status: nil, duration_ms: nil, representation: nil, journey_id: nil, captured_at: nil, user_agent: nil, accept: nil, client_ip: nil, country: nil, referrer_host: nil) Sellers.require_slug!(seller, "seller", "report_page_view") unless path.is_a?(String) && path.start_with?("/") raise Error.new("malformed_input", operation: "report_page_view", message: "path must be a string beginning with \"/\"") end if !representation.nil? && !REPRESENTATIONS.include?(representation) raise Error.new("malformed_input", operation: "report_page_view", message: "representation must be \"html\" or \"markdown\"") end payload = { "seller" => seller, "path" => path } payload["status"] = status unless status.nil? payload["durationMs"] = duration_ms unless duration_ms.nil? payload["representation"] = representation unless representation.nil? payload["journeyId"] = journey_id unless journey_id.nil? payload["capturedAt"] = captured_at unless captured_at.nil? payload["userAgent"] = user_agent unless user_agent.nil? payload["accept"] = accept unless accept.nil? payload["clientIp"] = client_ip unless client_ip.nil? payload["country"] = country unless country.nil? payload["referrerHost"] = referrer_host unless referrer_host.nil? payload end |
.interpret_report(status, _body) ⇒ Object
A 204 carries no body, so there is nothing to parse; a non-2xx is the only failure a well-formed beacon can hit here. Distinct from Usage.interpret_report, which requires a JSON body.
60 61 62 63 64 |
# File 'lib/zeroclick/sellers/page_views.rb', line 60 def interpret_report(status, _body) return if (200..299).cover?(status) raise Error.new("api_status_error", operation: "report_page_view", status: status) end |