Skip to content

fix: harden Twitch bot socket handling and triggers (FR-470..474)#22

Merged
Avicennasis merged 1 commit into
mainfrom
fix/twitch-socket-hardening-fr470-474
Jul 16, 2026
Merged

fix: harden Twitch bot socket handling and triggers (FR-470..474)#22
Avicennasis merged 1 commit into
mainfrom
fix/twitch-socket-hardening-fr470-474

Conversation

@Avicennasis

Copy link
Copy Markdown
Owner

Batch fix for five verified twitch.py bugs filed under the ClaudeCode project (Redmine #48945–#48949). All are in the Twitch bot's socket/IRC handling; each was checked against source before fixing.

Fixes

  • FR-474 (#48949) — connect over TLS (port 6697, ssl.create_default_context() + wrap_socket(..., server_hostname=SERVER)). The OAuth token, sent via the IRC PASS command, was previously transmitted in plaintext over port 6667.
  • FR-470 (#48945) — call socket.settimeout(SOCKET_TIMEOUT) after connect, so the pre-existing except socket.timeout: continue branch is actually reachable and a stalled/dead connection can't hang the process forever.
  • FR-471 (#48946) — frame messages properly: accumulate received bytes in a buffer and split on the IRC \r\n terminator, processing one complete line at a time and keeping any trailing partial for the next recv(). Mirrors the async Wikimedia bot. Previously the whole recv() blob was .strip()ed and treated as a single message, so concatenated or split messages were mishandled (this also silently fixes the mention regexes, which anchor on $).
  • FR-472 (#48947) — remove the "PING :tmi.twitch.tv""lol" trigger. It was dead code behind the PING early-return, and would have spammed chat on every server ping if reached.
  • FR-473 (#48948) — add TwitchBot._word_in() (regex \bword\b) and apply it to the five triggers the ticket names — love, cake, portal, shiny, duck — so they match whole words, not substrings (glove, cupcake, portable, abduction, shininess). The remaining bare-substring triggers are the same class but a couple involve a matching-strictness judgment (e.g. yay vs yayyy); tracked as follow-up #49439 for the owner to decide.

Verification

  • ruff check + ruff format --check: clean
  • Existing pytest suite: 22/22 pass (covers the Wikimedia bot; unaffected)
  • Standalone behavioral checks: _word_in whole-word matching (matches real words, rejects glove/cupcake/portable/abduction/shininess), and CRLF framing across concatenated, split-mid-line, and partial-only chunks.

Note: BotConfig.SERVER remains irc.twitch.tv (unchanged/out of scope) — only the port and transport changed.

- FR-474: connect over TLS (port 6697, ssl.create_default_context +
  wrap_socket) so the OAuth token sent via PASS is encrypted, not
  plaintext on 6667.
- FR-470: set socket.settimeout(SOCKET_TIMEOUT) after connect so the
  existing `except socket.timeout` branch is live and a stalled
  connection can't hang the process indefinitely.
- FR-471: buffer received bytes and split on the CRLF terminator,
  processing one complete IRC line at a time (mirrors the Wikimedia
  bot). A single recv() can hold several messages or a partial one;
  the old code treated the whole blob as one message.
- FR-472: remove the "PING :tmi.twitch.tv" -> "lol" trigger. It was
  unreachable behind the PING early-return and would spam chat on every
  server ping if reached.
- FR-473: add TwitchBot._word_in() whole-word helper and apply it to the
  five triggers named in the ticket (love, cake, portal, shiny, duck) so
  they no longer fire on substrings (glove, cupcake, portable, ...).
  Remaining substring triggers tracked in follow-up #49439.

Verified: ruff check + format clean; existing pytest suite 22/22 pass;
standalone checks of _word_in whole-word matching and the CRLF framing
(concatenated, split-midline, partial-only).
@Avicennasis
Avicennasis merged commit 947966e into main Jul 16, 2026
5 checks passed
@Avicennasis
Avicennasis deleted the fix/twitch-socket-hardening-fr470-474 branch July 16, 2026 16:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant