# Changelog of Twitch Chat Scraper — VOD Chat Archive (`devilscrapes/twitch-vod-chat-archive`) Actor

- **URL**: https://apify.com/devilscrapes/twitch-vod-chat-archive/changelog.md
- **Full Actor documentation**: https://apify.com/devilscrapes/twitch-vod-chat-archive.md

## Twitch VOD Chat Archive — Changelog

### 0.4.0 — 2026-09-10

- Fix: dedup chat messages across overlapping page boundaries. Twitch's
  `contentOffsetSeconds` pagination anchor is not exact-and-exclusive —
  live-reproduced against a real VOD, requesting
  `contentOffsetSeconds = last_edge_offset + 1` still returned a page
  that started 44 seconds earlier, re-serving 13 of the previous page's
  59 messages verbatim (same `message_id`). Every multi-page VOD walk
  was double-billing customers for a chunk of messages at each page
  transition. `_walk_vod_chat` now tracks `seen_ids` per VOD and drops
  any repeated `message_id`; confirmed 0 duplicates across 2000 rows /
  46 page boundaries after the fix (was 87/100 unique before).
- Fix: fail loud instead of silently reporting a SUCCEEDED 0-row run
  when Twitch never answers a single request in the run (network
  exhausted after retries / integrity challenge never clears). Before
  this, a fully-blocked run was indistinguishable — on every dashboard
  — from a genuinely empty channel or a deleted VOD, while still
  billing the `actor-start` warm-up fee for a run that never actually
  searched anything. Added `TransportBlockedError`; only raises when
  nothing was emitted AND zero pages were ever successfully fetched, so
  ordinary partial multi-VOD failures still succeed normally.
- 30-day health flagged 83% success (9/56 customer runs failed/aborted,
  37 users). Own `/acts/{id}/runs` showed 0 failures (all 4 own runs on
  record SUCCEEDED) — customer-side failures aren't readable by us — so
  root-caused via live reproduction rather than log reading; see
  `docs/specs/twitch-vod-chat-archive/notes.md`.

### 0.3.0 — 2026-09-02

- Fix: `channelLogin` now accepts a full Twitch channel URL
  (`https://twitch.tv/<login>` or `.../<login>/videos`), not just a
  bare slug. `vodIds` already normalized URL-or-ID input
  (`_extract_vod_id`); `channelLogin` did not, so pasting the
  browser-address-bar URL — the single most natural customer action —
  raised `ValueError` and hit `Actor.fail()` before any network call.
  30-day health flagged this Actor at 86% success (6/44 customer runs
  failed); this closes the highest-probability, fully reproducible
  gap. Added `_extract_channel_login` + 4 regression tests.

### 0.2.0 — 2026-05-16

- Fix PPE: charge `result-row` (was `result`) so dataset emits bill correctly.

### 0.1.0 — 2026-05-16

- Initial release. Twitch VOD chat replay export via the public
  `VideoCommentsByOffsetOrCursor` GraphQL endpoint. One row per
  message, with normalized fragments, badges, user color, and offset.
  Two input modes: explicit `vodIds` list, or `channelLogin` +
  `maxRecentVods`.
