From 34eee58a348bd50b79545d8b4b803e7e203b4ad6 Mon Sep 17 00:00:00 2001 From: NatLee Date: Wed, 4 Nov 2026 07:25:30 +0800 Subject: [PATCH 1/7] test: add a fake Twitch chat server to practise and test against There is no way to test a Twitch bot without a Twitch account and a token, and we have neither. tools/fake_twitch_server.py speaks just enough of Twitch's IRC dialect (CAP REQ, PASS/NICK, JOIN, PRIVMSG, PING/PONG, RECONNECT, NOTICE) with the reply lines from Twitch's docs. Tests use it as a context manager on a free port. People learning from the repo can run it in a terminal and chat as a viewer by typing "alice: hello". It does not import the bot's code, so a parser bug in the bot can't hide behind the same bug in the server. --- tools/fake_twitch_server.py | 480 ++++++++++++++++++++++++++++++++++++ 1 file changed, 480 insertions(+) create mode 100644 tools/fake_twitch_server.py diff --git a/tools/fake_twitch_server.py b/tools/fake_twitch_server.py new file mode 100644 index 0000000..6881521 --- /dev/null +++ b/tools/fake_twitch_server.py @@ -0,0 +1,480 @@ +"""A pretend Twitch chat server you can run on your own computer. + +It speaks just enough of Twitch's IRC dialect for this repo: CAP REQ, PASS, NICK, +JOIN, PRIVMSG, PING/PONG and RECONNECT, with the same reply lines that Twitch's +docs show (https://dev.twitch.tv/docs/chat/irc/). Two uses: + +* Practice without a Twitch account. In one terminal: + + python tools/fake_twitch_server.py + + In another one, point the bot at it (the server prints the exact command): + + TWITCH_IRC_HOST=127.0.0.1 TWITCH_IRC_PORT=6667 TWITCH_IRC_TLS=false python main.py + + Then type ``alice: hello`` in the server window to chat as a viewer called alice. + ``/ping`` sends a PING, ``/reconnect`` asks the bot to reconnect, ``/quit`` stops. + +* Tests. ``FakeTwitchServer`` is a context manager; tests start it on a free port, + make it say things (``say``, ``ping``, ``send_raw``) and check what the bot sent + (``wait_for``, ``sent_lines``). + +This is not Twitch. It does not check tokens against anything real, has no rate +limits and knows only the channels you give it. It is deliberately written without +importing the bot's own code, so a parser bug in the bot cannot hide behind the same +bug in the server. +""" + +from __future__ import annotations + +import argparse +import itertools +import socket +import ssl +import sys +import threading +import time +from collections.abc import Callable, Iterable +from dataclasses import dataclass, field + +SERVER_NAME = "tmi.twitch.tv" +DEFAULT_HOST = "127.0.0.1" +DEFAULT_PORT = 6667 # Twitch's plain-text IRC port; the practice server has no TLS +DEFAULT_CHANNELS = ("demo",) +ACCEPT_POLL = 0.1 # seconds between checks whether stop() was called +KNOWN_CAPABILITIES = ("twitch.tv/tags", "twitch.tv/commands", "twitch.tv/membership") + +# Exact texts from Twitch's docs, so the bot sees what it would see on Twitch. +AUTH_FAILED = "Login authentication failed" +CHANNEL_SUSPENDED = "This channel does not exist or has been suspended." +BAD_AUTH_ORDER = "Improperly formatted auth" +WELCOME_LINES = ( + ("001", "Welcome, GLHF!"), + ("002", "Your host is tmi.twitch.tv"), + ("003", "This server is rather new"), + ("004", "-"), + ("375", "-"), + ("372", "You are in a maze of twisty passages, all alike."), + ("376", ">"), +) + +_TAG_ESCAPES = {";": r"\:", " ": r"\s", "\\": "\\\\", "\r": r"\r", "\n": r"\n"} + + +def escape_tag_value(value: str) -> str: + """Escape a tag value the way IRCv3 says (https://ircv3.net/specs/extensions/message-tags).""" + return "".join(_TAG_ESCAPES.get(char, char) for char in value) + + +def format_tags(tags: dict[str, str]) -> str: + return "@" + ";".join(f"{key}={escape_tag_value(value)}" for key, value in tags.items()) + + +@dataclass +class _Client: + """One connected bot.""" + + number: int + sock: socket.socket + caps: set[str] = field(default_factory=set) + password: str | None = None + nick: str | None = None + channels: set[str] = field(default_factory=set) + lock: threading.Lock = field(default_factory=threading.Lock) + + def send(self, data: bytes) -> None: + with self.lock: + try: + self.sock.sendall(data) + except OSError: + pass # the bot already hung up; nothing to deliver + + def send_line(self, line: str) -> None: + self.send((line + "\r\n").encode("utf-8")) + + def close(self) -> None: + try: + self.sock.shutdown(socket.SHUT_RDWR) + except OSError: + pass + self.sock.close() + + +class FakeTwitchServer: + """A threaded IRC server that behaves like Twitch chat for the parts this repo uses.""" + + def __init__( + self, + host: str = DEFAULT_HOST, + port: int = 0, + *, + channels: Iterable[str] = DEFAULT_CHANNELS, + suspended_channels: Iterable[str] = (), + accepted_token: str | None = None, + ssl_context: ssl.SSLContext | None = None, + on_event: Callable[[str], None] | None = None, + ) -> None: + names = [name.lstrip("#").lower() for name in channels] + self.channels = set(names) + self.default_channel = names[0] # where say() and the console send chat by default + self.suspended_channels = {name.lstrip("#").lower() for name in suspended_channels} + self.accepted_token = accepted_token # None: any "oauth:..." password logs in + self.ssl_context = ssl_context + self.on_event = on_event or (lambda text: None) + self._listener = socket.create_server((host, port)) + self.address = self._listener.getsockname()[:2] + self._clients: list[_Client] = [] + self._sent: list[tuple[int, str]] = [] # (client number, line the bot sent) + self._joins: dict[str, int] = {} # channel -> how many successful JOINs so far + self._changed = threading.Condition() + self._numbers = itertools.count(1) + self._message_ids = itertools.count(1) + self._running = False + self._threads: list[threading.Thread] = [] + + # ----- start / stop --------------------------------------------------------- + + def start(self) -> FakeTwitchServer: + self._running = True + self._spawn(self._accept_loop) + return self + + def stop(self) -> None: + self._running = False + self._listener.close() + self.disconnect_all() + for thread in self._threads: + thread.join(timeout=2) + + def __enter__(self) -> FakeTwitchServer: + return self.start() + + def __exit__(self, *exc_info: object) -> None: + self.stop() + + @property + def host(self) -> str: + return self.address[0] + + @property + def port(self) -> int: + return self.address[1] + + # ----- things a test (or the console) can make the server do --------------- + + def say(self, user: str, text: str, *, channel: str | None = None, display_name: str | None = None) -> None: + """Send a chat message from viewer ``user`` to every bot in ``channel``.""" + channel = (channel or self.default_channel).lower() + login = user.lower() + tags = { + "badge-info": "", + "badges": "", + "color": "#1E90FF", + "display-name": display_name or user, + "emotes": "", + "first-msg": "0", + "flags": "", + "id": f"00000000-0000-0000-0000-{next(self._message_ids):012d}", + "mod": "0", + "room-id": "1000", + "subscriber": "0", + "tmi-sent-ts": str(int(time.time() * 1000)), + "turbo": "0", + "user-id": str(2000 + sum(map(ord, login))), + "user-type": "", + } + line = f":{login}!{login}@{login}.{SERVER_NAME} PRIVMSG #{channel} :{text}" + for client in self._clients_in(channel): + client.send_line(self._with_tags(client, tags, line)) + + def ping(self, text: str = SERVER_NAME) -> None: + self.send_line_to_all(f"PING :{text}") + + def request_reconnect(self) -> None: + """Twitch sends RECONNECT before maintenance. Only bots with twitch.tv/commands get it.""" + for client in self._snapshot_clients(): + if "twitch.tv/commands" in client.caps: + client.send_line(f":{SERVER_NAME} RECONNECT") + + def send_line_to_all(self, line: str) -> None: + for client in self._snapshot_clients(): + client.send_line(line) + + def send_raw(self, data: bytes) -> None: + """Send exact bytes, e.g. two lines in one packet or half a line.""" + for client in self._snapshot_clients(): + client.send(data) + + def disconnect_all(self) -> None: + for client in self._snapshot_clients(): + client.close() + + # ----- things a test can check ---------------------------------------------- + + def sent_lines(self) -> list[str]: + """Every line the bots sent, oldest first.""" + with self._changed: + return [line for _, line in self._sent] + + def wait_for(self, predicate: Callable[[str], bool], timeout: float | None = 5.0, count: int = 1) -> str: + """Wait until bots have sent ``count`` lines that match ``predicate``; return the last of them. + ``timeout=None`` waits forever.""" + def matches() -> list[str]: + return [line for _, line in self._sent if predicate(line)] + + with self._changed: + if not self._changed.wait_for(lambda: len(matches()) >= count, timeout): + sent = [line for _, line in self._sent] + raise TimeoutError(f"wanted {count} matching line(s) within {timeout} s; bots sent {sent}") + return matches()[count - 1] + + def wait_for_join(self, channel: str | None = None, timeout: float | None = 5.0, count: int = 1) -> None: + """Wait until a bot is in ``channel`` and there have been ``count`` JOINs to it so far. + ``timeout=None`` waits forever.""" + wanted = (channel or self.default_channel).lower() + with self._changed: + joined = self._changed.wait_for(lambda: self._clients_in(wanted) and self._joins.get(wanted, 0) >= count, timeout) + if not joined: + raise TimeoutError(f"no bot joined #{wanted} {count} time(s) within {timeout} s") + + # ----- the server itself ---------------------------------------------------- + + def _spawn(self, target: Callable[..., None], *args: object) -> None: + thread = threading.Thread(target=target, args=args, daemon=True) + thread.start() + self._threads.append(thread) + + def _accept_loop(self) -> None: + # On Linux, closing a socket does not wake up accept(); a short timeout lets stop() end this loop. + self._listener.settimeout(ACCEPT_POLL) + while self._running: + try: + sock, _ = self._listener.accept() + except TimeoutError: + continue + except OSError: + return # listener closed by stop() + sock.settimeout(None) + self._spawn(self._serve, sock) + + def _serve(self, sock: socket.socket) -> None: + if self.ssl_context is not None: + try: + sock = self.ssl_context.wrap_socket(sock, server_side=True) + except (OSError, ssl.SSLError): + sock.close() + return + client = _Client(next(self._numbers), sock) + with self._changed: + self._clients.append(client) + try: + self._read_lines(client) + finally: + with self._changed: + self._clients.remove(client) + self._changed.notify_all() + client.close() + self.on_event(f"bot #{client.number} disconnected") + + def _read_lines(self, client: _Client) -> None: + buffer = b"" + while True: + try: + data = client.sock.recv(4096) + except OSError: + return + if not data: + return + buffer += data + *lines, buffer = buffer.split(b"\n") + for raw in lines: + line = raw.rstrip(b"\r").decode("utf-8", errors="replace") + with self._changed: + self._sent.append((client.number, line)) + self._changed.notify_all() + if not self._handle(client, line): + return + + def _handle(self, client: _Client, line: str) -> bool: + """React to one line from a bot. Returns False when the connection should end.""" + command, _, rest = line.partition(" ") + handler = getattr(self, f"_on_{command.lower()}", self._on_unknown) + return handler(client, rest, command) + + def _on_cap(self, client: _Client, rest: str, command: str) -> bool: + wanted = rest.removeprefix("REQ").strip().lstrip(":").split() + if all(cap in KNOWN_CAPABILITIES for cap in wanted): + client.caps.update(wanted) + client.send_line(f":{SERVER_NAME} CAP * ACK :{' '.join(wanted)}") + else: + client.send_line(f":{SERVER_NAME} CAP * NAK :{' '.join(wanted)}") + return True + + def _on_pass(self, client: _Client, rest: str, command: str) -> bool: + client.password = rest.strip() + return True + + def _on_nick(self, client: _Client, rest: str, command: str) -> bool: + if client.password is None: + return self._refuse(client, BAD_AUTH_ORDER) + token_ok = client.password.startswith("oauth:") and client.password != "oauth:" + if self.accepted_token is not None: + token_ok = client.password == self.accepted_token + if not token_ok: + return self._refuse(client, AUTH_FAILED) + client.nick = rest.strip().lower() + for number, text in WELCOME_LINES: + client.send_line(f":{SERVER_NAME} {number} {client.nick} :{text}") + if "twitch.tv/commands" in client.caps: + tags = {"badge-info": "", "badges": "", "color": "", "display-name": client.nick, + "emote-sets": "0", "user-id": "1", "user-type": ""} + client.send_line(self._with_tags(client, tags, f":{SERVER_NAME} GLOBALUSERSTATE")) + self.on_event(f"bot #{client.number} logged in as {client.nick}") + return True + + def _on_user(self, client: _Client, rest: str, command: str) -> bool: + return True # IRC libraries send USER; Twitch does not need it + + def _on_join(self, client: _Client, rest: str, command: str) -> bool: + nick = client.nick + for name in rest.strip().split(","): + channel = name.strip().lstrip("#").lower() + if channel in self.suspended_channels: + client.send_line(self._with_tags(client, {"msg-id": "msg_channel_suspended"}, + f":{SERVER_NAME} NOTICE #{channel} :{CHANNEL_SUSPENDED}")) + continue + if channel not in self.channels: + continue # Twitch quietly drops JOINs for channels that do not exist + with self._changed: # count the bot in before it hears 366, so chat can reach it right away + client.channels.add(channel) + self._joins[channel] = self._joins.get(channel, 0) + 1 + self._changed.notify_all() + self.on_event(f"bot #{client.number} joined #{channel}") + client.send_line(f":{nick}!{nick}@{nick}.{SERVER_NAME} JOIN #{channel}") + client.send_line(f":{nick}.{SERVER_NAME} 353 {nick} = #{channel} :{nick}") + client.send_line(f":{nick}.{SERVER_NAME} 366 {nick} #{channel} :End of /NAMES list") + if "twitch.tv/commands" in client.caps: + client.send_line(self._with_tags(client, self._userstate(nick), f":{SERVER_NAME} USERSTATE #{channel}")) + roomstate = {"room-id": "1000", "slow": "0"} + client.send_line(self._with_tags(client, roomstate, f":{SERVER_NAME} ROOMSTATE #{channel}")) + return True + + def _on_part(self, client: _Client, rest: str, command: str) -> bool: + channel = rest.strip().lstrip("#").lower() + client.channels.discard(channel) + client.send_line(f":{client.nick}!{client.nick}@{client.nick}.{SERVER_NAME} PART #{channel}") + return True + + def _on_privmsg(self, client: _Client, rest: str, command: str) -> bool: + target, _, text = rest.partition(" :") + self.on_event(f"{client.nick} -> {target}: {text}") + if "twitch.tv/commands" in client.caps: + # Twitch does not echo the bot's own PRIVMSG back; it sends USERSTATE instead. + client.send_line(self._with_tags(client, self._userstate(client.nick), f":{SERVER_NAME} USERSTATE {target}")) + return True + + def _on_pong(self, client: _Client, rest: str, command: str) -> bool: + self.on_event(f"bot #{client.number} answered: PONG {rest}") + return True + + def _on_quit(self, client: _Client, rest: str, command: str) -> bool: + return False + + def _on_unknown(self, client: _Client, rest: str, command: str) -> bool: + client.send_line(f":{SERVER_NAME} 421 {client.nick or '*'} {command} :Unknown command") + return True + + def _refuse(self, client: _Client, notice: str) -> bool: + client.send_line(f":{SERVER_NAME} NOTICE * :{notice}") + self.on_event(f"bot #{client.number} refused: {notice}") + return False # Twitch closes the connection after a failed login + + def _userstate(self, nick: str | None) -> dict[str, str]: + return {"badge-info": "", "badges": "", "color": "", "display-name": nick or "", + "emote-sets": "0", "mod": "0", "subscriber": "0", "user-type": ""} + + @staticmethod + def _with_tags(client: _Client, tags: dict[str, str], line: str) -> str: + return f"{format_tags(tags)} {line}" if "twitch.tv/tags" in client.caps else line + + def _snapshot_clients(self) -> list[_Client]: + with self._changed: + return list(self._clients) + + def _clients_in(self, channel: str) -> list[_Client]: + return [client for client in self._snapshot_clients() if channel in client.channels] + + +# ----- console mode ------------------------------------------------------------- + +CONSOLE_HELP = """\ +Type a chat line as name: message (example: alice: hello there) +Commands: /ping /reconnect /quit +Lines you type before a bot joins wait until one does.""" + + +def run_console(server: FakeTwitchServer, lines: Iterable[str], delay: float) -> None: + """Read lines from the keyboard (or a pipe) and play them into the chat.""" + channel = server.default_channel + commands = { + "/ping": ("PING sent", server.ping), + "/reconnect": ("RECONNECT sent", server.request_reconnect), + } + for raw in lines: + line = raw.strip() + if not line: + continue + if line == "/quit": + return + server.wait_for_join(channel, timeout=None) + if line in commands: + note, action = commands[line] + print(f"[server] {note}", flush=True) + action() + else: + user, separator, text = (part.strip() for part in line.partition(":")) + if not separator or not user: + print("[server] write it as name: message", flush=True) + continue + print(f"[chat] {user}: {text}", flush=True) + server.say(user, text, channel=channel) + time.sleep(delay) + + +def main(argv: list[str] | None = None) -> None: + parser = argparse.ArgumentParser(description="Pretend Twitch chat server for practice (plain TCP, no TLS).") + parser.add_argument("--host", default=DEFAULT_HOST, help=f"address to listen on (default {DEFAULT_HOST})") + parser.add_argument("--port", type=int, default=DEFAULT_PORT, help=f"port to listen on (default {DEFAULT_PORT})") + parser.add_argument("--channel", action="append", + help=f"channel that exists (default {DEFAULT_CHANNELS[0]}); repeat for more") + parser.add_argument("--token", help="only accept this PASS value (default: any oauth:... value)") + parser.add_argument("--delay", type=float, default=0.3, help="seconds to wait after each typed line (default 0.3)") + args = parser.parse_args(argv) + + server = FakeTwitchServer( + args.host, args.port, + channels=args.channel or DEFAULT_CHANNELS, + accepted_token=args.token, + on_event=lambda text: print(f"[server] {text}", flush=True), + ) + with server: + host, port = server.address + channel = server.default_channel + print(f"[server] fake Twitch chat listening on {host}:{port} (plain TCP, not the real Twitch)", flush=True) + print("[server] point the bot here, for example with these lines in .env:", flush=True) + print(f" TWITCH_IRC_HOST={host} TWITCH_IRC_PORT={port} TWITCH_IRC_TLS=false", flush=True) + print(f" TWITCH_CHANNEL={channel} TWITCH_BOT_NAME=any_name " + f"TWITCH_OAUTH_TOKEN={args.token or 'oauth:anything'}", flush=True) + print(CONSOLE_HELP, flush=True) + try: + run_console(server, sys.stdin, args.delay) + if not sys.stdin.isatty(): + # input came from a pipe: keep serving until Ctrl+C so the bot can finish + threading.Event().wait() + except KeyboardInterrupt: + pass + print("[server] stopped", flush=True) + + +if __name__ == "__main__": + main() From fc2e4b8b3a3c80932a35e599655f852084bce6ec Mon Sep 17 00:00:00 2001 From: NatLee Date: Wed, 4 Nov 2026 07:26:00 +0800 Subject: [PATCH 2/7] feat: add twitch_chat.py, a step-by-step Twitch IRC client The 2019 client read one recv() as one line, cut messages with split(":"), returned (None, None) for PING and never noticed a closed connection. twitch_chat.py replaces it with a client meant to be read top to bottom, in nine commented steps: TLS connect, CAP REQ, PASS and NICK, JOIN, line buffering, parsing (tags, prefix, command, params), PING/PONG, sending under Twitch's rate limit, and ConnectionClosed. It connects to irc.chat.twitch.tv:6697 with TLS by default, waits for the join with a timeout, turns Twitch's login NOTICE into an AuthenticationError, hides the token in debug logs and still uses only the standard library. Tests run against the fake server, including one per 2019 bug. --- pyproject.toml | 15 ++ requirements-dev.txt | 6 + tests/conftest.py | 83 ++++++++ tests/test_parsing.py | 123 +++++++++++ tests/test_rate_limit.py | 67 ++++++ tests/test_twitch_chat.py | 247 ++++++++++++++++++++++ twitch_chat.py | 424 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 965 insertions(+) create mode 100644 pyproject.toml create mode 100644 requirements-dev.txt create mode 100644 tests/conftest.py create mode 100644 tests/test_parsing.py create mode 100644 tests/test_rate_limit.py create mode 100644 tests/test_twitch_chat.py create mode 100644 twitch_chat.py diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..04859d5 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,15 @@ +# Tool settings only. This repo is a few scripts to read and run, not a package to install. + +[tool.pytest.ini_options] +testpaths = ["tests"] +pythonpath = ["."] +addopts = "-ra" +timeout = 60 # a socket test that hangs fails instead of blocking CI + +[tool.ruff] +line-length = 130 +target-version = "py310" + +[tool.ruff.lint] +select = ["E", "F", "W", "I", "N", "UP", "B"] +ignore = ["N818"] # ConnectionClosed reads better than ConnectionClosedError (websockets uses the same name) diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 0000000..52acdc9 --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1,6 @@ +# For running the tests. The bot itself (main.py, twitch_chat.py, config.py) +# uses only Python's standard library and needs none of this. +pytest>=8.3 +pytest-timeout>=2.3 +trustme>=1.2 +ruff>=0.15 diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..1d4731b --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,83 @@ +"""Shared test helpers: a fake Twitch server per test, and a way to connect to it. + +Nothing here talks to the real Twitch. Servers listen on 127.0.0.1 with port 0, +so the operating system picks a free port for every test. +""" + +from __future__ import annotations + +import threading +from collections.abc import Callable, Iterator +from typing import Any + +import pytest + +from tools.fake_twitch_server import FakeTwitchServer +from twitch_chat import TwitchChat + +TOKEN = "oauth:test-token-not-real" +CHANNEL = "demo" +BOT = "echo_bot" + + +@pytest.fixture +def server() -> Iterator[FakeTwitchServer]: + with FakeTwitchServer(channels=[CHANNEL], accepted_token=TOKEN) as fake: + yield fake + + +@pytest.fixture +def chat_options(server: FakeTwitchServer) -> dict[str, Any]: + """TwitchChat arguments that point at the fake server (plain TCP, short timeouts).""" + return { + "channel": CHANNEL, + "nick": BOT, + "token": TOKEN, + "host": server.host, + "port": server.port, + "use_tls": False, + "handshake_timeout": 2.0, + } + + +@pytest.fixture +def connect(chat_options: dict[str, Any]) -> Iterator[Callable[..., TwitchChat]]: + """connect(**overrides) -> a connected TwitchChat; closed after the test.""" + opened: list[TwitchChat] = [] + + def _connect(**overrides: Any) -> TwitchChat: + chat = TwitchChat(**{**chat_options, **overrides}) + opened.append(chat) + chat.connect() + return chat + + yield _connect + for chat in opened: + chat.close() + + +class Background: + """Run a blocking call in a thread and collect its result or exception.""" + + def __init__(self, target: Callable[[], Any]) -> None: + self.result: Any = None + self.error: BaseException | None = None + self._thread = threading.Thread(target=self._run, args=(target,), daemon=True) + self._thread.start() + + def _run(self, target: Callable[[], Any]) -> None: + try: + self.result = target() + except BaseException as error: # noqa: B036 - hand every failure back to the test + self.error = error + + def join(self, timeout: float = 5.0) -> Any: + self._thread.join(timeout) + assert not self._thread.is_alive(), "the call is still running" + if self.error is not None: + raise self.error + return self.result + + +class StopBot(Exception): + """Raised by a fake sleep() to end a bot's reconnect loop inside a test.""" diff --git a/tests/test_parsing.py b/tests/test_parsing.py new file mode 100644 index 0000000..90c89d6 --- /dev/null +++ b/tests/test_parsing.py @@ -0,0 +1,123 @@ +"""STEP 5 and STEP 6: turning bytes into lines, and lines into their parts.""" + +import pytest + +from twitch_chat import ChatMessage, LineBuffer, parse_line, unescape_tag_value + +# Modelled on the PRIVMSG example in https://dev.twitch.tv/docs/chat/irc/ (checked 2026-11-04) +TWITCH_DOCS_EXAMPLE = ( + "@badge-info=;badges=turbo/1;color=#0D4200;display-name=ronni;emotes=25:0-4,12-16/1902:6-10;" + "id=b34ccfc7-4977-403a-8a94-33c6bac34fb8;mod=0;room-id=1337;subscriber=0;tmi-sent-ts=1507246572675;" + "turbo=1;user-id=1337;user-type=global_mod :ronni!ronni@ronni.tmi.twitch.tv PRIVMSG #ronni :Kappa Keepo Kappa" +) + + +def test_twitch_docs_example_splits_into_tags_prefix_command_params(): + message = parse_line(TWITCH_DOCS_EXAMPLE) + + assert message.command == "PRIVMSG" + assert message.prefix == "ronni!ronni@ronni.tmi.twitch.tv" + assert message.nick == "ronni" + assert message.params == ["#ronni", "Kappa Keepo Kappa"] + assert message.tags["display-name"] == "ronni" + assert message.tags["emotes"] == "25:0-4,12-16/1902:6-10" + assert message.tags["badge-info"] == "" + assert len(message.tags) == 13 + + +def test_chat_text_with_colons_stays_whole(): + # Regression: the 2019 code used split(":") and kept only "look at this". + message = parse_line(":alice!alice@alice.tmi.twitch.tv PRIVMSG #demo :look at this: https://example.com :)") + + assert message.trailing == "look at this: https://example.com :)" + + +def test_text_that_starts_with_a_colon(): + assert parse_line(":a!a@a.tmi.twitch.tv PRIVMSG #demo ::)").trailing == ":)" + + +def test_ping_has_no_prefix(): + message = parse_line("PING :tmi.twitch.tv") + + assert (message.prefix, message.command, message.params) == (None, "PING", ["tmi.twitch.tv"]) + + +def test_numeric_reply(): + message = parse_line(":tmi.twitch.tv 001 echo_bot :Welcome, GLHF!") + + assert message.command == "001" + assert message.params == ["echo_bot", "Welcome, GLHF!"] + + +def test_line_without_trailing_parameter(): + assert parse_line(":echo_bot!echo_bot@echo_bot.tmi.twitch.tv JOIN #demo").params == ["#demo"] + + +def test_empty_trailing_parameter_is_kept(): + assert parse_line("PRIVMSG #demo :").params == ["#demo", ""] + + +def test_cap_nak(): + assert parse_line(":tmi.twitch.tv CAP * NAK :twitch.tv/foo").params == ["*", "NAK", "twitch.tv/foo"] + + +def test_tag_without_value(): + assert parse_line("@flag;key=1 PING :x").tags == {"flag": "", "key": "1"} + + +@pytest.mark.parametrize( + ("escaped", "plain"), + [ + (r"Hello\sthere", "Hello there"), + (r"a\:b", "a;b"), + (r"back\\slash", "back\\slash"), + (r"line\rbreak\n", "line\rbreak\n"), + (r"\b", "b"), # unknown escape: drop the backslash + ("test\\", "test"), # lone backslash at the end: drop it + ("", ""), + ], +) +def test_tag_values_are_unescaped_like_ircv3_says(escaped, plain): + assert unescape_tag_value(escaped) == plain + + +def test_display_name_comes_from_tags_and_falls_back_to_login(): + tagged = ChatMessage.from_irc(parse_line(r"@display-name=Alice\sW :alice!alice@alice.tmi.twitch.tv PRIVMSG #demo :hi")) + untagged = ChatMessage.from_irc(parse_line(":alice!alice@alice.tmi.twitch.tv PRIVMSG #demo :hi")) + + assert (tagged.channel, tagged.user, tagged.text, tagged.display_name) == ("demo", "alice", "hi", "Alice W") + assert untagged.display_name == "alice" + + +# ----- LineBuffer ------------------------------------------------------------------- + + +def test_two_lines_in_one_chunk(): + # Regression: the 2019 code treated one recv() as one line and lost the second. + assert LineBuffer().feed(b"PING :a\r\nPING :b\r\n") == ["PING :a", "PING :b"] + + +def test_half_a_line_waits_for_the_rest(): + buffer = LineBuffer() + + assert buffer.feed(b"PRIVMSG #demo :hel") == [] + assert buffer.feed(b"lo\r\nPING") == ["PRIVMSG #demo :hello"] + assert buffer.feed(b" :x\r\n") == ["PING :x"] + + +def test_character_cut_between_two_chunks(): + # Regression: decoding each recv() on its own crashed on a split UTF-8 character. + data = "PRIVMSG #demo :你好\r\n".encode() + cut = data.index("你".encode()) + 1 + buffer = LineBuffer() + + assert buffer.feed(data[:cut]) == [] + assert buffer.feed(data[cut:]) == ["PRIVMSG #demo :你好"] + + +def test_bare_newline_and_blank_lines(): + assert LineBuffer().feed(b"PING :a\n\r\n\r\nPING :b\n") == ["PING :a", "PING :b"] + + +def test_invalid_utf8_does_not_crash(): + assert LineBuffer().feed(b"PRIVMSG #demo :\xff\r\n") == ["PRIVMSG #demo :�"] diff --git a/tests/test_rate_limit.py b/tests/test_rate_limit.py new file mode 100644 index 0000000..40444f5 --- /dev/null +++ b/tests/test_rate_limit.py @@ -0,0 +1,67 @@ +"""STEP 8: RateLimiter, with a fake clock so the tests run instantly.""" + +from twitch_chat import DEFAULT_RATE_LIMITS, RateLimiter + + +class FakeClock: + def __init__(self) -> None: + self.now = 0.0 + self.slept: list[float] = [] + + def __call__(self) -> float: + return self.now + + def sleep(self, seconds: float) -> None: + self.slept.append(seconds) + self.now += seconds + + +def limiter(rules, clock): + return RateLimiter(rules, clock=clock, sleep=clock.sleep) + + +def test_first_messages_go_out_at_once(): + clock = FakeClock() + limit = limiter([(3, 10.0)], clock) + + assert [limit.wait() for _ in range(3)] == [0.0, 0.0, 0.0] + + +def test_one_per_second(): + clock = FakeClock() + limit = limiter([(1, 1.0)], clock) + + limit.wait() + clock.now += 0.25 + + assert limit.wait() == 0.75 + + +def test_twitch_defaults_twenty_one_messages_take_thirty_seconds(): + # DEFAULT_RATE_LIMITS = 20 per 30 s and 1 per s (Twitch's numbers for a normal bot). + # Sends 1-20 go out one second apart (t = 0..19). Send 21 must wait until + # send 1 is 30 s old, so it leaves at t = 30 after an 11 s wait. + clock = FakeClock() + limit = limiter(DEFAULT_RATE_LIMITS, clock) + + for _ in range(21): + limit.wait() + + assert clock.slept == [1.0] * 19 + [11.0] + assert clock.now == 30.0 + + +def test_messages_spread_out_never_wait(): + clock = FakeClock() + limit = limiter(DEFAULT_RATE_LIMITS, clock) + + for _ in range(50): + assert limit.wait() == 0.0 + clock.now += 2.0 # slower than 20 per 30 s + + +def test_no_rules_means_no_limit(): + clock = FakeClock() + limit = limiter([], clock) + + assert sum(limit.wait() for _ in range(100)) == 0.0 diff --git a/tests/test_twitch_chat.py b/tests/test_twitch_chat.py new file mode 100644 index 0000000..1e17e8f --- /dev/null +++ b/tests/test_twitch_chat.py @@ -0,0 +1,247 @@ +"""TwitchChat against the fake Twitch server: the handshake, reading, PING, sending, endings. + +Tests marked "Regression" failed with the 2019 twitchSocket.py; the reproduction +script and its output are kept in the revamp notes. +""" + +from __future__ import annotations + +import logging +import ssl +import time + +import pytest +import trustme + +from tests.conftest import BOT, CHANNEL, TOKEN, Background +from tools.fake_twitch_server import FakeTwitchServer +from twitch_chat import ( + DEFAULT_RATE_LIMITS, + TWITCH_IRC_HOST, + TWITCH_IRC_PLAIN_PORT, + TWITCH_IRC_TLS_PORT, + AuthenticationError, + ConnectionClosed, + JoinError, + TwitchChat, +) + +ALICE = ":alice!alice@alice.tmi.twitch.tv PRIVMSG #demo :" + + +# ----- STEP 1 to 4: connecting -------------------------------------------------------- + + +def test_defaults_are_twitchs_tls_endpoint(): + chat = TwitchChat(channel="demo", nick="bot", token="t") + + assert (chat.host, chat.port, chat.use_tls) == (TWITCH_IRC_HOST, TWITCH_IRC_TLS_PORT, True) + assert TwitchChat(channel="demo", nick="bot", token="t", use_tls=False).port == TWITCH_IRC_PLAIN_PORT + + +def test_handshake_sends_cap_pass_nick_join_in_order(server, connect): + connect() + + assert server.sent_lines() == [ + "CAP REQ :twitch.tv/tags twitch.tv/commands", + f"PASS {TOKEN}", + f"NICK {BOT}", + f"JOIN #{CHANNEL}", + ] + + +def test_names_and_token_are_normalised(server, connect): + connect(channel="#Demo", nick="Echo_Bot", token=TOKEN.removeprefix("oauth:")) + + assert server.sent_lines()[1:] == [f"PASS {TOKEN}", "NICK echo_bot", "JOIN #demo"] + + +def test_wrong_token_raises_authentication_error_with_twitchs_words(connect): + # Regression: the 2019 constructor kept looping after Twitch hung up. + with pytest.raises(AuthenticationError, match="Login authentication failed"): + connect(token="oauth:wrong") + + +def test_unknown_channel_times_out_with_a_hint(connect): + # Regression: Twitch ignores a JOIN for a channel that does not exist; the 2019 code waited forever. + started = time.monotonic() + + with pytest.raises(JoinError, match="spelled right"): + connect(channel="no_such_channel", handshake_timeout=0.5) + assert time.monotonic() - started < 3 + + +def test_suspended_channel_notice_becomes_join_error(): + with FakeTwitchServer(channels=[CHANNEL], suspended_channels=["gone"], accepted_token=TOKEN) as fake: + chat = TwitchChat(channel="gone", nick=BOT, token=TOKEN, host=fake.host, port=fake.port, use_tls=False) + with chat, pytest.raises(JoinError, match="has been suspended"): + chat.connect() + + +def test_tls_connection_checks_the_certificate(): + ca = trustme.CA() + server_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) + ca.issue_cert("127.0.0.1").configure_cert(server_context) + trusting = ssl.create_default_context() + ca.configure_trust(trusting) + + with FakeTwitchServer(channels=[CHANNEL], accepted_token=TOKEN, ssl_context=server_context) as tls_server: + options = dict(channel=CHANNEL, nick=BOT, token=TOKEN, host="127.0.0.1", port=tls_server.port, handshake_timeout=2) + with TwitchChat(**options, ssl_context=trusting) as chat: + chat.connect() + tls_server.say("alice", "over TLS") + assert chat.read_message().text == "over TLS" + + # The default context does not know our test CA, so it must refuse the server. + with TwitchChat(**options) as untrusted, pytest.raises(ssl.SSLCertVerificationError): + untrusted.connect() + + +def test_token_never_reaches_the_debug_log(connect, caplog): + caplog.set_level(logging.DEBUG, logger="twitch_chat") + + connect() + + assert "> PASS ***" in caplog.text + assert TOKEN.removeprefix("oauth:") not in caplog.text + assert "< :tmi.twitch.tv 001 echo_bot :Welcome, GLHF!" in caplog.text + + +# ----- STEP 5 to 7: reading ------------------------------------------------------------ + + +def test_message_with_colons_and_tags(server, connect): + # Regression: the 2019 code returned only "look at this". + chat = connect() + server.say("alice", "look at this: https://example.com", display_name="Alice") + + message = chat.read_message() + + assert (message.channel, message.user, message.display_name) == ("demo", "alice", "Alice") + assert message.text == "look at this: https://example.com" + assert message.tags["user-id"] + + +def test_two_messages_in_one_packet(server, connect): + # Regression: the 2019 code returned the first and silently dropped the second. + chat = connect() + server.send_raw(f"{ALICE}first\r\n{ALICE}second\r\n".encode()) + + assert [chat.read_message().text, chat.read_message().text] == ["first", "second"] + + +def test_line_and_character_split_across_packets(server, connect): + # Regression: the 2019 code crashed (UnicodeDecodeError, then UnboundLocalError). + chat = connect() + data = f"{ALICE}你好,世界\r\n".encode() + cut = data.index("你".encode()) + 1 # inside the 3 bytes of 你 + reader = Background(chat.read_message) # already waiting in recv() when the first half arrives + time.sleep(0.1) + server.send_raw(data[:cut]) + time.sleep(0.1) + server.send_raw(data[cut:]) + + assert reader.join().text == "你好,世界" + + +def test_ping_gets_the_same_text_back_and_is_not_a_chat_message(server, connect): + # Regression: the 2019 code returned (None, None) for PING, and main.py crashed on it. + chat = connect() + server.ping("custom-ping-text") + server.say("alice", "after the ping") + + assert chat.read_message().text == "after the ping" + assert server.wait_for(lambda line: line.startswith("PONG")) == "PONG :custom-ping-text" + + +def test_ping_and_chat_in_the_same_packet(server, connect): + # Regression: the 2019 code reported user "tmi.twitch.tv\r\n" and echoed IRC protocol text. + chat = connect() + server.send_raw(f"PING :tmi.twitch.tv\r\n{ALICE}hello\r\n".encode()) + + message = chat.read_message() + + assert (message.user, message.text) == ("alice", "hello") + server.wait_for(lambda line: line == "PONG :tmi.twitch.tv") + + +def test_chat_text_that_says_ping_is_just_text(server, connect): + # Regression: the 2019 code answered PONG to any packet containing "PING :tmi.twitch.tv". + chat = connect() + server.say("alice", "PING :tmi.twitch.tv") + + assert chat.read_message().text == "PING :tmi.twitch.tv" + assert not [line for line in server.sent_lines() if line.startswith("PONG")] + + +def test_notices_are_logged(server, connect, caplog): + chat = connect() + server.send_line_to_all("@msg-id=msg_duplicate :tmi.twitch.tv NOTICE #demo :Your message is identical to the one you sent.") + server.say("alice", "next") + + assert chat.read_message().text == "next" + assert "Twitch notice: Your message is identical" in caplog.text + + +# ----- STEP 8: sending ------------------------------------------------------------------ + + +def test_send_message(server, connect): + connect().send_message("hello: chat") + + assert server.wait_for(lambda line: line.startswith("PRIVMSG")) == "PRIVMSG #demo :hello: chat" + + +def test_line_breaks_cannot_smuggle_in_another_command(server, connect): + chat = connect() + chat.send_message("one\r\nJOIN #someone_else\ntwo") + chat.send_message("done") + + server.wait_for(lambda line: line == "PRIVMSG #demo :done") + assert "PRIVMSG #demo :one JOIN #someone_else two" in server.sent_lines() + assert "JOIN #someone_else" not in server.sent_lines() + + +def test_sending_waits_for_the_rate_limit(server, connect): + assert DEFAULT_RATE_LIMITS == ((20, 30.0), (1, 1.0)) # Twitch's numbers for a normal bot + chat = connect(rate_limits=[(1, 0.3)]) + started = time.monotonic() + + chat.send_message("a") + chat.send_message("b") + + assert time.monotonic() - started >= 0.29 + server.wait_for(lambda line: line == "PRIVMSG #demo :b") + + +# ----- STEP 9: endings ------------------------------------------------------------------- + + +def test_server_hanging_up_raises_connection_closed(server, connect): + # Regression: the 2019 code returned (None, None) in a busy loop forever. + chat = connect() + server.disconnect_all() + + with pytest.raises(ConnectionClosed, match="closed the connection"): + chat.read_message() + + +def test_reconnect_request_raises_connection_closed_and_connect_starts_over(server, connect): + chat = connect() + server.request_reconnect() + + with pytest.raises(ConnectionClosed, match="reconnect"): + chat.read_message() + + chat.connect() + server.wait_for(lambda line: line == f"JOIN #{CHANNEL}", count=2) + server.say("alice", "welcome back") + assert chat.read_message().text == "welcome back" + + +def test_using_a_closed_chat_says_so(connect): + chat = connect() + chat.close() + + with pytest.raises(ConnectionClosed, match="not connected"): + chat.send_message("hi") diff --git a/twitch_chat.py b/twitch_chat.py new file mode 100644 index 0000000..5416622 --- /dev/null +++ b/twitch_chat.py @@ -0,0 +1,424 @@ +"""Talk to Twitch chat with nothing but a socket. + +Twitch chat is an IRC server: you open a connection, send short text commands, +and Twitch sends text lines back. This file does that by hand, so you can see +every step. Read it from top to bottom; each STEP matches a section of the README. + + STEP 1 open a connection (TLS) ............ TwitchChat._open_socket + STEP 2 ask for Twitch's extra features .... TwitchChat._request_capabilities + STEP 3 log in with PASS and NICK .......... TwitchChat._log_in + STEP 4 join a channel ..................... TwitchChat._join + STEP 5 cut the byte stream into lines ..... LineBuffer + STEP 6 split a line into its parts ........ parse_line + STEP 7 answer PING with PONG .............. TwitchChat._next_message + STEP 8 send a message, not too fast ....... TwitchChat.send_message, RateLimiter + STEP 9 notice when the connection ends .... ConnectionClosed + +Everything Twitch-specific below comes from Twitch's docs, checked on 2026-11-04: +https://dev.twitch.tv/docs/chat/irc/ and https://dev.twitch.tv/docs/chat/#rate-limits + +Only the Python standard library is used. +""" + +from __future__ import annotations + +import logging +import re +import socket +import ssl +import time +from collections import deque +from collections.abc import Callable, Iterable, Iterator +from dataclasses import dataclass, field + +log = logging.getLogger("twitch_chat") + +# ----- Where Twitch chat lives ------------------------------------------------- +TWITCH_IRC_HOST = "irc.chat.twitch.tv" +TWITCH_IRC_TLS_PORT = 6697 # encrypted, use this one +TWITCH_IRC_PLAIN_PORT = 6667 # not encrypted: your token travels in clear text + +# Extra features we ask for in STEP 2. "tags" adds details such as display-name +# to each message; Twitch only gives tags to bots that also ask for "commands". +DEFAULT_CAPABILITIES = ("twitch.tv/tags", "twitch.tv/commands") + +# How long to wait for Twitch to answer while logging in and joining (seconds). +HANDSHAKE_TIMEOUT = 15.0 + +# Twitch's limits for a bot that is not the broadcaster, a moderator or a VIP: +# at most 20 messages in any 30 seconds, and 1 message per second in a channel. +# Go over and Twitch ignores the bot's messages for an hour. Each pair is +# (messages, seconds). +DEFAULT_RATE_LIMITS = ((20, 30.0), (1, 1.0)) + +# STEP 9: seconds to wait before reconnecting after the 1st, 2nd, ... failure in a row. +RECONNECT_DELAYS = (1, 2, 4, 8, 16, 30) + +RECV_SIZE = 4096 # bytes to read per recv() call; any size works, see STEP 5 +ENCODING = "utf-8" + + +# ----- What can go wrong -------------------------------------------------------- +class TwitchChatError(Exception): + """Base class for the errors below.""" + + +class AuthenticationError(TwitchChatError): + """Twitch refused the login (STEP 3). Usually a wrong or expired token.""" + + +class JoinError(TwitchChatError): + """Twitch did not let us into the channel (STEP 4).""" + + +class ConnectionClosed(TwitchChatError, ConnectionError): + """The connection ended, or Twitch asked us to reconnect (STEP 9). Connect again.""" + + +def reconnect_delay(failures: int) -> int: + """STEP 9: wait longer after each failure in a row, so a broken network is not hammered.""" + return RECONNECT_DELAYS[min(failures, len(RECONNECT_DELAYS) - 1)] + + +def irc_password(token: str) -> str: + """The IRC password is the token with "oauth:" in front. Accept it with or without.""" + return token if token.startswith("oauth:") else "oauth:" + token + + +def default_port(use_tls: bool) -> int: + return TWITCH_IRC_TLS_PORT if use_tls else TWITCH_IRC_PLAIN_PORT + + +# ----- The client ------------------------------------------------------------------ +class TwitchChat: + """One bot account in one Twitch channel. + + >>> chat = TwitchChat(channel="your_channel", nick="your_bot", token="oauth:...") + >>> chat.connect() + >>> for message in chat.messages(): + ... chat.send_message(message.text) + """ + + def __init__( + self, + channel: str, + nick: str, + token: str, + *, + host: str = TWITCH_IRC_HOST, + port: int | None = None, + use_tls: bool = True, + capabilities: Iterable[str] = DEFAULT_CAPABILITIES, + rate_limits: Iterable[tuple[int, float]] = DEFAULT_RATE_LIMITS, + handshake_timeout: float = HANDSHAKE_TIMEOUT, + ssl_context: ssl.SSLContext | None = None, + ) -> None: + # Twitch wants lowercase names. Channels are written "#name" in IRC, + # so we accept both "name" and "#name" and store the bare name. + self.channel = channel.strip().lstrip("#").lower() + self.nick = nick.strip().lower() + self._password = irc_password(token) + self.host = host + self.port = port or default_port(use_tls) + self.use_tls = use_tls + self.capabilities = tuple(capabilities) + self.handshake_timeout = handshake_timeout + self._ssl_context = ssl_context + self._limiter = RateLimiter(rate_limits) + self._sock: socket.socket | None = None + self._buffer = LineBuffer() + self._lines: deque[str] = deque() + + # STEP 1 to 4 ------------------------------------------------------------------ + def connect(self) -> None: + """Open the connection, log in and join the channel. Returns once we are in. + Calling it again after ConnectionClosed starts over with a fresh connection.""" + self.close() + self._buffer = LineBuffer() # leftovers from an old connection mean nothing now + self._lines.clear() + self._sock = self._open_socket() # STEP 1 + try: + self._request_capabilities() # STEP 2 + self._log_in() # STEP 3 + self._join() # STEP 4 + except BaseException: + self.close() # don't leave a half-open connection behind + raise + self._sock.settimeout(None) # from now on, wait as long as chat is quiet + log.info("joined #%s as %s", self.channel, self.nick) + + def _open_socket(self) -> socket.socket: + """STEP 1: a TCP connection, wrapped in TLS so nobody can read the token.""" + log.info("connecting to %s:%s (%s)", self.host, self.port, "TLS" if self.use_tls else "plain text") + sock = socket.create_connection((self.host, self.port), timeout=self.handshake_timeout) + if not self.use_tls: + return sock + context = self._ssl_context or ssl.create_default_context() + return context.wrap_socket(sock, server_hostname=self.host) + + def _request_capabilities(self) -> None: + """STEP 2: CAP REQ asks for Twitch's extras. Twitch answers "CAP * ACK" (yes) + or "CAP * NAK" (no); we read that answer in STEP 3 together with the login reply. + """ + if self.capabilities: + self._send_line("CAP REQ :" + " ".join(self.capabilities)) + + def _log_in(self) -> None: + """STEP 3: PASS (the token) must come before NICK (the bot's login name). + + Success is a burst of numbered lines starting with "001". A wrong token gets + "NOTICE * :Login authentication failed" and Twitch hangs up. + """ + self._send_line("PASS " + self._password, secret=True) + self._send_line("NICK " + self.nick) + self._wait_for("001", error=AuthenticationError, waiting_for="the login reply") + + def _join(self) -> None: + """STEP 4: JOIN #channel. Twitch answers with JOIN, a member list (353) + and "366 ... :End of /NAMES list". For a channel that does not exist Twitch + answers nothing at all, which is why we wait with a timeout. + """ + self._send_line(f"JOIN #{self.channel}") + self._wait_for( + "366", + error=JoinError, + waiting_for=f"the JOIN reply (is #{self.channel} spelled right? Twitch ignores unknown channels)", + ) + + def _wait_for(self, command: str, *, error: type[TwitchChatError], waiting_for: str) -> IrcMessage: + """Read lines until Twitch sends ``command``. During login and join, a NOTICE + means Twitch said no, so it becomes ``error`` with Twitch's own words.""" + try: + while True: + message = self._next_message() + if message.command == command: + return message + if message.command == "NOTICE": + raise error(f"Twitch said: {message.trailing}") + if message.command == "CAP" and "NAK" in message.params: + log.warning("Twitch refused capabilities: %s", message.trailing) + except TimeoutError: + raise error(f"no answer from Twitch within {self.handshake_timeout:g} s while waiting for {waiting_for}") from None + + # STEP 5 to 7: reading ---------------------------------------------------------------- + def messages(self) -> Iterator[ChatMessage]: + """Chat messages, one after another, forever (until the connection ends).""" + while True: + yield self.read_message() + + def read_message(self) -> ChatMessage: + """Wait for the next chat message. PING and other server lines are handled here.""" + while True: + message = self._next_message() + if message.command == "PRIVMSG": + return ChatMessage.from_irc(message) + if message.command == "NOTICE": + # e.g. "Your message was not sent because you are sending messages too quickly." + log.warning("Twitch notice: %s", message.trailing) + + def _next_message(self) -> IrcMessage: + """Read one line (STEP 5), parse it (STEP 6) and handle the lines that are about + the connection itself (STEP 7 and STEP 9).""" + line = self._next_line() + log.debug("< %s", line) + message = parse_line(line) + if message.command == "PING": + # STEP 7: Twitch checks that we are still here. Answer with the same text + # it sent, or Twitch closes the connection. + self._send_line("PONG :" + message.trailing) + elif message.command == "RECONNECT": + # STEP 9: Twitch is about to restart this server; we should come back. + raise ConnectionClosed("Twitch asked us to reconnect (server maintenance)") + return message + + def _next_line(self) -> str: + """STEP 5: one complete line. recv() returns whatever bytes have arrived: + maybe half a line, maybe five lines. LineBuffer keeps the leftovers.""" + while not self._lines: + data = self._require_socket().recv(RECV_SIZE) + if not data: + # STEP 9: recv() returns b"" only when the other side closed the connection. + raise ConnectionClosed("Twitch closed the connection") + self._lines.extend(self._buffer.feed(data)) + return self._lines.popleft() + + # STEP 8: sending ---------------------------------------------------------------------- + def send_message(self, text: str) -> None: + """Say ``text`` in the channel. Waits first if we would go over the rate limit.""" + # One IRC line is one command, so a line break would end the message and + # start a new (unwanted) command. Twitch shows messages on one line anyway. + text = " ".join(text.splitlines()) + waited = self._limiter.wait() + if waited: + log.info("waited %.1f s to stay under Twitch's rate limit", waited) + self._send_line(f"PRIVMSG #{self.channel} :{text}") + + def _send_line(self, line: str, *, secret: bool = False) -> None: + """Every command goes out through here: text + CRLF, encoded as UTF-8.""" + if "\r" in line or "\n" in line: + raise ValueError("an IRC line cannot contain CR or LF") + log.debug("> %s", line.split(" ", 1)[0] + " ***" if secret else line) + self._require_socket().sendall((line + "\r\n").encode(ENCODING)) # sendall: send() may send only part + + # Housekeeping --------------------------------------------------------------------------- + def close(self) -> None: + if self._sock is not None: + self._sock.close() + self._sock = None + + def __enter__(self) -> TwitchChat: + return self + + def __exit__(self, *exc_info: object) -> None: + self.close() + + def _require_socket(self) -> socket.socket: + if self._sock is None: + raise ConnectionClosed("not connected; call connect() first") + return self._sock + + +# ----- STEP 5: from a byte stream to lines -------------------------------------------- +class LineBuffer: + """TCP delivers a stream of bytes, not messages. Twitch ends every line with + CRLF ("\\r\\n"), so we collect bytes and hand out only complete lines. + + We split the *bytes* and decode each finished line. Decoding chunk by chunk + would break when a character such as "你" (3 bytes in UTF-8) is cut in two. + """ + + def __init__(self) -> None: + self._pending = b"" + + def feed(self, data: bytes) -> list[str]: + *lines, self._pending = (self._pending + data).split(b"\n") + # rstrip("\r") also accepts a bare "\n"; errors="replace" keeps one bad byte from killing the bot + return [line.rstrip(b"\r").decode(ENCODING, errors="replace") for line in lines if line.strip()] + + +# ----- STEP 6: the parts of one line -------------------------------------------------- +@dataclass(frozen=True) +class IrcMessage: + """One IRC line, split into its four parts. See the picture in the README. + + @badge-info=;display-name=Alice;... :alice!alice@alice.tmi.twitch.tv PRIVMSG #demo :hi: there + |------------- tags --------------| |------------ prefix ------------| |command| |params----| + """ + + tags: dict[str, str] + prefix: str | None # who sent it: "nick!user@host", or a server name + command: str # PRIVMSG, PING, JOIN, NOTICE, or a number such as 001 + params: list[str] = field(default_factory=list) + + @property + def trailing(self) -> str: + """The last parameter, which is the only one that may contain spaces.""" + return self.params[-1] if self.params else "" + + @property + def nick(self) -> str | None: + """The sender's login name: the part of the prefix before "!".""" + return self.prefix.split("!", 1)[0] if self.prefix else None + + +def parse_line(line: str) -> IrcMessage: + """Split one IRC line (without its CRLF) into tags, prefix, command and params. + + Never use line.split(":") for this: the chat text itself may contain ":". + The rule is: the first " :" starts the last parameter, and everything after it, + colons and spaces included, belongs to that parameter. + """ + rest = line + tags: dict[str, str] = {} + if rest.startswith("@"): # IRCv3 tags: "@key=value;key2=value2 " + raw_tags, _, rest = rest[1:].partition(" ") + tags = parse_tags(raw_tags) + prefix = None + if rest.startswith(":"): # prefix: ":nick!user@host " + prefix, _, rest = rest[1:].partition(" ") + middle, has_trailing, trailing = rest.partition(" :") + command, *params = middle.split() + if has_trailing: + params.append(trailing) + return IrcMessage(tags=tags, prefix=prefix, command=command.upper(), params=params) + + +def parse_tags(raw: str) -> dict[str, str]: + """"badges=;display-name=Alice" -> {"badges": "", "display-name": "Alice"}""" + tags = {} + for item in filter(None, raw.split(";")): + key, _, value = item.partition("=") + tags[key] = unescape_tag_value(value) + return tags + + +# Tag values cannot contain ";" or spaces, so IRCv3 writes them as escapes. +# https://ircv3.net/specs/extensions/message-tags#escaping-values +_TAG_UNESCAPES = {":": ";", "s": " ", "\\": "\\", "r": "\r", "n": "\n"} + + +def unescape_tag_value(value: str) -> str: + r""""Hello\sthere" -> "Hello there". An unknown escape "\x" becomes "x", and a + lone "\" at the very end is dropped, as the spec says.""" + return re.sub(r"\\(.?)", lambda match: _TAG_UNESCAPES.get(match[1], match[1]), value) + + +@dataclass(frozen=True) +class ChatMessage: + """A chat message, the part of a PRIVMSG line a bot usually cares about.""" + + channel: str # without "#" + user: str # login name, lowercase + text: str + tags: dict[str, str] = field(default_factory=dict) + + @property + def display_name(self) -> str: + """How the name looks in chat (may have capitals or CJK); the login if not set.""" + return self.tags.get("display-name") or self.user + + @classmethod + def from_irc(cls, message: IrcMessage) -> ChatMessage: + # PRIVMSG params are [#channel, text] + return cls( + channel=message.params[0].lstrip("#"), + user=message.nick or "", + text=message.trailing, + tags=message.tags, + ) + + +# ----- STEP 8: staying under the rate limit --------------------------------------------- +class RateLimiter: + """Remembers when we sent recently, and waits when one more message would break + a rule such as "20 messages in any 30 seconds". + + ``rules`` is a list of (messages, seconds) pairs; all of them must hold. + ``clock`` and ``sleep`` can be swapped out in tests. + """ + + def __init__( + self, + rules: Iterable[tuple[int, float]], + *, + clock: Callable[[], float] = time.monotonic, + sleep: Callable[[float], None] = time.sleep, + ) -> None: + self.rules = tuple(rules) + self._clock = clock + self._sleep = sleep + self._sent: deque[float] = deque(maxlen=max((limit for limit, _ in self.rules), default=0)) + + def wait(self) -> float: + """Block until sending is allowed, record the send, and return the seconds waited.""" + now = self._clock() + # For "N messages per T seconds": the N-th most recent send must be at least T seconds ago. + ready_at = max( + (self._sent[-limit] + period for limit, period in self.rules if len(self._sent) >= limit), + default=now, + ) + delay = max(0.0, ready_at - now) + if delay: + self._sleep(delay) + self._sent.append(now + delay) + return delay From 9cc71c6b4f5c529f0ea564e7eb3944ffe6d30791 Mon Sep 17 00:00:00 2001 From: NatLee Date: Wed, 4 Nov 2026 07:26:36 +0800 Subject: [PATCH 3/7] fix: run the 2019 twitchSocket API on the new client Scripts written for the old version keep working with the same calls: twitchSocket(channelName=, botName=, botAuth=), getMsg() and sendMsg(), printing the same lines as before. Underneath they now use TwitchChat, so they get TLS and the bug fixes for free. One visible difference: getMsg() waits for the next chat message instead of returning (None, None) for PINGs. That (None, None) is what crashed the old main.py a few minutes after start, so nobody can have relied on it working. All old names live in twitchSocket.py, which emits a DeprecationWarning and says when it can go (not before 2027-11-04). --- tests/test_legacy.py | 62 ++++++++++++++++++++++ twitchSocket.py | 121 ++++++++++++++++++++----------------------- 2 files changed, 119 insertions(+), 64 deletions(-) create mode 100644 tests/test_legacy.py diff --git a/tests/test_legacy.py b/tests/test_legacy.py new file mode 100644 index 0000000..c760b8e --- /dev/null +++ b/tests/test_legacy.py @@ -0,0 +1,62 @@ +"""The 2019 names in twitchSocket.py must keep working. + +Delete this file together with twitchSocket.py (not before 2027-11-04, see that file). +""" + +from __future__ import annotations + +import pytest + +from tests.conftest import CHANNEL, TOKEN +from twitchSocket import twitchSocket + + +@pytest.fixture +def legacy(server): + """The 2019 call, plus the options that point it at the fake server instead of Twitch.""" + + def _open(*args, **kwargs): + with pytest.warns(DeprecationWarning, match="twitch_chat.TwitchChat"): + return twitchSocket(*args, **kwargs, host=server.host, port=server.port, use_tls=False) + + return _open + + +def test_old_keyword_call_joins_in_the_constructor(server, legacy): + ts = legacy(channelName=CHANNEL, botName="Echo_Bot", botAuth=TOKEN) + + server.wait_for_join() + assert server.sent_lines()[-1] == f"JOIN #{CHANNEL}" + ts.close() + + +def test_old_positional_call(server, legacy): + legacy(CHANNEL, "echo_bot", TOKEN).close() + + +def test_getmsg_and_sendmsg_print_like_before(server, legacy, capsys): + ts = legacy(channelName=CHANNEL, botName="Echo_Bot", botAuth=TOKEN) + server.say("alice", "hi: there") + + assert ts.getMsg() == ("alice", "hi: there") + ts.sendMsg("hello") + + server.wait_for(lambda line: line == "PRIVMSG #demo :hello") + assert capsys.readouterr().out == "alice: hi: there\nEcho_Bot: hello\n" + ts.close() + + +def test_the_2019_main_loop_survives_a_ping(server, legacy): + # Regression: in 2019, getMsg() returned (None, None) for a PING and the next line, + # ts.sendMsg(message), raised TypeError, which main.py did not catch. + ts = legacy(channelName=CHANNEL, botName="echo_bot", botAuth=TOKEN) + server.ping() + server.say("alice", "still here?") + + username, message = ts.getMsg() # the body of the 2019 main.py loop + ts.sendMsg(message) + + assert (username, message) == ("alice", "still here?") + server.wait_for(lambda line: line == "PRIVMSG #demo :still here?") + assert "PONG :tmi.twitch.tv" in server.sent_lines() + ts.close() diff --git a/twitchSocket.py b/twitchSocket.py index 80286ec..c6c5cbc 100644 --- a/twitchSocket.py +++ b/twitchSocket.py @@ -1,64 +1,57 @@ -import socket - - -class twitchSocket(object): - def __init__(self, channelName:str, botName:str, botAuth:str): - self.__HOST = 'irc.twitch.tv' - self.__PORT = 6667 - self.__NICK = botName - self.__PASS = botAuth - self.__CHANNEL = channelName - - self.__s = self.__setSocket() - - while True: - if 'End of /NAMES list' in self.__getPacket(): - break - - def __setSocket(self) -> socket: - s = socket.socket() - s.connect((self.__HOST, self.__PORT)) - s.send(bytes('PASS ' + self.__PASS + '\r\n', 'UTF-8')) - s.send(bytes('NICK ' + self.__NICK + '\r\n', 'UTF-8')) - s.send(bytes('JOIN #' + self.__CHANNEL + '\r\n', 'UTF-8')) - - return s - - def sendMsg(self, message:str): - self.__s.send(bytes('PRIVMSG #' + self.__CHANNEL + ' :' + message + '\r\n', 'UTF-8')) - print(self.__NICK + ': ' + message) - - def __sendPong(self): - self.__s.send(bytes('PONG :tmi.twitch.tv\r\n', 'UTF-8')) - - def __getPacket(self) -> str: - return self.__s.recv(1024).rstrip().decode('UTF-8') - - def __getDataFromPacket(self) -> str: - # rawData Sample: - # :usr!usr@usr.tmi.twitch.tv PRIVMSG #channel :string - rawData = self.__getPacket() - if 'PING :tmi.twitch.tv' in rawData: - self.__sendPong() - # Filter the twitch send <3 - # Avoid twitch ping you without any message. - if len(rawData.split(':')) < 3: - return None - return rawData - - def getMsg(self) -> tuple: - username = None - message = None - try: - rawData = self.__getDataFromPacket() - # get message and username with extracting raw data. - if rawData is not None: - username = rawData.split(':')[1].split('!')[0] - message = rawData.split(':')[2].strip() - print(username + ': '+ message) - except Exception as e: - print(rawData) - print(e) - - return username, message - +"""The 2019 names, kept so scripts written for the old version keep working. + + from twitchSocket import twitchSocket + + ts = twitchSocket(channelName="...", botName="...", botAuth="oauth:...") + username, message = ts.getMsg() + ts.sendMsg(message) + +New code should use ``twitch_chat.TwitchChat`` (PEP 8 names, see the README). +This file is the only place that knows the old names; nothing else imports it. + +What changed underneath (all bug fixes, same calls): +* it connects to irc.chat.twitch.tv:6697 with TLS instead of irc.twitch.tv:6667 in plain text; +* getMsg() waits for the next real chat message. It used to return (None, None) for + PINGs and other server lines, and main.py then crashed on sendMsg(None); +* messages that contain ":" come through whole, and the other 2019 bugs listed in the + README ("What the 2019 version got wrong") are gone too. + +When can this file go? Not before 2027-11-04, one year after the new names were +announced in the README. Before deleting it, search GitHub for "from twitchSocket import" +to see whether anyone still uses it, then remove this file and its test +(tests/test_legacy.py) and the "Code from 2019" section of the README together. +""" + +from __future__ import annotations + +import warnings +from typing import Any + +from twitch_chat import TwitchChat + + +class twitchSocket(TwitchChat): # noqa: N801 - the 2019 name, on purpose + def __init__(self, channelName: str, botName: str, botAuth: str, **options: Any) -> None: # noqa: N803 + """Connects and joins right away, like the 2019 version did. + + ``options`` go to TwitchChat (host, port, use_tls, ...); old code passes none. + """ + warnings.warn( + "twitchSocket is the 2019 name; use twitch_chat.TwitchChat (see README)", + DeprecationWarning, + stacklevel=2, + ) + super().__init__(channel=channelName, nick=botName, token=botAuth, **options) + self._bot_name = botName # printed as given, like before + self.connect() + + def getMsg(self) -> tuple[str, str]: # noqa: N802 + """Wait for the next chat message; print and return (username, message).""" + message = self.read_message() + print(message.user + ": " + message.text) + return message.user, message.text + + def sendMsg(self, message: str) -> None: # noqa: N802 + """Send ``message`` to the channel and print it.""" + self.send_message(message) + print(self._bot_name + ": " + message) From 01098fd4b93d44bd7c82e4983c17441225e90644 Mon Sep 17 00:00:00 2001 From: NatLee Date: Wed, 4 Nov 2026 07:27:16 +0800 Subject: [PATCH 4/7] feat: read settings from .env and reconnect in main.py The token used to be pasted into main.py, one commit away from being public. main.py now reads TWITCH_CHANNEL, TWITCH_BOT_NAME and TWITCH_OAUTH_TOKEN from the environment or a .env file (ignored by git; .env.example is the template), plus optional TWITCH_IRC_HOST, TWITCH_IRC_PORT and TWITCH_IRC_TLS to point it at the practice server. When the connection drops or Twitch sends RECONNECT, the bot waits 1, 2, 4 ... 30 s and connects again. A wrong token or channel stops it with Twitch's own message instead, since retrying won't help. --debug prints every raw IRC line, with the token masked. --- .env.example | 20 +++++++ .gitignore | 15 +++-- config.py | 74 +++++++++++++++++++++++ main.py | 87 +++++++++++++++++++++++---- tests/test_main.py | 144 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 326 insertions(+), 14 deletions(-) create mode 100644 .env.example create mode 100644 config.py create mode 100644 tests/test_main.py diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..27220a6 --- /dev/null +++ b/.env.example @@ -0,0 +1,20 @@ +# Copy this file to .env and fill it in: cp .env.example .env +# .env is listed in .gitignore. Never commit a real token. +# How to get a token and which scopes it needs: README, "Get a token". + +# The channel to join: a Twitch login name, without the # +TWITCH_CHANNEL=your_channel + +# The bot account's login name. It must be the account the token belongs to. +TWITCH_BOT_NAME=your_bot_account + +# A user access token of the bot account, with or without "oauth:" in front. +# Scopes: chat:read chat:edit (main.py and examples/irc_library_echo.py) +# user:read:chat user:write:chat (examples/eventsub_echo.py) +TWITCH_OAUTH_TOKEN= + +# Optional. Leave these out to use the real Twitch chat (irc.chat.twitch.tv:6697 with TLS). +# For the practice server (python tools/fake_twitch_server.py) use: +# TWITCH_IRC_HOST=127.0.0.1 +# TWITCH_IRC_PORT=6667 +# TWITCH_IRC_TLS=false diff --git a/.gitignore b/.gitignore index e4824e8..fd844f3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,14 @@ -__pycache__ +# your settings and token (copy .env.example) +.env -.DS_Store +# Python +__pycache__/ +*.py[cod] +.venv/ +.pytest_cache/ +.ruff_cache/ +# editors and OS +.vscode/ +.DS_Store desktop.ini - -.vscode \ No newline at end of file diff --git a/config.py b/config.py new file mode 100644 index 0000000..c68853c --- /dev/null +++ b/config.py @@ -0,0 +1,74 @@ +"""Settings for the bots in this repo, read from environment variables. + +Keep the token out of your code: put it in a file called .env next to this one +(copy .env.example and fill it in). .env is in .gitignore, so git will not pick it up. +Variables that are already set in your shell win over the file. +""" + +from __future__ import annotations + +import os +from collections.abc import Mapping, MutableMapping +from dataclasses import dataclass +from pathlib import Path + +from twitch_chat import TWITCH_IRC_HOST + +ENV_FILE = Path(__file__).with_name(".env") + +# name of the environment variable -> what goes in it +REQUIRED = { + "TWITCH_CHANNEL": "the channel to join, e.g. your own login name", + "TWITCH_BOT_NAME": "the login name of the bot account", + "TWITCH_OAUTH_TOKEN": "a user access token of the bot account (see README: Get a token)", +} +FALSE_WORDS = {"0", "false", "no", "off"} + + +class ConfigError(Exception): + """A required setting is missing or has a bad value.""" + + +@dataclass(frozen=True) +class Settings: + channel: str + bot_name: str + token: str + host: str = TWITCH_IRC_HOST + port: int | None = None # None: the usual port for TLS or plain text + use_tls: bool = True + + @classmethod + def from_env(cls, environ: Mapping[str, str] = os.environ) -> Settings: + missing = [name for name in REQUIRED if not environ.get(name, "").strip()] + if missing: + lines = [f" {name}: {REQUIRED[name]}" for name in missing] + raise ConfigError("missing settings (put them in .env, see .env.example):\n" + "\n".join(lines)) + port = environ.get("TWITCH_IRC_PORT", "").strip() + if port and not port.isdigit(): + raise ConfigError(f"TWITCH_IRC_PORT must be a number, got {port!r}") + return cls( + channel=environ["TWITCH_CHANNEL"].strip(), + bot_name=environ["TWITCH_BOT_NAME"].strip(), + token=environ["TWITCH_OAUTH_TOKEN"].strip(), + host=environ.get("TWITCH_IRC_HOST", "").strip() or TWITCH_IRC_HOST, + port=int(port) if port else None, + use_tls=environ.get("TWITCH_IRC_TLS", "true").strip().lower() not in FALSE_WORDS, + ) + + +def load_env_file(path: Path = ENV_FILE, environ: MutableMapping[str, str] = os.environ) -> None: + """Copy KEY=value lines from ``path`` into ``environ``, without overwriting. + + A small stand-in for the python-dotenv package, so the bot needs nothing + outside the standard library. Blank lines and lines starting with # are skipped; + quotes around a value are removed. + """ + if not path.is_file(): + return + for raw in path.read_text(encoding="utf-8").splitlines(): + line = raw.strip() + if not line or line.startswith("#") or "=" not in line: + continue + key, _, value = line.partition("=") + environ.setdefault(key.strip(), value.strip().strip("'\"")) diff --git a/main.py b/main.py index bd3a609..aeb627e 100644 --- a/main.py +++ b/main.py @@ -1,14 +1,81 @@ -from twitchSocket import twitchSocket +"""Twitch echo bot: repeats every chat message back into the channel. -ts = twitchSocket(channelName='', - botName ='', - botAuth =' None: + """The bot's logic: read a message, send the same text back.""" + for message in chat.messages(): + print(f"#{message.channel} {message.display_name}: {message.text}", flush=True) + reply = message.text # <- change this line to make your own bot + chat.send_message(reply) + print(f"#{chat.channel} {chat.nick} (bot): {reply}", flush=True) + + +def run(settings: Settings, *, sleep: Callable[[float], None] = time.sleep) -> None: + """Connect, echo, and reconnect whenever the connection ends.""" + failures = 0 + while True: + chat = TwitchChat( + channel=settings.channel, + nick=settings.bot_name, + token=settings.token, + host=settings.host, + port=settings.port, + use_tls=settings.use_tls, + ) + try: + with chat: + chat.connect() + failures = 0 + echo(chat) + except OSError as error: # includes ConnectionClosed, refused connections, network trouble + delay = reconnect_delay(failures) + failures += 1 + log.warning("connection lost (%s); reconnecting in %s s", error, delay) + sleep(delay) + + +def main(argv: list[str] | None = None) -> int: + parser = argparse.ArgumentParser(description="Twitch echo bot") + parser.add_argument("--debug", action="store_true", help="print every IRC line sent and received") + args = parser.parse_args(argv) + logging.basicConfig( + level=logging.DEBUG if args.debug else logging.INFO, + format="%(asctime)s %(levelname)-7s %(message)s", + datefmt="%H:%M:%S", + ) + load_env_file() try: - username, message = ts.getMsg() - # Your logic here. - ts.sendMsg(message) + run(Settings.from_env()) + except ConfigError as error: + print(f"error: {error}", file=sys.stderr) + return 2 + except (AuthenticationError, JoinError) as error: + # Retrying will not help here: fix the token or the channel name first. + print(f"error: {error}", file=sys.stderr) + return 1 + except KeyboardInterrupt: + print("bye", file=sys.stderr) + return 0 + - except(KeyboardInterrupt, EOFError, SystemExit): - break +if __name__ == "__main__": + sys.exit(main()) diff --git a/tests/test_main.py b/tests/test_main.py new file mode 100644 index 0000000..36b033d --- /dev/null +++ b/tests/test_main.py @@ -0,0 +1,144 @@ +"""config.py and main.py: settings, the echo loop, reconnecting, and the real command line.""" + +from __future__ import annotations + +import os +import subprocess +import sys +from pathlib import Path + +import pytest + +import main +from config import REQUIRED, ConfigError, Settings, load_env_file +from tests.conftest import BOT, CHANNEL, TOKEN, Background, StopBot +from twitch_chat import TWITCH_IRC_HOST + +REPO = Path(__file__).resolve().parents[1] +GOOD_ENV = {"TWITCH_CHANNEL": CHANNEL, "TWITCH_BOT_NAME": BOT, "TWITCH_OAUTH_TOKEN": TOKEN} + + +def fake_server_env(server) -> dict[str, str]: + return {**GOOD_ENV, "TWITCH_IRC_HOST": server.host, "TWITCH_IRC_PORT": str(server.port), "TWITCH_IRC_TLS": "false"} + + +# ----- config.py ---------------------------------------------------------------------- + + +def test_missing_settings_are_all_named(): + with pytest.raises(ConfigError) as error: + Settings.from_env({"TWITCH_CHANNEL": " "}) + + for name in REQUIRED: + assert name in str(error.value) + + +def test_settings_default_to_real_twitch_over_tls(): + settings = Settings.from_env(GOOD_ENV) + + assert (settings.host, settings.port, settings.use_tls) == (TWITCH_IRC_HOST, None, True) + + +@pytest.mark.parametrize("word", ["false", "0", "No", "OFF"]) +def test_settings_for_the_practice_server(word): + settings = Settings.from_env({**GOOD_ENV, "TWITCH_IRC_HOST": "127.0.0.1", "TWITCH_IRC_PORT": "6667", "TWITCH_IRC_TLS": word}) + + assert (settings.host, settings.port, settings.use_tls) == ("127.0.0.1", 6667, False) + + +def test_bad_port_is_a_config_error(): + with pytest.raises(ConfigError, match="TWITCH_IRC_PORT"): + Settings.from_env({**GOOD_ENV, "TWITCH_IRC_PORT": "six"}) + + +def test_env_file_is_read_without_overwriting(tmp_path): + env_file = tmp_path / ".env" + env_file.write_text( + "# a comment\n\nTWITCH_CHANNEL = demo\nTWITCH_BOT_NAME='echo_bot'\n" + "TWITCH_OAUTH_TOKEN=\"oauth:from-file\"\nnot a setting\n", + encoding="utf-8", + ) + environ = {"TWITCH_OAUTH_TOKEN": "oauth:from-shell"} + + load_env_file(env_file, environ) + + assert environ == {"TWITCH_CHANNEL": "demo", "TWITCH_BOT_NAME": "echo_bot", "TWITCH_OAUTH_TOKEN": "oauth:from-shell"} + + +def test_missing_env_file_is_fine(tmp_path): + environ: dict[str, str] = {} + load_env_file(tmp_path / "nope.env", environ) + assert environ == {} + + +def test_env_example_lists_every_setting(): + example = (REPO / ".env.example").read_text(encoding="utf-8") + + for name in [*REQUIRED, "TWITCH_IRC_HOST", "TWITCH_IRC_PORT", "TWITCH_IRC_TLS"]: + assert name in example + + +# ----- main.py ------------------------------------------------------------------------ + + +def test_run_echoes_and_reconnects(server, capsys): + sleeps: list[float] = [] + + def fake_sleep(seconds: float) -> None: + sleeps.append(seconds) + if len(sleeps) == 2: + raise StopBot + + bot = Background(lambda: main.run(Settings.from_env(fake_server_env(server)), sleep=fake_sleep)) + + server.wait_for_join() + server.say("alice", "hello: bot", display_name="Alice") + server.wait_for(lambda line: line == "PRIVMSG #demo :hello: bot") + + server.request_reconnect() # Twitch's "please come back" -> the bot reconnects after 1 s + server.wait_for_join(count=2) + server.say("bob", "again") + server.wait_for(lambda line: line == "PRIVMSG #demo :again") + + server.disconnect_all() # second loss: the fake sleep ends the test + with pytest.raises(StopBot): + bot.join() + assert sleeps == [1, 1] # the failure count starts over after each good connection + out = capsys.readouterr().out + assert "#demo Alice: hello: bot\n#demo echo_bot (bot): hello: bot\n" in out + + +def test_main_stops_on_a_wrong_token(server, monkeypatch, capsys): + monkeypatch.setattr(main, "load_env_file", lambda: None) + for name, value in {**fake_server_env(server), "TWITCH_OAUTH_TOKEN": "oauth:wrong"}.items(): + monkeypatch.setenv(name, value) + + assert main.main([]) == 1 + assert "Login authentication failed" in capsys.readouterr().err + + +def test_main_explains_missing_settings(monkeypatch, capsys): + monkeypatch.setattr(main, "load_env_file", lambda: None) + for name in REQUIRED: + monkeypatch.delenv(name, raising=False) + + assert main.main([]) == 2 + assert ".env.example" in capsys.readouterr().err + + +def test_python_main_py_end_to_end(server): + """The command from the README, as a real process.""" + env = {**os.environ, **fake_server_env(server), "PYTHONUNBUFFERED": "1"} + with subprocess.Popen([sys.executable, "main.py", "--debug"], cwd=REPO, env=env, + stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True) as bot: + try: + server.wait_for_join(timeout=10) + server.say("alice", "end to end") + server.wait_for(lambda line: line == "PRIVMSG #demo :end to end") + finally: + bot.terminate() + output = bot.communicate(timeout=10)[0] + + assert "> PASS ***" in output + assert TOKEN.removeprefix("oauth:") not in output + assert "#demo alice: end to end" in output From 8875df89206294520386925b9fd413dacb8c9fa5 Mon Sep 17 00:00:00 2001 From: NatLee Date: Wed, 4 Nov 2026 07:27:58 +0800 Subject: [PATCH 5/7] feat: add the echo bot on the irc package and on EventSub Issue #1 asked why the bot doesn't use a ready-made IRC package. examples/irc_library_echo.py is the same bot on the irc package, so you can see what a package takes off your hands and what is still Twitch-specific. The README explains why the lesson keeps a raw socket. examples/eventsub_echo.py is the "next step": Twitch now recommends EventSub plus the Send Chat Message API over IRC. It follows Twitch's example chatbot (validate the token, look up ids, subscribe within 10 s of the welcome, skip the bot's own messages). Both are tested: the irc version against the fake IRC server, the EventSub version against small fakes of the Twitch API and EventSub WebSocket. Neither has run against the real Twitch. --- examples/eventsub_echo.py | 225 +++++++++++++++++++++++++++++++++++ examples/irc_library_echo.py | 85 +++++++++++++ examples/requirements.txt | 3 + requirements-dev.txt | 1 + tests/test_examples.py | 203 +++++++++++++++++++++++++++++++ 5 files changed, 517 insertions(+) create mode 100644 examples/eventsub_echo.py create mode 100644 examples/irc_library_echo.py create mode 100644 examples/requirements.txt create mode 100644 tests/test_examples.py diff --git a/examples/eventsub_echo.py b/examples/eventsub_echo.py new file mode 100644 index 0000000..06c91fb --- /dev/null +++ b/examples/eventsub_echo.py @@ -0,0 +1,225 @@ +"""Next step: the echo bot on the stack Twitch recommends today. + +Twitch's docs now say: read chat with EventSub (Twitch pushes events to you over a +WebSocket) and send with the Send Chat Message API, instead of IRC +(https://dev.twitch.tv/docs/chat/). This is the same bot built that way. It follows +Twitch's own example chatbot (https://dev.twitch.tv/docs/chat/chatbot-guide/): + + 1. check the token and learn who we are ........ GET id.twitch.tv/oauth2/validate + 2. look up the channel's user id ................ GET /helix/users?login=... + 3. open the EventSub WebSocket, read "welcome" .. wss://eventsub.wss.twitch.tv/ws + 4. subscribe to chat within 10 seconds .......... POST /helix/eventsub/subscriptions + 5. for every chat message, send it back ......... POST /helix/chat/messages + +Run it from the repo root with the same .env as main.py. The token needs the scopes +user:read:chat and user:write:chat (IRC used chat:read and chat:edit instead): + + pip install -r examples/requirements.txt + python -m examples.eventsub_echo +""" + +from __future__ import annotations + +import json +import logging +import os +import sys +import time +import urllib.error +import urllib.parse +import urllib.request +from collections.abc import Callable, Mapping +from dataclasses import dataclass +from typing import Any + +from websockets.exceptions import ConnectionClosed, WebSocketException +from websockets.sync.client import connect + +from config import ConfigError, Settings, load_env_file +from twitch_chat import DEFAULT_RATE_LIMITS, RateLimiter, reconnect_delay + +log = logging.getLogger("eventsub_echo") + +TWITCH_ID_URL = "https://id.twitch.tv/oauth2" +TWITCH_API_URL = "https://api.twitch.tv/helix" +EVENTSUB_WS_URL = "wss://eventsub.wss.twitch.tv/ws" +REQUIRED_SCOPES = ("user:read:chat", "user:write:chat") +WELCOME_TIMEOUT = 10.0 # Twitch closes the WebSocket if we have not subscribed 10 s after "welcome" +KEEPALIVE_MARGIN = 5.0 # extra seconds on top of Twitch's keepalive_timeout_seconds +HTTP_TIMEOUT = 15.0 + + +class TwitchAPIError(Exception): + pass + + +@dataclass(frozen=True) +class Endpoints: + """Where the three Twitch services live. Tests point these at fake servers.""" + + id_url: str = TWITCH_ID_URL + api_url: str = TWITCH_API_URL + eventsub_url: str = EVENTSUB_WS_URL + + @classmethod + def from_env(cls, environ: Mapping[str, str] = os.environ) -> Endpoints: + return cls( + id_url=environ.get("TWITCH_ID_URL") or TWITCH_ID_URL, + api_url=environ.get("TWITCH_API_URL") or TWITCH_API_URL, + eventsub_url=environ.get("TWITCH_EVENTSUB_URL") or EVENTSUB_WS_URL, + ) + + +class TwitchAPI: + """Just the four HTTP calls this bot needs.""" + + def __init__(self, token: str, endpoints: Endpoints) -> None: + self.token = token.removeprefix("oauth:") # IRC wants "oauth:", the API does not + self.endpoints = endpoints + self.client_id = "" + self.user_id = "" + self.login = "" + + def validate(self) -> list[str]: + """Step 1: who does this token belong to, and what may it do? Returns its scopes.""" + info = self._call("GET", f"{self.endpoints.id_url}/validate", auth=f"OAuth {self.token}") + self.client_id, self.user_id, self.login = info["client_id"], info["user_id"], info["login"] + return info.get("scopes", []) + + def user_id_of(self, login: str) -> str: + """Step 2: EventSub and the API use numeric user ids, not names.""" + query = urllib.parse.urlencode({"login": login.lstrip("#").lower()}) + users = self._call("GET", f"{self.endpoints.api_url}/users?{query}")["data"] + if not users: + raise TwitchAPIError(f"no Twitch user called {login!r}") + return users[0]["id"] + + def subscribe_to_chat(self, session_id: str, broadcaster_id: str) -> None: + """Step 4: ask Twitch to push this channel's chat messages to our WebSocket.""" + self._call("POST", f"{self.endpoints.api_url}/eventsub/subscriptions", expect=202, body={ + "type": "channel.chat.message", + "version": "1", + "condition": {"broadcaster_user_id": broadcaster_id, "user_id": self.user_id}, + "transport": {"method": "websocket", "session_id": session_id}, + }) + + def send_chat_message(self, broadcaster_id: str, text: str) -> dict[str, Any]: + """Step 5: say something. Twitch answers whether it really went out (is_sent).""" + return self._call("POST", f"{self.endpoints.api_url}/chat/messages", body={ + "broadcaster_id": broadcaster_id, + "sender_id": self.user_id, + "message": text, + })["data"][0] + + def _call(self, method: str, url: str, *, expect: int = 200, body: dict | None = None, auth: str | None = None) -> dict: + headers = {"Authorization": auth or f"Bearer {self.token}", "Client-Id": self.client_id} + data = None + if body is not None: + headers["Content-Type"] = "application/json" + data = json.dumps(body).encode() + request = urllib.request.Request(url, data=data, method=method, headers=headers) + try: + with urllib.request.urlopen(request, timeout=HTTP_TIMEOUT) as response: + status, payload = response.status, response.read() + except urllib.error.HTTPError as error: + status, payload = error.code, error.read() + if status != expect: + raise TwitchAPIError(f"{method} {url} -> HTTP {status}: {payload.decode(errors='replace')}") + return json.loads(payload or b"{}") + + +class EchoBot: + def __init__(self, settings: Settings, endpoints: Endpoints) -> None: + self.settings = settings + self.endpoints = endpoints + self.api = TwitchAPI(settings.token, endpoints) + self.limiter = RateLimiter(DEFAULT_RATE_LIMITS) + self.broadcaster_id = "" + + def prepare(self) -> None: + """Steps 1 and 2, done once.""" + scopes = self.api.validate() + missing = [scope for scope in REQUIRED_SCOPES if scope not in scopes] + if missing: + raise TwitchAPIError(f"the token is missing the scopes {missing}; get a new one (README: Get a token)") + if self.api.login != self.settings.bot_name.lower(): + log.warning("the token belongs to %s, not TWITCH_BOT_NAME=%s", self.api.login, self.settings.bot_name) + self.broadcaster_id = self.api.user_id_of(self.settings.channel) + + def listen(self) -> None: + """Steps 3 to 5. Returns when Twitch closes the connection.""" + url, subscribed = self.endpoints.eventsub_url, False + try: + while True: + with connect(url) as websocket: + welcome = json.loads(websocket.recv(timeout=WELCOME_TIMEOUT)) + session = welcome["payload"]["session"] + if not subscribed: # after a session_reconnect, Twitch moves our subscription over + self.api.subscribe_to_chat(session["id"], self.broadcaster_id) + subscribed = True + print(f"listening to #{self.settings.channel} as {self.api.login}", flush=True) + url = self._read_events(websocket, session["keepalive_timeout_seconds"] + KEEPALIVE_MARGIN) + # Simplification: Twitch suggests keeping the old socket open until the new one + # says "welcome", so that no event is lost in between. We close it first. + except ConnectionClosed as closed: + log.warning("Twitch closed the EventSub connection (%s)", closed) + + def _read_events(self, websocket: Any, timeout: float) -> str: + """Handle messages until Twitch tells us to move to another server (returns its URL).""" + while True: + # EventSub's version of PING: if nothing (not even a keepalive) arrives in time, + # the connection is dead and recv() raises TimeoutError. + message = json.loads(websocket.recv(timeout=timeout)) + kind = message["metadata"]["message_type"] + if kind == "notification": + self.on_chat_message(message["payload"]["event"]) + elif kind == "session_reconnect": + return message["payload"]["session"]["reconnect_url"] + elif kind == "revocation": + raise TwitchAPIError(f"Twitch cancelled the subscription: {message['payload']['subscription']['status']}") + # "session_keepalive" needs no answer: it only proves the connection is alive. + + def on_chat_message(self, event: dict[str, Any]) -> None: + if event["chatter_user_id"] == self.api.user_id: + return # unlike IRC, EventSub also delivers the bot's own messages; echoing them would never end + text = event["message"]["text"] + print(f"#{event['broadcaster_user_login']} {event['chatter_user_name']}: {text}", flush=True) + self.limiter.wait() + result = self.api.send_chat_message(self.broadcaster_id, text) + if not result["is_sent"]: + log.warning("Twitch did not send it: %s", result.get("drop_reason")) + return + print(f"#{event['broadcaster_user_login']} {self.api.login} (bot): {text}", flush=True) + + +def run(settings: Settings, endpoints: Endpoints, *, sleep: Callable[[float], None] = time.sleep) -> None: + bot = EchoBot(settings, endpoints) + bot.prepare() + failures = 0 + while True: + try: + bot.listen() # returns after a session that worked and then ended + failures = 0 + except (OSError, WebSocketException) as error: # timeouts, refused connections, bad handshakes + log.warning("could not stay connected (%r)", error) + failures += 1 + delay = reconnect_delay(failures) + log.info("reconnecting in %s s", delay) + sleep(delay) + + +def main() -> int: + logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)-7s %(message)s", datefmt="%H:%M:%S") + load_env_file() + try: + run(Settings.from_env(), Endpoints.from_env()) + except (ConfigError, TwitchAPIError) as error: + print(f"error: {error}", file=sys.stderr) + return 1 + except KeyboardInterrupt: + print("bye", file=sys.stderr) + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/examples/irc_library_echo.py b/examples/irc_library_echo.py new file mode 100644 index 0000000..413ee03 --- /dev/null +++ b/examples/irc_library_echo.py @@ -0,0 +1,85 @@ +"""The same echo bot, written with a ready-made IRC package. + +Issue #1 asked: why not use an existing IRC package? Fair question. Here is the bot +on top of `irc` (https://pypi.org/project/irc/), the package Twitch's own old Python +sample used. Put it next to main.py + twitch_chat.py and compare: + +* the package opens the socket, splits lines, parses them, answers PING and + reconnects with back-off (STEP 1, 5, 6, 7 and 9 in twitch_chat.py); +* we still do the Twitch-specific parts: the oauth: password, CAP REQ, JOIN, + reading the display-name tag and the rate limit (STEP 2, 3, 4 and 8). + +Run it from the repo root, with the same .env as main.py: + + pip install -r examples/requirements.txt + python -m examples.irc_library_echo +""" + +from __future__ import annotations + +import functools +import logging +import ssl +import sys + +import irc.bot +import irc.client +import irc.connection +from jaraco.stream import buffer + +from config import ConfigError, Settings, load_env_file +from twitch_chat import DEFAULT_CAPABILITIES, DEFAULT_RATE_LIMITS, RateLimiter, default_port, irc_password + +# Chat text is not always valid UTF-8; the package's documented way to cope with that. +irc.client.ServerConnection.buffer_class = buffer.LenientDecodingLineBuffer + + +class EchoBot(irc.bot.SingleServerIRCBot): + def __init__(self, settings: Settings) -> None: + self.channel = "#" + settings.channel.lstrip("#").lower() + self.limiter = RateLimiter(DEFAULT_RATE_LIMITS) + server = irc.bot.ServerSpec(settings.host, settings.port or default_port(settings.use_tls), irc_password(settings.token)) + super().__init__([server], settings.bot_name.lower(), settings.bot_name, connect_factory=connect_factory(settings)) + + def on_welcome(self, connection: irc.client.ServerConnection, event: irc.client.Event) -> None: + """Logged in (Twitch sent 001): ask for tags, then join.""" + connection.cap("REQ", ":" + " ".join(DEFAULT_CAPABILITIES)) + connection.join(self.channel) + + def on_join(self, connection: irc.client.ServerConnection, event: irc.client.Event) -> None: + print(f"joined {event.target} as {connection.get_nickname()}", flush=True) + + def on_pubmsg(self, connection: irc.client.ServerConnection, event: irc.client.Event) -> None: + """A chat message. event.arguments[0] is the text, already parsed for us.""" + text = event.arguments[0] + tags = {tag["key"]: tag["value"] for tag in event.tags or []} + print(f"{event.target} {tags.get('display-name') or event.source.nick}: {text}", flush=True) + self.limiter.wait() + connection.privmsg(event.target, text) + print(f"{event.target} {connection.get_nickname()} (bot): {text}", flush=True) + + +def connect_factory(settings: Settings) -> irc.connection.Factory: + if not settings.use_tls: + return irc.connection.Factory() + context = ssl.create_default_context() + return irc.connection.Factory(wrapper=functools.partial(context.wrap_socket, server_hostname=settings.host)) + + +def main() -> int: + logging.basicConfig(level=logging.INFO) + load_env_file() + try: + bot = EchoBot(Settings.from_env()) + except ConfigError as error: + print(f"error: {error}", file=sys.stderr) + return 2 + try: + bot.start() # runs forever; the package reconnects on its own + except KeyboardInterrupt: + bot.disconnect("bye") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/examples/requirements.txt b/examples/requirements.txt new file mode 100644 index 0000000..86e1e97 --- /dev/null +++ b/examples/requirements.txt @@ -0,0 +1,3 @@ +# Only the examples need these; main.py does not. +irc>=20.5 # examples/irc_library_echo.py +websockets>=13.0 # examples/eventsub_echo.py (uses the sync client) diff --git a/requirements-dev.txt b/requirements-dev.txt index 52acdc9..1a83ee8 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,5 +1,6 @@ # For running the tests. The bot itself (main.py, twitch_chat.py, config.py) # uses only Python's standard library and needs none of this. +-r examples/requirements.txt pytest>=8.3 pytest-timeout>=2.3 trustme>=1.2 diff --git a/tests/test_examples.py b/tests/test_examples.py new file mode 100644 index 0000000..df13e5f --- /dev/null +++ b/tests/test_examples.py @@ -0,0 +1,203 @@ +"""The two examples: the `irc` package version, and the EventSub version. + +The EventSub test uses small fakes of Twitch's HTTP API and EventSub WebSocket that +answer with the shapes from Twitch's docs. Like everything here, no real Twitch. +""" + +from __future__ import annotations + +import json +import os +import subprocess +import sys +import threading +import time +from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer +from pathlib import Path +from urllib.parse import parse_qs, urlparse + +import pytest + +from config import Settings +from tests.conftest import BOT, CHANNEL, TOKEN, Background, StopBot + +REPO = Path(__file__).resolve().parents[1] + + +# ----- examples/irc_library_echo.py --------------------------------------------------------- + + +def test_irc_library_example_echoes(server): + pytest.importorskip("irc") + env = {**os.environ, "PYTHONUNBUFFERED": "1", "TWITCH_CHANNEL": CHANNEL, "TWITCH_BOT_NAME": BOT, + "TWITCH_OAUTH_TOKEN": TOKEN, "TWITCH_IRC_HOST": server.host, "TWITCH_IRC_PORT": str(server.port), + "TWITCH_IRC_TLS": "false"} + with subprocess.Popen([sys.executable, "-m", "examples.irc_library_echo"], cwd=REPO, env=env, + stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True) as bot: + try: + server.wait_for_join(timeout=15) + server.say("alice", "hello from the irc package: yes", display_name="Alice") + server.wait_for(lambda line: line == "PRIVMSG #demo :hello from the irc package: yes") + server.ping("still-there") + server.wait_for(lambda line: line.startswith("PONG") and "still-there" in line) + finally: + bot.terminate() + output = bot.communicate(timeout=10)[0] + + sent = server.sent_lines() + assert sent.index(f"PASS {TOKEN}") < sent.index(f"NICK {BOT}") + assert "CAP REQ :twitch.tv/tags twitch.tv/commands" in sent + assert "#demo Alice: hello from the irc package: yes" in output + + +# ----- examples/eventsub_echo.py ------------------------------------------------------------- + +BOT_ID, CHANNEL_ID, VIEWER_ID = "100", "200", "300" +API_TOKEN = TOKEN.removeprefix("oauth:") + + +class FakeTwitchAPI(ThreadingHTTPServer): + """id.twitch.tv/oauth2/validate and the three Helix calls the example makes.""" + + def __init__(self, scopes: tuple[str, ...] = ("chat:read", "chat:edit", "user:read:chat", "user:write:chat")) -> None: + super().__init__(("127.0.0.1", 0), FakeAPIHandler) + self.scopes = list(scopes) # what the fake token is allowed to do + self.requests: list[tuple[str, str, dict, dict]] = [] # method, path, headers, body + self.subscribed = threading.Event() + self.chat_sent = threading.Event() + + @property + def url(self) -> str: + return f"http://127.0.0.1:{self.server_address[1]}" + + def bodies(self, path: str) -> list[dict]: + return [body for _, request_path, _, body in self.requests if request_path == path] + + +class FakeAPIHandler(BaseHTTPRequestHandler): + server: FakeTwitchAPI + + def log_message(self, *args: object) -> None: # keep test output quiet + pass + + def do_GET(self) -> None: # noqa: N802 + url = urlparse(self.path) + self.server.requests.append(("GET", url.path, dict(self.headers), {})) + if url.path == "/oauth2/validate" and self.headers["Authorization"] == f"OAuth {API_TOKEN}": + self._reply(200, {"client_id": "fake-client", "login": BOT, "user_id": BOT_ID, + "scopes": self.server.scopes, "expires_in": 3600}) + elif url.path == "/helix/users" and parse_qs(url.query) == {"login": [CHANNEL]}: + self._reply(200, {"data": [{"id": CHANNEL_ID, "login": CHANNEL, "display_name": "Demo"}]}) + else: + self._reply(401, {"status": 401, "message": "invalid request"}) + + def do_POST(self) -> None: # noqa: N802 + body = json.loads(self.rfile.read(int(self.headers["Content-Length"]))) + self.server.requests.append(("POST", self.path, dict(self.headers), body)) + if self.headers["Authorization"] != f"Bearer {API_TOKEN}" or self.headers["Client-Id"] != "fake-client": + self._reply(401, {"status": 401, "message": "bad token or client id"}) + elif self.path == "/helix/eventsub/subscriptions": + self.server.subscribed.set() + self._reply(202, {"data": [{"id": "sub-1", "status": "enabled", **body}]}) + elif self.path == "/helix/chat/messages": + self.server.chat_sent.set() + self._reply(200, {"data": [{"message_id": "msg-1", "is_sent": True}]}) + else: + self._reply(404, {"status": 404}) + + def _reply(self, status: int, payload: dict) -> None: + data = json.dumps(payload).encode() + self.send_response(status) + self.send_header("Content-Type", "application/json") + self.send_header("Content-Length", str(len(data))) + self.end_headers() + self.wfile.write(data) + + +def eventsub(kind: str, payload: dict) -> str: + return json.dumps({"metadata": {"message_id": f"id-{time.monotonic_ns()}", "message_type": kind, + "message_timestamp": "2026-11-04T00:00:00Z"}, "payload": payload}) + + +def welcome(session_id: str) -> str: + return eventsub("session_welcome", {"session": {"id": session_id, "status": "connected", + "keepalive_timeout_seconds": 10, "reconnect_url": None}}) + + +def chat_notification(chatter_id: str, name: str, text: str) -> str: + event = {"broadcaster_user_id": CHANNEL_ID, "broadcaster_user_login": CHANNEL, "broadcaster_user_name": "Demo", + "chatter_user_id": chatter_id, "chatter_user_login": name.lower(), "chatter_user_name": name, + "message_id": f"m-{time.monotonic_ns()}", "message": {"text": text, "fragments": []}} + return eventsub("notification", {"subscription": {"type": "channel.chat.message", "version": "1"}, "event": event}) + + +def test_eventsub_example_subscribes_echoes_and_skips_its_own_messages(capsys): + websockets_server = pytest.importorskip("websockets.sync.server") + from examples import eventsub_echo + + api = FakeTwitchAPI() + threading.Thread(target=api.serve_forever, daemon=True).start() + + def session(websocket) -> None: + if websocket.request.path == "/ws": + websocket.send(welcome("session-1")) + assert api.subscribed.wait(5) + websocket.send(eventsub("session_keepalive", {})) + websocket.send(chat_notification(VIEWER_ID, "Alice", "hello: eventsub")) + websocket.send(eventsub("session_reconnect", {"session": {"id": "session-1", "status": "reconnecting", + "reconnect_url": f"{ws_url}/moved"}})) + time.sleep(0.5) # Twitch would close the old socket a bit later + else: # the reconnect URL: the subscription comes along, no new POST expected + websocket.send(welcome("session-2")) + websocket.send(chat_notification(BOT_ID, BOT, "hello: eventsub")) # the bot's own echo + websocket.send(chat_notification(VIEWER_ID, "Bob", "after the move")) + deadline = time.monotonic() + 5 + while len(api.bodies("/helix/chat/messages")) < 2 and time.monotonic() < deadline: + time.sleep(0.05) + time.sleep(0.3) # room for a (wrong) third send + # returning closes the connection, which ends bot.listen() + + sleeps: list[float] = [] + + def fake_sleep(seconds: float) -> None: + sleeps.append(seconds) + raise StopBot + + with websockets_server.serve(session, "127.0.0.1", 0) as ws_server: + ws_url = f"ws://127.0.0.1:{ws_server.socket.getsockname()[1]}" + threading.Thread(target=ws_server.serve_forever, daemon=True).start() + endpoints = eventsub_echo.Endpoints(id_url=f"{api.url}/oauth2", api_url=f"{api.url}/helix", eventsub_url=f"{ws_url}/ws") + settings = Settings(channel=CHANNEL, bot_name=BOT, token=TOKEN) + bot = Background(lambda: eventsub_echo.run(settings, endpoints, sleep=fake_sleep)) + with pytest.raises(StopBot): + bot.join(timeout=20) + ws_server.shutdown() + api.shutdown() + + assert api.bodies("/helix/eventsub/subscriptions") == [{ + "type": "channel.chat.message", + "version": "1", + "condition": {"broadcaster_user_id": CHANNEL_ID, "user_id": BOT_ID}, + "transport": {"method": "websocket", "session_id": "session-1"}, + }] + assert api.bodies("/helix/chat/messages") == [ + {"broadcaster_id": CHANNEL_ID, "sender_id": BOT_ID, "message": "hello: eventsub"}, + {"broadcaster_id": CHANNEL_ID, "sender_id": BOT_ID, "message": "after the move"}, + ] + assert sleeps == [1] + out = capsys.readouterr().out + assert "#demo Alice: hello: eventsub\n#demo echo_bot (bot): hello: eventsub\n" in out + + +def test_eventsub_example_refuses_a_token_without_chat_scopes(): + pytest.importorskip("websockets") + from examples import eventsub_echo + + api = FakeTwitchAPI(scopes=("chat:read", "chat:edit")) # an IRC-only token + threading.Thread(target=api.serve_forever, daemon=True).start() + try: + endpoints = eventsub_echo.Endpoints(id_url=f"{api.url}/oauth2", api_url=f"{api.url}/helix", eventsub_url="ws://unused") + with pytest.raises(eventsub_echo.TwitchAPIError, match="user:read:chat"): + eventsub_echo.run(Settings(channel=CHANNEL, bot_name=BOT, token=TOKEN), endpoints) + finally: + api.shutdown() From 1bc6716d6d089b326f52316736c2f8846dc26c2f Mon Sep 17 00:00:00 2001 From: NatLee Date: Wed, 4 Nov 2026 07:27:58 +0800 Subject: [PATCH 6/7] ci: lint and test on Python 3.10 to 3.14 The repo never had CI. The workflow checks that the bot imports with no packages installed (it promises the standard library only), then runs ruff and the test suite against the fake Twitch server on five Python versions. --- .github/workflows/ci.yml | 42 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..b194699 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,42 @@ +name: CI + +on: + push: + branches: [master] + pull_request: + workflow_dispatch: + +permissions: + contents: read + +jobs: + test: + name: Python ${{ matrix.python }} + runs-on: ubuntu-latest + timeout-minutes: 10 + strategy: + fail-fast: false + matrix: + python: ["3.10", "3.11", "3.12", "3.13", "3.14"] + steps: + - uses: actions/checkout@v7 + + - uses: actions/setup-python@v7 + with: + python-version: ${{ matrix.python }} + cache: pip + cache-dependency-path: | + requirements-dev.txt + examples/requirements.txt + + - name: The bot needs only the standard library + run: python -c "import main, twitch_chat, config, twitchSocket; print('imports fine without any packages')" + + - name: Install test tools + run: python -m pip install -r requirements-dev.txt + + - name: Lint + run: ruff check . + + - name: Tests (against the fake Twitch server, never the real one) + run: pytest -v From 69e98ead9b164ab4d25ef4f0aa5286dc7c1537b1 Mon Sep 17 00:00:00 2001 From: NatLee Date: Wed, 4 Nov 2026 07:28:08 +0800 Subject: [PATCH 7/7] docs: rewrite the README as a step-by-step lesson with pictures The old README was a clone command and a code sample with the token pasted in. The new one starts with a cover, lets you try the bot on the fake server before you have a token, explains how to get a token with the right scopes, and then walks through Twitch chat step by step: Mermaid sequence diagrams for the handshake, PING/PONG and sending, a picture of how one IRC line splits into four parts, and a terminal capture from a real practice run (clearly marked as the fake server). It also covers the irc package and EventSub examples, the 2019 API and the 2019 bugs. readme.md becomes README.md. Picture sources are HTML files in docs/images/src/. --- README.md | 436 ++++++++++++++++++++++++++ docs/images/hero-dark.png | Bin 0 -> 83870 bytes docs/images/hero-light.png | Bin 0 -> 94351 bytes docs/images/message-anatomy-dark.png | Bin 0 -> 71062 bytes docs/images/message-anatomy-light.png | Bin 0 -> 67679 bytes docs/images/src/hero.html | 157 ++++++++++ docs/images/src/message-anatomy.html | 130 ++++++++ docs/images/src/terminal-demo.html | 54 ++++ docs/images/terminal-demo.png | Bin 0 -> 93724 bytes readme.md | 44 --- 10 files changed, 777 insertions(+), 44 deletions(-) create mode 100644 README.md create mode 100644 docs/images/hero-dark.png create mode 100644 docs/images/hero-light.png create mode 100644 docs/images/message-anatomy-dark.png create mode 100644 docs/images/message-anatomy-light.png create mode 100644 docs/images/src/hero.html create mode 100644 docs/images/src/message-anatomy.html create mode 100644 docs/images/src/terminal-demo.html create mode 100644 docs/images/terminal-demo.png delete mode 100644 readme.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..a230fea --- /dev/null +++ b/README.md @@ -0,0 +1,436 @@ +

+ + + twitch-echo-bot-with-python: learn how Twitch chat works from one small file. Twitch chat at irc.chat.twitch.tv:6697 (TLS) sends PING and PRIVMSG lines; twitch_chat.py goes through 9 small steps (TLS, CAP, PASS, NICK, JOIN, cutting the byte stream at \r\n, splitting tags, prefix, command and params, answering PING with PONG, sending at most 20 messages per 30 seconds, reconnecting); the echo bot answers alice's 'hi bot!' with 'hi bot!'. Commands: python main.py, python tools/fake_twitch_server.py + +

+ +

+ CI + Python 3.10 to 3.14 + No dependencies + License: MIT +

+ +A Twitch chat bot that repeats every message back into the channel, written with a plain +socket and nothing outside Python's standard library, so you can see every line that goes +over the wire. Read [`twitch_chat.py`](twitch_chat.py) from top to bottom and you will know +how Twitch chat works: connecting, logging in, joining a channel, reading messages, +answering PING, staying under the rate limit and reconnecting. No Twitch account yet? A +small fake Twitch server in this repo lets you try everything on your own computer. + +- [Quick start](#quick-start): try it with the fake server, then with real Twitch +- [How Twitch chat works, step by step](#how-twitch-chat-works-step-by-step) +- [The same bot with a ready-made package](#the-same-bot-with-a-ready-made-package) (issue #1) +- [Next step: EventSub, the way Twitch recommends now](#next-step-eventsub-the-way-twitch-recommends-now) +- [Tests](#tests) · [Files](#files) · [Code from 2019](#code-from-2019) + +## Quick start + +You need Python 3.10 or newer. The bot itself installs nothing. + +```bash +git clone https://github.com/NatLee/twitch-echo-bot-with-python.git +cd twitch-echo-bot-with-python +``` + +### 1. Try it without a Twitch account + +Open two terminals in the repo folder. In the first one, start the fake Twitch chat: + +```bash +python tools/fake_twitch_server.py +``` + +In the second one, start the bot and point it at the fake server. The fake server takes any +token that starts with `oauth:`. + +```bash +# macOS / Linux / Git Bash +TWITCH_IRC_HOST=127.0.0.1 TWITCH_IRC_PORT=6667 TWITCH_IRC_TLS=false \ +TWITCH_CHANNEL=demo TWITCH_BOT_NAME=echo_bot TWITCH_OAUTH_TOKEN=oauth:anything \ +python main.py +``` + +```powershell +# Windows PowerShell +$env:TWITCH_IRC_HOST="127.0.0.1"; $env:TWITCH_IRC_PORT="6667"; $env:TWITCH_IRC_TLS="false" +$env:TWITCH_CHANNEL="demo"; $env:TWITCH_BOT_NAME="echo_bot"; $env:TWITCH_OAUTH_TOKEN="oauth:anything" +python main.py +``` + +Now type `alice: hi bot!` in the first terminal. You are alice, a viewer; the bot answers. +Type `/ping` to see the bot answer a PING, and `/reconnect` to watch it reconnect. + +

+ Two terminals from a practice run on 2026-11-04, against the fake server and not the real Twitch. Terminal 1, the fake server: the bot logs in as echo_bot and joins #demo; alice says 'hi bot!' and the bot sends it back; the server sends PING and the bot answers PONG :tmi.twitch.tv; Bob says a Chinese sentence with colons and a URL, and the bot sends it back unchanged. Terminal 2, the bot: connecting to 127.0.0.1:6667 (plain text), joined #demo as echo_bot, then each message and its echo. +

+ +Add `--debug` to see every raw IRC line the bot sends (`>`) and receives (`<`). The token +is never printed. From a second practice run (the final `bye` left out): + +```text +23:17:07 INFO connecting to 127.0.0.1:6667 (plain text) +23:17:07 DEBUG > CAP REQ :twitch.tv/tags twitch.tv/commands +23:17:07 DEBUG > PASS *** +23:17:07 DEBUG > NICK echo_bot +23:17:07 DEBUG < :tmi.twitch.tv CAP * ACK :twitch.tv/tags twitch.tv/commands +23:17:07 DEBUG < :tmi.twitch.tv 001 echo_bot :Welcome, GLHF! +23:17:07 DEBUG > JOIN #demo +(… 7 lines left out: 002 to 376 and GLOBALUSERSTATE …) +23:17:08 DEBUG < :echo_bot!echo_bot@echo_bot.tmi.twitch.tv JOIN #demo +23:17:08 DEBUG < :echo_bot.tmi.twitch.tv 353 echo_bot = #demo :echo_bot +23:17:08 DEBUG < :echo_bot.tmi.twitch.tv 366 echo_bot #demo :End of /NAMES list +23:17:08 INFO joined #demo as echo_bot +23:17:08 DEBUG < @badge-info=;badges=;color=;display-name=echo_bot;emote-sets=0;mod=0;subscriber=0;user-type= :tmi.twitch.tv USERSTATE #demo +23:17:08 DEBUG < @room-id=1000;slow=0 :tmi.twitch.tv ROOMSTATE #demo +23:17:08 DEBUG < @badge-info=;badges=;color=#1E90FF;display-name=Alice;emotes=;first-msg=0;flags=;id=00000000-0000-0000-0000-000000000001;mod=0;room-id=1000;subscriber=0;tmi-sent-ts=1793747827973;turbo=0;user-id=2510;user-type= :alice!alice@alice.tmi.twitch.tv PRIVMSG #demo :hi bot! +#demo Alice: hi bot! +23:17:08 DEBUG > PRIVMSG #demo :hi bot! +#demo echo_bot (bot): hi bot! +23:17:08 DEBUG < @badge-info=;badges=;color=;display-name=echo_bot;emote-sets=0;mod=0;subscriber=0;user-type= :tmi.twitch.tv USERSTATE #demo +23:17:08 DEBUG < PING :tmi.twitch.tv +23:17:08 DEBUG > PONG :tmi.twitch.tv +``` + +### 2. Get a token + +Twitch chat needs a **user access token** for the bot's account. For this bot it needs two +scopes (permissions): `chat:read` to read chat and `chat:edit` to send messages. If you also +want to try the [EventSub example](#next-step-eventsub-the-way-twitch-recommends-now), add +`user:read:chat` and `user:write:chat`. + +One way that uses only Twitch's own tools: + +1. Log in to the [Twitch Developer Console](https://dev.twitch.tv/console/apps) with the bot + account and register an application. Set the OAuth Redirect URL to + `http://localhost:3000`. Note the Client ID and create a Client Secret. +2. Install the [Twitch CLI](https://dev.twitch.tv/docs/cli/) and give it the two values: + `twitch configure`. +3. Ask for a token. A browser window opens; log in as the bot and allow access. + + ```bash + twitch token -u -s 'chat:read chat:edit user:read:chat user:write:chat' + ``` + +The command prints a User Access Token. That is what goes in `TWITCH_OAUTH_TOKEN`; the +`oauth:` in front is optional. User tokens expire, so run the command again when the bot +reports `Login authentication failed`. + +Treat the token like a password. Anyone who has it can chat as your bot. + +### 3. Run it on Twitch + +Copy the settings template and fill it in: + +```bash +cp .env.example .env +``` + +```ini +TWITCH_CHANNEL=your_channel # the channel to join, without # +TWITCH_BOT_NAME=your_bot_account # the account the token belongs to +TWITCH_OAUTH_TOKEN=... # from step 2 +``` + +`.env` is in `.gitignore`, so git will not pick it up. Settings already set in your shell +win over the file. Then: + +```bash +python main.py +``` + +The bot connects to `irc.chat.twitch.tv:6697` with TLS, joins your channel and repeats +whatever people say. Stop it with Ctrl+C. To build your own bot, change the line marked +`<- change this line` in [`main.py`](main.py). + +> [!NOTE] +> Everything in this repo was tested against the fake server and in CI, not against the real +> Twitch: we had no Twitch account token to test with. The fake server answers with the +> lines Twitch's documentation shows, but it is not Twitch. If something behaves differently +> on Twitch, please open an issue. + +## How Twitch chat works, step by step + +Twitch chat is an [IRC](https://en.wikipedia.org/wiki/IRC) server. IRC is a text protocol +from 1988: every command is one line of text that ends with `\r\n`. A bot opens a +connection, sends a few such lines to log in and join a channel, and from then on reads +lines from Twitch and answers some of them. The steps below match the `STEP` comments in +[`twitch_chat.py`](twitch_chat.py). Twitch's own description is in +[IRC Concepts](https://dev.twitch.tv/docs/chat/irc/) (read on 2026-11-04). + +### Steps 1 to 4: connect, ask for extras, log in, join + +```mermaid +sequenceDiagram + autonumber + participant Bot as Your bot (twitch_chat.py) + participant Twitch as Twitch chat (irc.chat.twitch.tv) + Bot->>Twitch: open a TCP connection to port 6697 and start TLS + Bot->>Twitch: CAP REQ :twitch.tv/tags twitch.tv/commands + Bot->>Twitch: PASS oauth:YOUR_TOKEN + Bot->>Twitch: NICK echo_bot + Twitch-->>Bot: :tmi.twitch.tv CAP * ACK :twitch.tv/tags twitch.tv/commands + alt the token is right + Twitch-->>Bot: :tmi.twitch.tv 001 echo_bot :Welcome, GLHF! + Note over Twitch: then 002, 003, 004, 375, 372, 376 and GLOBALUSERSTATE + else the token is wrong or expired + Twitch-->>Bot: :tmi.twitch.tv NOTICE * :Login authentication failed + Note over Twitch: hangs up + end + Bot->>Twitch: JOIN #35;demo + Twitch-->>Bot: JOIN #35;demo, then 353 (who is here) + Twitch-->>Bot: 366 echo_bot #35;demo :End of /NAMES list + Note over Bot: connect() returns: we are in the channel +``` + +1. **Connect.** `socket.create_connection` opens the connection and `ssl` wraps it in TLS, + so nobody on the way can read your token. Port 6697 is TLS; 6667 is the same chat + without encryption (the 2019 version used that). Twitch also offers + `wss://irc-ws.chat.twitch.tv:443` for WebSocket clients such as web pages. +2. **Ask for extras.** `CAP REQ` asks for Twitch's additions to IRC. `twitch.tv/tags` + adds details to each message, such as the viewer's display name and user ID. Twitch only + gives tags to bots that also ask for `twitch.tv/commands`. +3. **Log in.** `PASS` carries the token with `oauth:` in front, then `NICK` gives the + bot's login name in lowercase. The order matters: Twitch rejects `NICK` before `PASS`. + Success is a burst of numbered lines that starts with `001`. +4. **Join.** `JOIN #channel`. Twitch confirms with `366 … :End of /NAMES list`. For a + channel that does not exist, Twitch says nothing at all, so the bot gives up after 15 + seconds of silence (`HANDSHAKE_TIMEOUT`) and tells you to check the name. + +### Step 5: TCP is a stream, not a list of messages + +`recv(4096)` returns whatever bytes have arrived: maybe half a line, maybe five lines. +Twitch's docs even warn that what the server sends "may contain a single message or +multiple messages". So the bot keeps a buffer (`LineBuffer`), cuts it at `\r\n` and only +hands out complete lines. +It cuts the bytes first and decodes each finished line afterwards, because a character +like 你 is three bytes in UTF-8 and can be split between two packets. + +### Step 6: the four parts of a line + +

+ + + The line '@color=#1E90FF;display-name=Alice :alice!alice@alice.tmi.twitch.tv PRIVMSG #demo :look: a colon' split into four parts. 1, tags: starts with @, ends at the first space, pairs separated by ;, giving color and display-name. 2, prefix: starts with :, ends at the next space, the login is what comes before !, so alice. 3, command: PRIVMSG, which is chat; others are PING, JOIN, NOTICE, 001. 4, params: split at spaces, a colon right after a space starts the last one, which keeps its spaces and colons: '#demo' and 'look: a colon'. Below: the 2019 code, line.split(':'), got 'look'; parse_line(line).trailing gets 'look: a colon'. + +

+ +`parse_line()` splits a line into **tags** (only there because we asked in step 2), +**prefix** (who sent it), **command** and **params**. The rule that matters: the first +`" :"` starts the last parameter, and everything after it belongs to that parameter. That +is why you must never cut a line with `split(":")`: chat text is full of colons, and every +link has one. + +Tag values cannot contain spaces or `;`, so Twitch writes them as escapes from the +[IRCv3 message tags](https://ircv3.net/specs/extensions/message-tags) spec: `\s` is a +space, `\:` is `;`, `\\` is a backslash. `unescape_tag_value()` turns them back. + +### Step 7: PING and PONG + +```mermaid +sequenceDiagram + participant Twitch as Twitch chat + participant Bot as Your bot + Twitch-->>Bot: PING :tmi.twitch.tv + Bot->>Twitch: PONG :tmi.twitch.tv + Note over Twitch,Bot: no PONG? Twitch closes the connection +``` + +From time to time (Twitch does not say how often) Twitch checks that the bot is still +there. The bot answers `PONG` with the same text the `PING` carried. `read_message()` does +this for you and never returns a PING as a chat message. Only a line whose *command* is `PING` counts; a viewer who types +"PING :tmi.twitch.tv" in chat is just chatting. + +### Step 8: sending, and the rate limit + +```mermaid +sequenceDiagram + participant Alice as alice (a viewer) + participant Twitch as Twitch chat + participant Bot as Your bot + Alice->>Twitch: types "hi bot!" + Twitch-->>Bot: @…display-name=Alice… :alice!alice@alice.tmi.twitch.tv PRIVMSG #35;demo :hi bot! + Note over Bot: read_message() gives user "alice", text "hi bot!" + Bot->>Twitch: PRIVMSG #35;demo :hi bot! + Twitch-->>Alice: echo_bot: hi bot! + Twitch-->>Bot: USERSTATE #35;demo (Twitch never sends your own message back) +``` + +`send_message()` sends `PRIVMSG #channel :text`. A line break in the text would end the +command and start a new one, so the bot turns line breaks into spaces first. + +Twitch limits how fast a bot may talk. For a bot that is not the broadcaster, a moderator +or a VIP, the [rate limits](https://dev.twitch.tv/docs/chat/#rate-limits) are 20 messages +in any 30 seconds and 1 message per second in a channel. Go over and Twitch ignores the +bot's messages for an hour. `RateLimiter` remembers recent sends and waits before the next +one would break a rule. The numbers are in `DEFAULT_RATE_LIMITS`; if your bot is a moderator +in the channel, Twitch allows 100 per 30 seconds and you can pass your own `rate_limits`. +Twitch also drops a message that is identical to the one you sent less than 30 seconds +ago; the bot logs Twitch's `NOTICE` when that happens. + +### Step 9: when the connection ends + +Connections end. Twitch restarts servers and sends `RECONNECT` first, networks drop, and +when Twitch closes the connection `recv()` returns empty bytes. In all these cases +`TwitchChat` raises `ConnectionClosed`. [`main.py`](main.py) catches it, waits 1, 2, 4, 8, +16, then 30 seconds between tries (`RECONNECT_DELAYS`), connects again and joins the channel +again. A wrong token or channel name is different: retrying will not help, so `main.py` +stops and tells you what Twitch said. + +## The same bot with a ready-made package + +[Issue #1](https://github.com/NatLee/twitch-echo-bot-with-python/issues/1) asked why not use +an existing IRC package. For a real bot, you should. +[`examples/irc_library_echo.py`](examples/irc_library_echo.py) is the same echo bot on the +[`irc`](https://pypi.org/project/irc/) package, about 50 lines of logic: + +```bash +pip install -r examples/requirements.txt +python -m examples.irc_library_echo +``` + +It reads the same `.env`. Compare it with `twitch_chat.py`: the package opens the socket, +splits lines, parses them, answers PING and reconnects (steps 1, 5, 6, 7 and 9). You still +write the Twitch parts yourself: the `oauth:` password, `CAP REQ`, `JOIN`, the +`display-name` tag and the rate limit. + +This repo keeps a raw socket on purpose. It is a lesson, and the package hides exactly the +parts you came to see. The bugs fixed in the 2019 code (next section) were all in those +hidden parts. Once you have seen them, using a package is the right call. For a bigger bot, +also look at [TwitchIO](https://pypi.org/project/twitchio/), which speaks EventSub and the +Twitch API for you. + +## Next step: EventSub, the way Twitch recommends now + +IRC still works, but Twitch's [chat documentation](https://dev.twitch.tv/docs/chat/) now +recommends EventSub for reading chat and the Send Chat Message API for sending. Its +[IRC page](https://dev.twitch.tv/docs/chat/irc/) says IRC "has some limitations versus +EventSub, and is more complicated to parse". EventSub means Twitch +pushes events to you as JSON over a WebSocket. Twitch has not announced an end date for IRC +(checked 2026-11-04). + +[`examples/eventsub_echo.py`](examples/eventsub_echo.py) is the echo bot built that way, +following Twitch's [example chatbot](https://dev.twitch.tv/docs/chat/chatbot-guide/): + +```mermaid +sequenceDiagram + autonumber + participant Bot as Your bot + participant ID as id.twitch.tv + participant API as api.twitch.tv/helix + participant WS as EventSub WebSocket + Bot->>ID: GET /oauth2/validate (who am I, which scopes?) + Bot->>API: GET /users?login=demo (channel name to user id) + Bot->>WS: connect wss://eventsub.wss.twitch.tv/ws + WS-->>Bot: session_welcome (session id) + Bot->>API: POST /eventsub/subscriptions, type channel.chat.message (within 10 s) + WS-->>Bot: notification: alice said "hi bot!" + Bot->>API: POST /chat/messages "hi bot!" + WS-->>Bot: notification: echo_bot said "hi bot!" (your own message, skipped) +``` + +```bash +pip install -r examples/requirements.txt +python -m examples.eventsub_echo +``` + +What changes compared with IRC: + +| | IRC (`main.py`) | EventSub (`examples/eventsub_echo.py`) | +|---|---|---| +| Scopes | `chat:read`, `chat:edit` | `user:read:chat`, `user:write:chat` | +| Reading | `PRIVMSG` lines on one socket | JSON `notification` messages on a WebSocket | +| Sending | `PRIVMSG` on the same socket | `POST /helix/chat/messages` | +| Still alive? | answer `PING` with `PONG` | expect a message every `keepalive_timeout_seconds` | +| Your own messages | never sent back to you | sent back: skip them or the bot echoes itself forever | +| Moving servers | `RECONNECT`: connect again | `session_reconnect`: connect to the new URL, the subscription moves along | + +The example closes the old WebSocket before it opens the new one after `session_reconnect`. +Twitch suggests keeping both open until the new one says welcome, so a message sent in +that moment can be lost. + +## Tests + +The tests start a fake Twitch server on a free local port and never touch the real Twitch. +They cover each step above, the 2019 bugs below, the old `twitchSocket` calls, `main.py` +as a real process, and both examples (the EventSub one against fakes of the Twitch API and +EventSub WebSocket). + +```bash +pip install -r requirements-dev.txt +pytest +ruff check . +``` + +No Python on your machine? Docker works too: + +```bash +docker run --rm -v "$PWD:/src:ro" python:3.12-slim sh -c \ + 'cp -r /src /w && cd /w && pip install -q -r requirements-dev.txt && pytest' +``` + +GitHub Actions runs the same on Python 3.10 to 3.14 for every push and pull request. + +## Files + +| File | What it is | +|---|---| +| [`twitch_chat.py`](twitch_chat.py) | the lesson: the IRC client in 9 steps, standard library only | +| [`main.py`](main.py) | the echo bot: settings, the echo loop, reconnecting | +| [`config.py`](config.py) | reads settings from the environment and `.env` | +| [`.env.example`](.env.example) | template for your `.env` | +| [`tools/fake_twitch_server.py`](tools/fake_twitch_server.py) | the fake Twitch chat, for practice and tests | +| [`examples/`](examples/) | the same bot on the `irc` package, and on EventSub | +| [`twitchSocket.py`](twitchSocket.py) | the 2019 names, kept so old scripts keep working | +| [`tests/`](tests/) | pytest tests | +| [`docs/images/src/`](docs/images/src/) | HTML sources of the pictures in this README | + +## Code from 2019 + +Scripts written for the 2019 version still work, unchanged: + +```python +from twitchSocket import twitchSocket + +ts = twitchSocket(channelName="your_channel", botName="your_bot", botAuth="oauth:...") +while True: + username, message = ts.getMsg() + ts.sendMsg(message) +``` + +`twitchSocket` now runs on `twitch_chat.TwitchChat` and prints a `DeprecationWarning` +pointing there. It stays until at least 2027-11-04; [`twitchSocket.py`](twitchSocket.py) +says what to check before removing it. The new names: + +| 2019 | now | +|---|---| +| `twitchSocket(channelName=, botName=, botAuth=)` | `TwitchChat(channel=, nick=, token=)`, then `connect()` | +| `getMsg()` returns `(username, message)` | `read_message()` returns a `ChatMessage` (`.user`, `.text`, `.display_name`, `.tags`) | +| `sendMsg(message)` | `send_message(text)` | + +### What the 2019 version got wrong + +All of these were reproduced against the fake server before the rewrite, and each has a +test now. + +- **It crashed within minutes.** A PING made `getMsg()` return `(None, None)`, and + `sendMsg(None)` then raised `TypeError`, which the loop did not catch. +- **Colons cut messages short.** `split(":")` turned `look at this: https://example.com` + into `look at this`. +- **Two lines in one packet lost the second.** One `recv()` was treated as one line. When a + PING and a chat line arrived together, the bot reported a viewer called `tmi.twitch.tv` + and echoed IRC protocol text. +- **A character split between packets crashed it.** Decoding each `recv()` on its own + failed on half a 你, and the error handler then failed too. +- **It never noticed a closed connection.** `recv()` returned empty bytes forever and the + loop spun at full CPU. A wrong token or a misspelled channel hung the constructor. +- **It sent the token in plain text** to the old host `irc.twitch.tv:6667`, and the token + lived in `main.py`, one `git commit` away from being public. +- **It answered PONG to chat text** that contained `PING :tmi.twitch.tv`, always with a + hard-coded reply. +- **No rate limit**, so a busy chat could get the bot ignored for an hour. + +## License + +[MIT](./LICENSE) diff --git a/docs/images/hero-dark.png b/docs/images/hero-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..0cebf6767ae358405dfccd3ab08248e0746c996c GIT binary patch literal 83870 zcmYhiXH-*N7cRP!0Fjm`NKvXHO*%;LqM|P#2uc+ax=5AYLV_qLD5&&~4N;KZTLOqk zM`~yiKmj3i2qh%B@jK^^d;ewZtg-f*{n>Lq>$%x&Lw1()EC2wo-@19t8~~sg0DuUe zg3zDr%Ox=b065po`0jNYjizN_ET^carGHcVn#mPS0~tjv2^keJsVf2(rT8z1bMc9s zxQ&hq$eo%N!&)`@_?)#di_THZp(}d-(RgDR+(z6Rb-88Yp|N8wpsNjOnbND)JN?M^HqJiG^*n*<7?aA?8`q!pdfI#}5l@1nSOQggN2er>}k?=-27F zU&?C-MyKxCIR}JBg`=Ney>Z*aH!SXDs+GO#L!<5&$=TtUID?y}0r%z`T06Z1A|oFs z1X}i1WUur#Z0u~1=|&mt-hJ&g+E6$fcE92GG|Ag)VRh+PNlo{rk>x2?xSMA{tn0Vj zz&}rICp@edQhlcmNtA?#i!Qc{_wWC{>+mP$e*e3Wwa5p*?;!seJ1&_b{#z1{DC#IVqb}NWq))3Bpfr*(NeqQ=jdI6kIS?b;kIW+^mE0?7LG_Sn5rt!sy zM?^xq=C*EwnTn!?=iR*g;1y?+H$@S9#i&Cm$*Y$vmDEFfbzj|Ge#ZY-~kTWCQ$%P9k=f}eU zrav@Y^+;{k-Bqg3x~7;qu-7AANne+;J|YNPwGx65MfBJ!lW-}Ex{)KVc16U(hmZY6 zEe4W;)BZH&M23f|9eukgI8w!E!8=kXo_X%s@iGh??Ih|>8fM9Aybq4MNbC0OSg`KR zZC2smxO?YP)XwMmGwlSo?QGLO@2DSR^a|>`XTcj*-pB+BpYY3bYpU`r%ZDoENqzm3 z)2&m8-yAjQ{9&3G(P6!;W&gK@>EtBo^J|NKVcvPwpM3k9{0!jEJEzL7s>m<-m5+Wr z(mefzqFMA>^)#RLvY+v@UgxdTg{9?`;(&UKB2QDNtImrX&T5-nZTREzSijbeRAOX3KK+QBbpI`-uS+tOpN%#8wWc&Y9hKXR2|+c-tN-6^eg!d3^Auw*M&Bhpr6w=L69j zs!Mutzag**DtjCK6suY1h-0+r`3fxfii#H@FeygFdNn$7Q26wZJCF82hP)7>RLr6P zWJZ=cmz;>cVBH2&*}4_MS8oU=(|u9B$C=IVfeztz4@5wGb;^(T1eN2^IC??$Cof@O7i5?M4VMtqA&AGtI{l>uRfSB_a%)e;H@oTjJ>CR#IQQlF=zd{u za)>b~j}oEp_lm-|$xA3a!Olt<`K+AD<2!W!P<4k^Nw?LEXd1LQArePT((D?B@>|j5 zJQr0CPCW>&Ubnev&3vL{F1X{1(Gynf9D&Y6E8r^bHcev1O=yM}#pJkk6vlI`;V zf-Agc>0R@oQ&@3r%F~?8n2Qw~P(hVUocYCXh_cW-^OY0`g!0aH8*W)oe9pPx3WYv3 zJahYpznLpEMnY=Yzx~3)ydDxMKE2-sEScTw;@|Gd`t-tlwlANqm{8-@d zM`_pH!sPDiA{tMs$#d|PKW~YCit2rDCVo)`qAsdSKcvBQx4)H3)WsUsyEa%7w|@L6 zFX~(~xBSg}*yVZT6TG~b^6fnCf@{GZ_@11rw*HvGB1XA+4@JG)udemx-QbYPzVR@rvS%fL<<<~X3)35abnu*yWQ0|;JP1uOu`fg30}t(N=WCodwRm;V9d7pM0_c}VS?VSuOsoe~G^B5@AD zi^J?dzL0T2-l%tL!i+FvDJ@;}5yu(pQQ8_a?pf4XX8}qp@0WMn<<2%Ec^S?Rz&MpC zLi05~T)Vbg0t*Z75$|K2Gcgxd^nG0&Pid@qp9(KBJB@8nL)kWak=gW<=Ul~7d!8Mm zwb`X2B(ensbv*Fc0Ubg$!eEFg?l~Mka(d6tyr87rQHw!l6>@vN^6|s)Q{g|g#c99s`@&3D#28q}&rFA)c8m@pv0S^rI8XC-+)y%F z`oue~;>bu=l=W6ubz!qT|NPjHp2ViEF5JO69%DKR%AR&aOTtF~m|2_YA7KQRw8`R} znUEaTuXx-gp173wW2=A54G56LZ%}^GFp=jV(hB*HA%AW)WloGm(hMOl&YhtaeSw9S zo>p#+f;aqx{Pa9QT_aFp3M8v{UXOy+IgZMuv_%bI7vAvZe!T?pyReE-KE?159u2S0 z-qEY$h0I(G$lf}t)mr5*62kk(#)@Vz(BFFPj{-a}Lx(Ul`Z26PpRQz4GV>=LGqX0F+}TK ztQ7bCM%U|(-kLO%kl!=<&qyrn8fg~pb?rZ06M)STCw%&*o{#5+>+=wpy9_};kDdP; zKA;(e+fJa>{3s6!OG-Y*Zio!Fk)us70tYwm(7w=}OqQ3;_>o}$`hUfjxd zjuvGG*uc>YV^82}3}l{2T$_JAih>0Pl;=nzZ~HvR|L}(Q--2tR8xX-2c_Ba9EaRa^ zy)j&m>4AFU9$V9|T|de`06)28O&6s|U7z2tJhNbN8Iq{Tl#xuHOt!5=tLGsR`~Um@ zN5b)wMT}-I)Qb;FJirI^MdD1BqkSG;vh|}N_-MYnaL!zN`pLS$F^u$=W|{FXVmfv~ z7M`Gx=kWUHyvVuH6551@(AtOR)sM&hwzhFdP>i0iV?!8*d~^o~+EslaL3p;KXQ*~w z;GW=vGU}YA7h;@=v;_5e+5EqyWslVeZ3Jyxh520_g4?ccojk2)jFq_Cc=LaM!yjIN zTUzT7Fd2OFwzx+X(YalDsC^LYAv$y04eNzW7E(L3MgsDu7&y|z>6pk9WJrL(et-u$ zf6$8M@iB0G7cVkZJb8rsS*f~5 zkLfO&j*Jg&)p_`8*xT$qNEaTe_0W8@3j&U2+wZ&rQ^VimRpW>CQTwm!?8bK>d4&8< zhZU&nAj_x-&7Xo!gHeRUJx~&h#HushQ`-XyMB*W^l$J9`7-t>mu_S_myQ+iqr6QCf zS~?*iMR03|28{D*35Qiq66hd=4&3C)s>hjDD*W^)opCuSduF^i4Avne%UGlvEt~>o zE=Pjeh0U({(^ns;e*?uif(-b}lV;c_phRURYdYp6pLr0%M^{-rGg(zbs2s7!$P}Y@ z=H@6=3wVU<_g7P)BJPk?)r86?c#(8?GQmXJfRMUbVAIf&M*#%;&G3V!x!o#VazH$F ze~_|oc81Tks^H=CJ#x{CfpyX|PJ&O?IBV`6%s0(tNZ#LDzoG^te^7`*=(PtNb>y(y``jP^8=;3qm z*z5m;VdRid7Z>X*Fy3^os_1^#Toi8HxjY}Lt<_HPxzER&A7=)XWPIMNTsT-ZUMfqb zkP|Gatu(7wzuu4jO1c!T1rY=y!MCcVsk!lKsjsI#OK*rjmY7bsWUCT$HfR$3=E39$ z9eIu1+?Mlvq4Vk0{r8xA(>&>1PrsyBcHDfyP87axc@}ruwf`UXViR+8O3_lWOawcZVdZx1) z@dXtowe>@#!N`6Z9|wkOb8|3$8e2P(-*7@1L!fj?4DRG7M+tESPveSP*!1(CwVmE8 zsH>D`$lX_A(7r42Z0>%Jj*LUCc5FeAklzJ56#EW>Dl_ELf!Jp}cHJ2WYRKrwp}x@SL#+pL z4Fz`nx*i4#1t4Q0VtH~)e6AYjh`7WLC1$Z|46K2gOwqx)6yx0k6dPK3muLH60!@KbT-<8db?)4L?*63Z zmGEiA_QPA{g7S0=3PHWf)eiSDnwmUUG-+SL$OkR_!kiS+m zgZrnX5k)EY`ulF6BTV8=dK#Z=h953Ge(Uiwl#n>cC@{T`5m=uKEnz19B(ZD3 z_bg1GEb_c`Mne0@r`X z3e%Z4&QSaNX)X2n5@zWYeolQz{}^L<4q|6?Q)wPE^*tF%_Gi#B~j2iXG@u6S0WWhTq0_5ml90x$v59S->U?;r2qGBM(z zke58y_*rh%+%l*s98d%Bcl5#dxZ;Ty%{3qVWC&>s7}cUOd7FbVFzmr4jYBoU{k|o= zHR8whxeEjJ0rfh_+d3uV>-6e9m$p7fK;hnxvfM1CzbiMLXm$Uf>>V71k73r*y+Oen z4IUoOdJNj%$!+f8RqCJT1c*h#AY#Xu=YM&&=4>cja8+4`n}3Zfs~U%ppRkI2He3T1 z-vjm9%Gd_6E`3uBIQoaLNOBXjwPLuM1gkaU{7d-OI>LhFzByS|y@EK86*?J;`xRo4 zgKGnYRz19{_14Xd-o*ZTo1y$u+F4fC`Z*u&K!hIv6X)3@5Rhjd;m#!9OgO|)5+PBm zk{5)^H@9&P6s*k4>$>Oa;ntmm2SU2XE6dt0`H^zsWG+wI`4h@e9FyTwW`2H5)x>_O z-$Nr5E5Ki^aRx`1K^ldNJn{k=o`%kN>mWgLey5KL&Iv}OB(qCPC(tGkWK{{)(7XAM z|D2|feY1W<{dqu(`YnPznzshjno!B3wv#_iWdOAYL6_aZWk}QWZvIAJo;! z6s6c4IrKORX{1#iVpktV^JP`QfyfwTmS3T&6V&}zl+~7j$ufxpxus1*ogE|9C(Qhp zFjaroa~m3V2haNgm>5fUFy6o@{wrL~k5x@esC;0dbQ`qB&%F&I=fI~374>lZq|i(X z9kak5#C(gk#=X~IK&QFWShf#Zuq!#J9aVZYF?fQ-9=)DBA*>WhL_-+MuLFdFv9|!X zZkh@ms11Q(N-(??Qs zP0yyRS`n)dKS`TiI>!}Bt;?|z(I6b?6u@8aH*@5!8NktQ?Zc;WnU>|zTkgbk^)q(LErx04d2yb zoO$W!PlrHImv*7WEd?B6*XNR)$Oq0sWYIGK zqA@YhGlyxb@=dC{W<>Vw;f_l`-dUXXw%8Q6`fIZByK35tJ>ihnboZKjL%7w^P>KU0 zucav>IYnxArbW}!Ato0}c*!ai8Z&(OjWo$!I{C-WDpkO$YdMX?pWq{7(sy?IVp!?| zen4p{cL&hYZAefpIvXNhM_gNPsH%E5uBr6s)AP>AP#_Ph9J?mnZ|tQhEtKleEPwBk zot3XcOVD%e&33E7cja~*aGd+*{W}8`{86vq;4&B`&Ds+YF>y1XxRj_RzE+gmdOJO* zrX(&fiF!CLbFvAWH69<^taFDDY+7DUaFV#UIzOs^wJ#-(=GP&sZVPExLhXsoUwdkd$4or`I<46{qD0hqrckN>^pqkTo6_Kn(lq@JwuX@^B!qr^&3;b zs3qWAYE`r_k=2~IEGsV=*PFV%8+?+jtLxy{dwX5Ur3!pF!%%bmPY+YwuPURp!f>m! z=3i#kph%y%@Ztvn;lKN(MBOI-EHFMCs8|^b&@4D@`-TfQ%((is2VeMU*P|tc&#EXP zFhKDuD5Eu5#xw(k^U~?JU*h^Ytippkz^hQTc-lPEg4Js^`YMx4!!nx#e4mycwKwzd z)i*`r1b6kJ1gKjme>J7|f>L=Dwn-QB-l5~7e>{qyIoch`Ft*?U~7 z_ok+$XL>(+T3TE|7615L7v4La)x`}IU#PzEG{j}iGJCCgSLe}fxgjk~htDl;V6e3O zX%W&1lqvVI*`-mRA6Mto&<+vIk|GW%c6$&bKW zTZ~5iCWp}!p@>A9*2-z8==|{i@Nh4I%-Y{S{3{}~52H}LNl}VO*3cBD@=u*f52*e# zSnT)SsE^@jU3$D<{ugA_JLhr148dT(v~z;fA1(Fs-$x{%qC#v-eN-TXy&4WIL%&p` zEd!wnF0&$G(qofk+tNL^eF!o7>7D&9bvB{4g_Qf{<6cffL;uu%x71+Rk(e705ZvNi z`{iRU3wq)n#aIPSD7Sla4wo>#rX2ipJ%c?{_G9EP|1Xy({GZ^8_Y#eY#f0PohNKR( zY;epDe1jQ>c6FZV7OW&-z^*LvuO%oFr@}^h1=j$C%G(x~oF8jXwYD9h^TXpS(Ub#F z6;SJfY~q$A+F>_GTL(Mtv3`%*TrHD2oddgmTW zEu*wH^j0fQX|^k4%}D{OqfdxbLG3%lNX&znPi+Ecfe@&41Rw=MGmzts7g*8zlAb{wpPs*~(S=6TK@hyP>;ezFTy1ZOUuw{wof9b~9GAB@u_Qt>_! z?3_z+ZjzRn1nM0vlnyZhlKh|H`1VC%FC;7#@;W>(@&IH9NW0Of7rUqwt}?op>29!M zl8pz0dhySWK9=1dZL*n)wrNE zg#^ROqtg9m8yw(b+N^{ou8CtefurKw18#ud-^d9R*}KFrb4EL#_%VmDS=adTj^|_P zMM&!no;mHcPH?OH#P^q()&{);>z{0wL5Drj_Wip9Gk*>-sEZYJ>>_(q5T|vB>DYtp zqS}JdS3I=wZ8BsutdVOBH<&Z|=ZlGB2itUMo1gBJi0bH4)FUJIo;M9+n7#W zeY`wEHN0Bv&pMK(P!}?2&MoiEpJWOTEyoB<9X{)sGiV}9fARXoLQt4qYR-Pv2km>I z+w}t~od(yq5rxdNC;l9+sX|lceK6eR%(%pn{4;1;lIh8~FM9YMmZF&-`cv%qKqPCw zcy|H{C`nfCNxZhPDC$eJJm-w#V6%5@)pMA`9`r;5)U6l2UwCdS1DXM>&=gx(g{2Z}?K`fLw^+jk3WL4Nfzx3(CJ>ji74 zlb-zS5d_OGuFDFVzsB{MbbkA14Tmw4r`U7R!Jqp}oQ8a+iQk%WZA0lD^VX8E3fz4` zvO5IIbI|)|E4h`72?J^eqxKOq^TmI$TXZ;*xsFf(mOs6Q{VgpBT;}+B{bbwV7$WoE z@5H}`#pkXVC%wxEwpv-w?;co;Ps(6;Y}oT_i(%Q*t46i#z@_SMghk)4lCjH_n~xs) zbhf{?vr(vE$TAm69PIxYA(*|~_GRz%;7ZHMtG`=ZocJkEE32i#_$8RB@`zkj+D#9z zJ56!SGox3wa_f`-$Ed%m5Vbni!L6EBCxz-gkDu$Vk2%Y7R~X{4K9<6R+MUJYDaM4kuRVeV6-bPg?Gclt1l zkzRt~UwYG-n3UoIh^h_^4?yJ>{q(M3=Js;N5$1iuznn+^U}1m@eSa55Ma;<%?!YkK z{d1-it4GwRon+en^(aztQYC3~lUmA*BOOVs2k0xcs`Xnd*$HLoci@%&vwbg>6Thx_ zSjjdV<6?3rojc%JifGM;&5YRjrEjHN2Ev!Grk%^Wr`027-Cv~gL2@WXZ*0c1%!_jo zmDcih$jKj{owT4*_iIPFLe6DruwLV=aAsk6*{jKZqW1OctaW+rWDjq)*2()rj%Su~ZG7hohDgP z6sH2#m`r?@!nK0x>7NMfn{g)`K9qUe;gQb2JQI2wc9J zs=)F0{vDXpkpcQ+SZz{gnnZ6@_&XlE{=~(xfP2qmx+8y&qTck~ZfceC|Gi{%OS!+* zkXY0&K-@q*2!rmXpNp0i3}@Whc|~pWE_|7U_`X@OzSCSGwsi{itEY3?5|HEbxXd$| z_33&JE_xcbT_Bs@ewAek?&UY>xRe@j*4!`PD}&_8hfQw!rweH^AFbmi7zeJdGDeKr>c;9MVrg&SN6nLZ9u3JZ>2s)PhQaqS4zIoQj?#)booAlzUtG7?*`TNym9p&d8LT-v` zYeAhni6&;oP5qO07x(+{`bqY!&&GrCbkV^p(GkD?25JX#<8F))dr1|gF|I}uTZwKU zC6S>fcWrR!3CBM3^!M!_d#9&m<;*?7N(QtZ-s;b8EFb&UZ#^>bJ89_M(Wkd}bN@g| z9@1I1s8=YhbLEW0)2KbW9)@Mp$e!xMGveg2P4q$?JEt|`EjU>o7>)(E%jeZv^UreIT6wex!YEOMW<%GkC2?IfzK zEc0UEq=y6B*RdpGfvPXxjUZ8Cnu`XgFT`nZuM+>Z>Wr&#ta9*=KbM1#6f5pY@!S)V zM`e9pvDXJSha|-_ORO1i5mHO-F;iJMxpMVRY2eq}%${)~7@5^!p9;5K_WP#(Hn+jJ z6RH^=zOKf1c;eneTf@RLpva~bge%i{u`RtstGl78PZZ%s{ZZEqX<3KlIcl~X;C5pm zh5DZ=@2BeQ@Xn-Lap9I}S|Qmll3wKIYtXjZbB*>M>jl=hiW!W8Kl$?jN*BH?%PG8L z&r!FyGZMP>HMe_uG(5bJ$R0Rl@Es=txbe(6i~Axz>6!z7m~pB+8LMJ_f7CI{dB$A7 zO(1H`|D-;Y?KmBd>E8q?I+FJbt8}OFSbkvo3?76tj=L`Jlp!9n@BSoOIsEx3pdgDq7@?KPBaqLX;jNec28Cxx2q?qVtqGi~; znE50NuXQdYw=_?)v)%JnAt&zF-D)gq!Wx)% z$C}SHmQZ@TqdqRpnf)i#F^KhW$v>&@r0z50syp7`KPJT1yraDd>9fxs{~NZV^7oxj zra;5$&)jp?RYocyOP#g`FEmlw5U|wcmf1(Nw+J-1vOX@kT*c-hmgW3CQqBUt4}4B(GUw9JtEQ>?v1ZI~$_-8CqkjVBKD4P_E5@zOS7@Cj7aH~T zY0OVlXub%>L&(w919SfJFOyXPc9p3Ix^6+7lw;Fp!P(+2M^CCm-RMPxY3sdyZ^Vl< zfk$o}8g~nedgU8<08N{5;&TrsoWGbe|K$k9G-D=GuxxVoFH{j=>lNH>OKSsT7?Q$PvvP_^Um zpX2>f#?AwTy)8f6Q8;~C;-s8=R-$;S`LBzjj0XJt|Br0s0bPv)$pH_p%b%=;`yh|%JuwhLSNNfvlPTO?bq;)R$=>kbpKnC{kH4ORvM7dCxc0QS6 zBWZH-9ldqOj^3t}gW@c~i$c{(bnOgxaHf20^s1NLW)KKp>f^QPHLjjcc^#TF|2%~Y zTJGhV_z~j6jkBsue0Uxw*4r2axW76S{{berXH;$gc{S?By}_SeucTGy)cD?-Ha1$w zsS*R_+}N1~FM%?c8O8oqtnijB5HWMyTa}+Vrl2$DF>$Z2q5fa`(st#|cTq@lOS7-( zf2MKWzd3K+(cPjGr1W;pgBiN>#@@NwX);Y$^3&ulXR)2fosB|AJ49|JuU?XtLZe?+ zpi}V(4gL&I8ddcrRtJ=kXRf&K;p`@@=(Hl6a_+`#ckLz6Te2m$8#8`2?0Kx%wV{m>2`kV7_AxeqeX* zv71b-w*|u}hbBY+6N&!q+vN_UPn}vmnJ%xSJ=sw7vg2^oJ+I%_Y$QlI9ax)mR8s#I z$jBSQBs-c|#H@0OefS{+D6N~*d(tZM$vhv9U*sDMNyoLY>%+wvdtraJPFEMf)t>gU ze0h4|L2BEHHGKd$3MYD;ni}!jKUGJ(1$VX6VREqHqiy=_JjcWp&~gRP_WQG@BtWpBpO3$uRD~LB^&S4WVG8 z9S!E*{h@U^SD^^g!oJ5h-p$!>tbH;)?&;K-L*a}?7t_xP`Dqu~49(`iZMDv;<%A-o z+?~1Oe*1BQGoEyU%C*sRbdxwysf`}n2u_Ty&maN|7$3Mzy!>@W$^3wvR{K}I)G9Eh zmyXR~?-kmLcd|TMIm>L*btWB*{Wjk?|MZ5M>7dhO));ZkFL-89@iI48Ud6RDys+VP zndB1+29v(JnaUs3gS~D!fQXmLIhQAO++G38Evrg#VAK7*p9&jr=t&*s+z-pm*XCJ_ zTHXAFynMjThCgG$z}}99^)fM(z#G3vW9P(;65ZPo{1hWdMmD9#nmoaVq!Qh))0Sy} zIWd2|D4NI5M7zyg_EPIs)U9Ko6Z9j0xaKmVYJdOp*$}xBhufO>)`rEW6S}kg^qU_% zeY$_UL8G?nO7Wa}C`dkA_>Bzl)rG#>Fec^f5J=h6AD8qT})ED_h?-hWYNW z@apO_{mPd#RJ=eOi5>U87O2Hz)ee6EyF1=PdT`MG~Eum6T_oS!^IcRmU=Ki|u5iUe>;H&(dkB^RrcrC=fUD<}ssu z06N8mhoQ9?a)`+a4$5up`aENtn_(IXoV_X#t}56#YS79dlx!`xSi#?{4Tz z*~Y!M^*A=FGsP@u-;i%tN?v?7mqHp4H_Z-$gihMCD zMtMZ)MtkYnUK^+CTXCT3Y{~ss4f~ZbBP2yoz2fJ4A+Oo%?-+-wuz4CIeut*ncsV#@ zXU90r|L5)L#m75Baeb1COUMg%L@rv4+T`;MOC$5(p{TF70E8RtgW~5&Y^G}=rO!2z zp`1SDJB%EvsED>3U==8mQ)BYqrs!~8#Gu=>$ToH-R*dEBXx$$>2hQ98tyBQr3G%WH zL-n4hFS3pvpa1i|i6k@`luc|-RiB-jwskDN!>omVDsZi;IBi6n6`W!3e^994;gRq> zsrw+fx-CIp_3PNJ`K}srtu9dd{ zII$dBf6a@~#uJ=DvX~O`()~BUv_8fJ!Bm%_8^)`)k|$?-XKzX)Vdy!-N?ksncIP0b zkwShAm-M7%flivdNK*0G1;FjOne6SEsfJ2_m&oP^s}Fi^H1{ZpPA3r?O)P%JWaip& zHm%`JyRR1AZ!pIO{v|0kZKldJJ>*hWzS$M(SM-91-V|M}teOU^vS zMI(cyTBi6c&w8rwIisH)5h;NlAD6Q$~MztD-m&Ja#2q@K== zMD0RC7M@iv&bV)=1r`9cHE4E#_GNv~y`S3YDVG6w`O?Bc^1k}Q4=+t+UA`&wNhPM^ z%9H*z6_a{ZovOi`E_b7PTW#MJ0(2I(OYQzlY9@>C;3R8mW%gN~Qo8k$UwgNne85l4 zSG@Sd6;$NxIMYH*t(u8hwg-zp9eo3a%F`OfJ%B-O_3NdX#JOmYLzapn$2vO>0$#7Y zE5!B#EXek(l^@n+PJnWYRwRQNvIQ}E3jA-)8tSR`{=#2DqvG@l+Tk}gm;V0yUiYS5W zKW+%h)3fU5rB(IGEf^tTBcx38+#HDicNXp#AK*2?Xo+7-5UNjpm+ZBxqj`unfXI8( zzI2!U7=E08@`MxpoSa_Lyv6LS+-@2*+s; zo-Y~ZYMlMn{`f zVQpr|80Q@|8Ob4I>)_1J5PvodSuLcd$sO9KLjVn!DbIg31mIeW!3P?_kK`p-@jsvf zDU|Gl{yr%>JMTEUsfR~;g~rZ`vm_r-HfeJ4cgW9ay(;9?B^m`U6m_)%MN0r7?M}i$ zxI~$+nq?&$AfHiI1ZmI{1?st5Bc&9d}s> zB}VWby`U_ide+Fc(hBT6 zIHQuDVZKJ~F~^o-4YtT++I}+W_*<7Upoz!k0e$CUWY#T&vc)7u1WLQ%U2dF9A=&&> z9`&Y(Dn`e@rNsL(mLp*ojbC32j<9S**_m4g@AJxT0s{k6FS*~hMkq+hj`%-e&3RZ% zjECEJv{ResoUko)&oGmaku(DWd{ca6-Ol(|v0>JhxRo7i(PXdYIt%w~(3ajT73SmR zC@%p7P;mP6Ima-xqT=(8dNYJ<1A9-e!$??k zS0TB?R_S%k-OV*;D<`vR_X}G+|EAl>!BTr!aV7{vzJI>JIokQkj#q~xoeT`?hnu{{ z_aE@VFzDAE2=8si@tNx%IbOImPx>r}iJ zEv(t|YV0qWDGxckwXCkX(`o0<_{Ces!s!_1D|q*jqPNUt-!i+V#vTTNPt$Ces>$U- zwf)5Bt_7p6On$+6HNIolIK*=8mR^9iu&9oo_G?9Ew&pls;C7YO=Wwaq_1-KZ!c$@k zZ!6RVeX-Yk)Murd4cXEwY;E_@wG#C3$Xe5n%fe)n)R%D`&4@){heQ z5WE1o9fZw4`I>}2SzNvUz@19{tO~fBZYs_G_ekA!!nY!UQL$8Z!?dzepGEmRmb5*mJ81j4AEcH&YwfnF8?VXd zU{}D1J4KB3zT1pUA9Rj-)AChfePcQ@;#2YRJ9%64A)wF~xAk;$vDal7QT1v<-aa$I z!3N>QfjiZfuoN6NkGs}KqSKGm#jhAR!B=l0%JCTi8QkUc43O7F&saf7|(o!yejC6Gp4l8)AZ09<2>L7HwBXsi{{) zR9QDSXexwd_!N@FL=ml30j`DC(gXJ=8v-W7f;aPQ1HCpjYV(&pqxRcpSiXd~ZnUpn z$6j8a)JeKcda43S8k~Tp5@TG{=j^Qk{Nk zzs5^_9yqx{2YHW&uTISDsb=zi%-iVkz=FD7&;5Y!Jx@T)PSIRD;roz~7jpQq&9!#N zKgNt+AiGbx0o=5E62(b|=*QP+Q7PYO7bT_SPP#WARK2GWOjkP5HYXR!2d3Ho$oG{$ z9OWSis>gkxt&K^YRys$GeF58s{M$S4H>BeCqG$~_@AHzm_8TRB3fpFf^V%zGn?o1? z)Sx$%%$Lf?FSse>JMmZ{nt-$H6*+S1RYW_2zU}Y0`#^~e&c+b1+SuElKE%W<$nBm= zX?abj#H(Cf?}rmtS$)#)c!1{05@@OntoWN$FJrWdE7s{oHf>AfA?X&K7e}kt(Ox?s z#^rNS!F1NY?r$cfCToVx1;>+uL1Dj}ELrp$p|DY=L?L>Ui+IP|(4L1QV%)48sGY+0 zEwEl9b9K(qj>#`5#q@T$GC=#4zg6YCLXrb`8FsEe<}ROvo_L5sdOE1BQR7Uo$V*uj zXo$$8p*8TD^I*k5Txa)!%0EJlMLcUgL%&2=8*T8CF_9~*pP$6d={5go z=9$!Om%42?I~FKA5=E-&q*B&lAF*wnyy+rQ&FTUH`+h>5x-fG zPf|=;<&gHv}Kpl@6 z9#Ro;ok@G!?gCi!u`YlUeg)^Kz_9a$CZwBa0WC({bv!+`|9VXz)uKx$&^iI$5f%Tb81qHr@v69;T5mg0$+P)t^m)hlzpiWK0k@ z^dY1xxiL}N=fBq+6SE}mUz?t?ocYv~E=#gi+a~Q$>0e;Qe3M3YGTq+D+Oo^UuR1GZXjgYYoGfum z5H~gc49YZ2{jCf?onPw~cH*-2&HK%dJW8wd^D(6l5@rDHT^5~#C_SkvL5+HnP06f8 z(|#oWBXH?np+<4j?BgKc)q)jGBMyT8d74Jn`@2<=E-nRk ztpcS>`*L-S?KrL(zJY6;SQ9W@?yDMp^|#dVZI08puVj=YtcryLry4aWOXku(KFN;% zf7trUs3^ZL+;@NhX%XpCL69!#5=m)Lx<b2hx$}Sth6eqp(*u3j%Fs4z|k@I>U-P7oi1!$&Vcj1A_3o-@_yZIbW zdA-7a3I#o?myE&rOBofLy*f_hpSuwr`q%3ei`yWx_)et0Rx{U@akW-d+qYgKpws4* zTXXh@M$?D*)0^sY5d2r;(>op5%fXe|? z%cW=8RJ!J{S5H#AWcGif#lH|8zkzuC=;-^NrUo}i^AxPvIJ{Q9%fRqnx171Iy!3?Y zEztgG508vtPY1+L4`+E*x#Z9g{)`2~LrBi-Af)WmA zt+fxUgRh2r!UPF;c2SJi;|!>G_^jE0&$;uJ|RZozi?t-CqZLhgxg+N zxkk0FXaCNjs<-&rO||#?&j^_Rmo)qeu%M%dAyNbQVPJSBFVA%xgs9e!ATDN^X+~=f zt|+BQfVxRq{NQx}NYdn=ga^^?{iEfn(#HpO*9oXI-cnVVtD9Nhvo@GW!qeZ&I~Bm= zIkS4TJn=%g;G)bmJ`kp3E;+u^ zfFe+fjC<`3U*&}%tmzUq z)D)#kGT9^2gWx8`ICO)nc~?43zkNa`7eeN*gzw1(59dy!2*{@>T1UFp)#<56|Hiy@ zFyL&)ej3zUpQEaujxr3V83mZjS&QuC^N{kRu4=y&ij~brdX%wp#2|kpmPC}NgXLXa ziHAA!Yx*u=d(;;h@c+^=V9#LlJLD5S_o)fYDGX)1s$t4NXoJoMxR8Z8+utqaJU#qN zy$j8U_=4celHQnvyU1hwZ#g>YAIuc{2yg_)U(0pBfDQiu`F7Mv14sZK;*fX9ttNhN6u2GtJsosgYZU8{4%b- z$IXw{*@UtC6&CQ0@C}#{y(P$-goFv-<_qP7$c3i4Mv}DWqw89OQ#mY~g1fTzBdh+{ z(J_iqBRvco%iAGorMh^mo)-TB6@r5B5(US}4!<0#!Xwh(_JvNb((9IX?RWC$tr|z* ze`fA^Kk5ox25h708-~HYP4UYIX0GTITTk8Or25EY*v_=%Tf znn$Yy^*$oC%v<03Gi&`|^A{|n)L_c+QO{L_mplcODVL5uoZUSQ%fH4iPJR^ggX@I% zzhpmK`8I}q1)YY+>w1q#cu%G8>XLg0zYqY!6Cyuy?9heygt)kzGyCcwe}J+~?Gvrb zqt6gm!AfHl9M@6&Q8ea=aU(kfmaCPy*CAY0&xmSJ1T0Scd3-1}iHkJ~NAE|W;nlsa zu3zV$djPewr!@Ye85IeSOGHgz`S}d0@{A_XnNjtpeJ)F`@3Ul@xw|GVi7ea6F z7J5iBes;q2$?qGC(W{yE5aO8~D4fJLN*Z6iP~oUtbnBB=1^;n)Jq zmNf#OAPis%-v+{yDGMAkz_0eTRJ|*zz15aE$*Z1l>)bqv{Nb09%y7QDudXG>13OB4 zI)&%c789s~I;?Gyotz5+K=i=`>w(-8P>$M|D$?;;@X$$(~fZg z1HxndRqv~G1$C<*!4>Sjx)e{R-bS|vgzy7D0-R&?xWc7l9oT*i2-@C*3&;D~xD@{A za9ftxF%#H)>Vp!o9n~;@@6TBG%-7vrE6FdrvL_l)Doja`-^F>~3Krnq6!raK;+2e# z2}_ffyy(3UF!ZmEpSTDe)Qlfne{q@+KL~PDH;}iME7Osia@3Q|+`c=Y@@p>JHhy0$(YzIBHvlI1TX#uy;^}Zza9Zfc~Y~INvK-5o|Zwk9azszMr zv&eid_K`dC@fvW;z5C_$?7kg6t-AYh%fR#*d<8*c9&U&5`HZY2I1jkv$_SggkGD5D z{bnAP9z?!1mp-hsi&})@LsL!!A+)pcdx`R?{Y@b&xo6kpR{ov~@Ma$8rXL|Pe*$@bAN^ZOqRo5dy#968BP@ZR@VAwR_E>HHzZiA18?dS zBW(FpdMw|OggaU)wfhB|_67T6-5W4|3XMFibtB-1X5KeUJ#KLJIN=HuvvIniIa`Jtu#9XmoCmI6HvqmIH#--_|*Z ztHB$szs^_B6m>i|>`I*)PnONXFI@_ybcn$pBAHIIhQNHd4_mxAttB}vKX z)sew<`p*z3_BVT#F*Mc0}mMk;Ety+%S^ zF_pHZ+qaVKcbxF6(({vjx#SvCTK-m3Gx$UTQrO;CZ;#G>EL ze;Z-`euc5e;G<;W*_U<-qW+!I35_`I{UnO6BRbF0UvQBfD=T*yQ-qlyO+u*g*~q_J zknb5C-4FE-*<)j68TI*8#6_Ce#Rgq)Mhi%zbWPjU;4P_!_WS0760X2uAdRfAxojgp zF;L@h|HJ!J%OOG@b& z{P}hfJDE#u)((%{hXX0H?O^BGo_(Qwer-qSrPG`X=Y@V_f8mB1sxhX_J?Y-#o}=pBrpTuxND6h-{t@zC(v}8` z75_9wutw&-V^Yx7U7b-65!PdyP1E$z+!5b+XPS$iZ~GTsmS&1}86h~nsty>tF;wohx zeA8+7NmSyLL!G0|Ty}zfJeLtQ7ig*LgC1Ymx3ZbisWin2BjF>SO5cO!&9Vm~!}6|L zz|eUFFP#%a@~z*PVW2QZ2nOV7nImm(cuC|aYBp#h&fMskobVx;3*<7t%m2D{;PztN zvo*SihWDpn4YjnEk|_4Iq(|%+;6z;!0-Mu)i9ESK9fQ-!pR?g7oTs~;w$r=0X9}h8 z2;FjI77A!X`qIAyA?M#3FGYG-7%(rFtBJ+OEjQV3KfeGi4H}xQ0(|b`dvp|JTv%h4 zYst%j0|Oxsja}mUwxQF(y!KgBjvibsTfwplJOc<{t%qGnSfwzUEEUb4gwK<({j< zkm9?1?bf&RuYL%J1CKyzUe7`oKll&sF2WIgzT8*C1NVWqb<{-SITRzKS?5;^3kwpa zTTzy?#1hrjw}4=H5ZkfkU-XjmH|!4A4PLHZ*sb+1opeR9{G}sFM_-e}2^!)_3HV{k z_IfzUyki7zr}*(R+l}78llu)XwIgPU`&=j*2vp@37L;>Af2Zu_Mc~Y_*%K?eIH>O0 zb>m%t=ab3BEmXE0Ym~|HFJF6O78`B*$&~#M^iPpvAC6bMN_WbvFyiOtDkyI8O_O7u z+?yr2sxCHLd8ba9J|VSni=XH*2_q(WY>igMxN{E%WiW2$iTolMApL8iFJs#LRp6rx|)6>($~JuDZMfquV`?C7sA;VV<=Hueo9Ep!2g+0G4@5C@7URc9-RYv?Uy&kDn8D!*# z%a90?P^zZ4|8`dO1xy>#i^*^Zb0TXXueGL%>_&5ybNPCmPQ=dT6tR|(1maKM;4YAi7ooIbj8OqeCP%0YMYN(Yi zQeVir`P2gLu)KQAttP=fOa3n4vd?*ZUF1wdQ@=+yW@^M-=N38h{9Kh(ghrIQpUWN2 z1pdi}%u+QWM@VxGKGO0^YH>tZu&gFVyu$I6ofgeO*wc_F!J9dw9lCyxsPX=_;8{4P z2PqYV(Mc0y!p|#@K!bzaE zxp!UHg!4t=k*9?s`1p(GIn%11v)%c0$8-zqQex)@ z&F^ltqFog+XJe>0tvjEqoipo%O0WHmRjw@6S%J3S63f4FUHmTnxCp93&=WAkNyN%y zuGGh!ZFM;%%6Rt}DT=^~s(~jgoVL!&0{^p)<9}AG)VirMtw}xdjnx?wdq3L9_AT>n z%+Yg_B`|tyq9VhjeJ%S;A2$P%*63z|ueZtL<-eS+qnD~(r;cR+uZ#s7^FBAQ3(_yr zH)UEJ=WLEod1w?dsFqG77fg*hr&Ugr`3F_D?G?5Tm8t@wS4dQ60!dzjuLMwZ8tRKY z+rf@YMxd}ZKh7#an}XG6jA3$$*N-p1%EL;P&yc(gg*NHG1|es>0WdpP2Fo zG?jNmq>;uHquGdUE%i{!0yj1szncJgI3>dKe+ca`Cma_}CZ0d>07fqL`H_gmwLI)D z7L|RI{_7!3MPrqWeNK-xjDdS!r3Bgbsq;=K4R^XnMM#!KL_cIqSc+E9v*eJ)mNby0 z(9$mV^e6N5pMzxXhlm0U&ymtrq7-a-Gd&pji?nsvZYumVFD?Fk=lsA0GMLi>vZrkM z%Tq>Y9tFTIivn0|sNvGK$7+=iIt7Z>bU+8?4DUSJ1LqCBD8nxYTrAzUPyKF@G4#La z=gMgJ*|AIHwK?;c?|81Fq6oh5c^(kz&QVD7RIw_>c*1YLOr>3Y#!#M~LKT3>-+l}Pzu}&yB z<;&drZ=N!0vY=ZWbLQ;i+wAD1+E8OwCvlmI)U?g#yQ3Y<@R2sed0!}o-;u&0)#`Qj z$Z0$Z%)X}Ys>Ja*+6ttdhrUiOE8O^(KZMcynX@#}oi=~*in0|imU(7=&r6G?{%?h`LCa^o8D5hLSvw&_ zKUA|$hbC0pXiWhgEM?rjXE7c0s&MB4!zU`s{P1V==i(}Vma!N;W@NNjf+Bj`-0Q96;Y`R-skJYOOtROB<@v$%$`hS5@- zDhh|Ah{IOoGxObxK9&qS>u_j7-REJm4ro`Rv}n**{ST;l+-=R@4|Ol=ol3?V{C_Vc zrG0*);0i#4kRWq0?|AZ%QlUT#=GuRZJK!(qO^d>C!KMeRm1I7(ejdQVNkOZvTRM5c z?4i{R8gEcDROB4LF8?lcrxNJ3;y6TVi;(cm|Bb8W9*PY)Uu_df?S8Ay=Dqtf^iH~X zr#xP*@=Dt@o# zGUTTk#*l1HuW#ctgvAwwp6RrcQR z(<6r9NJnZP0MvY1?Kv&kZ@&{@@(IbAlo)r~Rry#a17RD#t}hW>Zf`%BgQkMH)c|_@ zQ$_Jw9}eIjmw2vyWAs=8Bjl2Oo^Up%FZMeix87Uzi3ms11?ncx{H%m1e`$8Y;g_t) zUS~6ZQQB}$0cAqEj_j~{u;mrU^1(JQnYJotuB`7U=e?dNP;g_k1u^r!JwrR&Utd38BIa|IKw4 z)8RPFTiG2&0c(6cxRiC;TE~>C|7hD}IA5kXZsW zN|v~l<~ecW1`x=n8DPSWc6gvu%Ne7OoglLkaEr-tu-wE?NvVpJvu97dPMS!Wo|~X% z--gsI063I_#j!HfAohv8MYj2he#u`}evb?(dYQaeMWQeupwAxbr}OH*z%XOW&Fa>7 z)gRM$ULYmE5zE^L8zR`nVMCa($v_Nk0WIAQ?s7n{2o^!*OlTWdmEB*)!o}{-_R|+5 z;EFeB-!OU8$Fpc62^evjuYo*>Yz{%nlWB`sTQS&usdqwFpB%sB4JV z6lkb2@RFFqW2In0gkgYeC_7>joa%k-&BV0O2|>4{h%gR#%I#xK@8mr3I%0#qod{Pk zjrMco-w%j3Fgt!xK_9Md)3x~zq#xBaTRl%Z_i)|j@PC8Df^^5$#+c~YD>r?`F0{zB zsR8D!vXTa$msT<4bmsns{3dg{L4^5aFnk=|pefVBB{qmZ5&$=!Uke%;Exv8 zlltM?SYGIfVAm*rKHUpwiu$uVm6s}J37Q+5kfs02L2qxRSZUFJsc#HK!!CO#vh9O) zo(SPb&k15r1LG>KGpEAPS|8>DS%`(PqY?_s0D(Q(OS3yZwqWFlE)7?3-V9+NCykXE z26=l4kWlN>x9zCQf&#^BIlJ}TNUh|Naz;Tx{!r<|z8`|Ij(_^ZC}qA!njFGbo6m{Q zuSyJRunlHZXO2|WG`2Eo)`&)>b`0lc~!pM-q%rE2yH;GBtYrpavE*AZCN1bDkl z?}{rF^2x%&WPsikjV-LN6na!?UbXI~;xGIL6sP#)sthY1j1P&p080CI9ccAvl|jqX z2VUX9X_MXsCwl<^fWts(Fs!`)glO!RylS)G-!;QJwMs!+9Xxj`ZDR#5< zn+%L`L_EFNZPQnoZC9lSjw`S1E7p&c;(vlD5uzPfdic_*5yyCazOj{{dbqp9%S14d z%l%>fIl2g)Y&9Qzbfv!RrZ<|5ZdG~)T3Ql13!;)O(m%6CDj}SrBGzt(!K`ze4tDyyPW76cz33T z3&-WkfW5JB^gx?LYtUe5TJIVEKJmx^)#pT2ky=OVWcm~-mmq0U@m zNe4B6nhUx`pel9jjTR`(H#uF1nuf6BmZiFM#ZJvgc;myY`uL!Cv5LLj$eTZm{OH8k zrd)7#LklbXk6R4s0Cr5_+9+J|L3~vc$;M50ch;v_S~~_@BIor_#Yp%&&|CWRP!2Vc z_r_9XC^nZhMWxG18^&iKHKRTX2Y76&kIxZ{(+ysjkuyXE`Tt@`n<9^@bIpU&Dh-cDd#(zqLV)WO^T{9A&v7&E*sWIBKXjih-Tpeem?N zIx_(+OU()S*dXTF_D zX4K`ej6SiVBnX!NR}@+M)9J`oJ-Dqlm|Vg&(HZzG0c(7m=~a%L?;aksKsv zWKUyWtseDK>!%Trf4as})w{r>tvVJ`7f_37*WRpyK~cx4e>D8O z|K8O8>CQt)6KoydwB4uRJ_!obOtGu1FW$YAy&5&oSE9wEk0q1YAe+>o$33L$s8`sV zq+|V^Z@ZBwA|Ded5g0@B&1z}~rA9`rd&+$D7YBPNIrg{yZ9%2C%G2&& zwy4xu_MdA>Bv%5R>ud3Wa6AGs+AAmy?)=rMOJl}`8^ZeGMX}Ua@IxVHF7u+M)uQF92edj^i;sjAaZpfQ`IoZ{wpkpSL z(~H>LfDxX@oCedPDKyBs7d^eE$!GX>1QN&%Of6JPi|OM#_#Yn6ZWisiXFOnBa?DLz z|5M{I3GAO$fY4Zz7yp96fwUQTv9CAZIzOR0_{lDiTY?ybxCK{LocR7JF#lokS>fbl zy0g4wjL}4JJ-bcNR@pDhEEH!^k z_Gf^7cqx|&85%0K{5ZaSvBT=k0o?o*SLnE_y1&1c9<;}YR=W)Cue7$wpKNIM4>}s) zozTLkE|=HTC1gd~V$JSqasA1hir}&qga)M|`n<;UEmc{kkj!F*viO5+tB>qY{^;Tw zcGm-dmD|(Gl5qnI)=?^6$|}1`2Rp6*X~{Ml_{m3B5E3t7 zw3OpVPz4$!sz-@6#P+LcRIc3#;f^2muAs@E#t9LZ=H9qgGK`Q=KLnc`Bqt$W4A_jP z_EL_$uqRJd*Y-~RF-Hyg?guxgnpob8!)x28ei{ImB&)J9?@;0-3`L>dxuq}xX8bzg z4xJUE4tNAz8ryIFCYiQx+BH(%1D(xZ*4?KRIIL*xT*_YhjhGu&6G!zJc@^LZr`jkN zpPh$QX@dm2^V#3tYAhJWqh5cJmmh;58UMMlG5G+Eb1)Xllbc9 zq4T5jzkAa=4~rX$LqR3IVS0ty%Q_osQ;NPVB9dRG6NE0&p$nIFl@wisi+r=_u%m0s z4_~=~wqL>OjfSpr1hLGYJm=rSS>a8lr>fd3b41VuO8r7^GXV&?PkmmETVK8PK8Fso zA~kO=dol8lvsW)-Ptmy5_ql4y@)?*u)#n0NOxrcKDkR$i3y29}Ukj87Ebvh(hI*%| z=UZw7xTTxzky(86vSba|>ycrH`3HS@-#zi!6SXme>!r2fh~r438fuo=0%DQzbG$8b z4CCTq+Oe@DAf;J_P0jr(Yn>=Bd4J_ShuPkGnJt%z4z>#x#RV}o9aXMc?BM+^Y1n`2}c>}1brcZb$I%%9h$_fo-Fuo9rpui$+hn3QOT((4qseWBX+fNioCo-IL+E9`* z(`z(nH+l$4iKU=Tp4s7vZ3gCD^|zx=XfX>bO#~Va7bxol8USw12H8O_EV&d*BB;8n zuz+Rc^!F9-_K5~-I|O_9b{1@Ny^OSGVygF?So9NQZ2gx+q-&*EApdH)EChBnlX5=` zjhp@9Oc1^>T$oGr=0a0los1YBQBBmxUZsAuOsiR32Me@rEn=Y(rIEZ-|5%SK2Jmy= zwnY8Ow@sJ~H9FRROOB=qjlm`~cey`3wV{vRK;Y)GlV3aBU;X2Xe@Pp=Qj8)lIJh%& zv%fQaBUd`BB42n>1=-~3MZ<#r#Zh~l=cd3&NlcHQzg@a~e7pev8#=8OESd9g8ynDU>| zRFZ+pliVrOOiTMm6dVfZ@8sap(mRKU{OH^4n7!8Tnwn$gJ*<{NM>`^24Gtb}-}z8} zs0i9X+jWOaqKBpon3scaU7ubDi|{s^sWoH{yep?8RZAHIQ?DQ+Z}%z*BXGY#aOch` zaHo1*kSw~;jzC48u`sk9cJ1G`d*+c{_cI-DQGVOZ`+nnYhfTcoQ)hz% z>Dx~}l8c{lyxyVfDwD6xAB*56F-}&~l_#NtUh?tULJ2VA`K8T*Y`X=L7#N!!0d2 zs*Vb!x_YjJs>HDPDxQfd9%e&y@LCm|>5Sg&1IOzz8?t8^vJ1yM-hgh_sQa&}7K+Y*{1Gef!n80@5-z`UvK{` zWEMI)tj{^`1_vb-<9pgo_j5O1`4yIAyZ!b1lq?+5#GtdOQ*&qvFZN-Y>)~o&&DnPkuf*iepu(n-n;`q@ zETvBX7J0|&4XLC2be`XLRI_hq!C>-Ne_J>iu+;wqQ+mO#z(BYS!B65VIJNmOEkBJI zIHeHTZ0KG$v7woqMr2jP;iWmrH zae!fEiGp*;||8^}PYK+`wJqXZ1kG(NpoVG!9@3lie{$l2#`EISHhKon2zd!2@ zSR_V?FoekG>GkVQRo4yX6kP@MH$<`5|Bz>CNi(x5eKGk6f0KmsVnd-Qx?8dBHi5!v zJ(a!>C7d?K_izF;7~RDW-ip8`OsFD-_7c1_1=@EjPMf|5U&;$GqHVT9ABYeJD{i?U zkYnp_zQ4s5f7-L@4%4(%PusM6cL>(fV> zRO22EZP~}4`3FXjRn(Rfykve|?BQz(xjV$RSirjV)z9exXj4xs-etdLCT8hpXd0iMv-F>@h8YwXcvW z6_#V~K|kM)vn#poi-M9JhRWG+FhPJ}U?sZ(f;>!mn)(D(pPMod;dJgHfy=({fo9OC zk&bW15b{2e7GjcO3srpNB;0J~g?A{S9npAvtdS;>$-v;XL~G&?gw*$nNXAnIHhSFA z17e=A3@l})Xd-G^C9#SDm?f|C8HVXTsfO|)|5;x{8p3=#yD(>aGJW9#{jl|G&#f4G{}p1#zq_ouK||(DY%QFRAqV(sAEnR2=(exbf&WW;7}apFl6T^ zXUx05f#evj5Y5jAc|GqeVKdFi(zV_XeuiaCvjW#Xy19qyg($)$dA!u8%}=G@pK4U4P0R zhYRsQSx>_9!IeWP&x^ZI%}__?Im*#Z{q5$0y`MHdJq| z1}QKMoTBUkPqV*+4wY&sNaJ*3#gDop+C6P}h1bwI20$TDvc3N#ZqaRjqnl}@qC)1f zX!k6pTP2ogX>+Yk@7xjL4@C=?G#0N`H%f*1etCrA%tIA-f;e54^vX=$eU7^-afksk z$mr(o`cV1yO%}U-EKJ9Sd2y#^e2V#-gR343ee!~>Z~Tmslr(s|5Lw{A z`|=}8`^)*~c=i;?F@W78$N+}YRb(}T7%L|H4W-`A5yA%77%iXggjW7_d3PSab>e=@Id~M08GJOWO6x&eL zy2VaLfkoHexPsOpZwDM70UUididnR}q9EWFc}SN#HEBDZ`aqFFq#hNdR`2t$8x|u- zuW`?N%3W9W-twlO`d+e8e_~nyxHhVCL}6_SL5Ib!ITUFyDwj!kVysYOLRFY6BF~_R zfBO*Whr^}4Oz6#%L$LGUWoJH7FLGkV!!C7FUy?jFn+D+Zqkt1xYp_9~sSos^pNR6~O0iw#}?3PmD-yZ+OKFtAK zuh$G8&XCmhuK$+z>=w2Ca2v7f)~MBne<{ZRw7o}wIq|0k&N_vP9@9AgY-!PNS#)u6 zB(+r8c*~!(*0z$w8M1Xg-vU|tGxpO*j{!nLGXIa&WlGlj(2}TqtT;gsvU#U~C@}&^`=<85(2F5^dwbR5V?a(u5&u(FV6o~% zp#4%xlrNyRnoy!h(=Y@q8=ruWKM7TIY6m62)W#dc(krUT4*PW3HSdgW*fz!iNa!|6 zIOAcB48;t-{m2y>4#54E0};lZCdUlSa@v4T6=Tmq)6#hEK^82)^*J72{x>Cj8*LI5X{t?h*?%zFr*oH-rn!XYFYS$Qoh(rEwah;GRz=)q9(#eb|0y zN`vTRuJa%O#=G0Z7vV(k_unNf92=&O8sXGQqCAo8F#$FVMh$ z{049zAkD<3j9y3BFfrQR9d&8cN=*9LI{f3TXc3!{z!-l^`k+UzQi+L(-C4ofnMIX0 zKD54u$>mzAR*OkiV4U8=Xpg$cCjMWK+*{^hWja20Rr*-%T4{Hd!2RNqVo&}B!^#G) zZ}`QpW6LeeehkLqZM|Z8YdkHoK*79f$IZbA;-=1@(s<9C`aRdK(alh0Tji4`@OX%I zPnz0>48CiPJ-7PmZ3vgQ#;frkyj2o@QUKdLOW8i*cty2vM6@YhAyAm$?n)MKq4BJ* za9m;t0z|zJ(s#&6s+I2P4^(SC1{dbZ*^NAGBFzjGW#1!D3w^FGP zHcVEZynZAlMq8qDiWI4;bn7XBlM+=4%rOUOt&p!u=ZXycMn*&?31Vj&xugifjI;MO zRNR^iY0rzQN*n|q2Di5cb5z#4(3CUPRfpJT%yRAUp0Y9Q@XM5^(PCDWS8}aBG%Eid z)NS}CSbn@QC!uV4e=OJ7zw%WXZUswwH7cLvi}Jtoki?-GvisajyQ=>Hsh26&2=Aao zM@J9kPM%ZYuN_43QWjT5D?})OPisSzM7-omZBpIGY+`xWuNWOzT;yxf1ardmY-c~& zt{l_v^L?@!TDCWtT^nJumm8L7(9%)8;R!-r{uE0*7&u2igEGw1qWO9uTR*ymaVZqR z=2Qn#hDj<<&utWE!$eT@ku*7oKByTHnr256Q8F7bIoh3&*vxS99ubCiEKgzLDVF`C zQEc+PY#Ie~dGzs(@8r#L$^z5dI_tP%iQB8(GrOzDOAy;b(UMsJmtsIX4c+Bum8O@} zL7JVx1NVT`^ZTSp-!TiC=p}Zu0GIgaW(*%PdePRE`)NzpXDig39g~O3bBx3+4;B$k zTNU`qY)F+e4=AW^Z**YsEY=`T-%|dR4D!JI>%hs=-ukuD7Y#ut?^Ggz+a34lovvDn z5>1ggApR$bGM~ivb}cSNYf>k{VaD9qM==NZ4b3B@+vsIkxwF`Xs%JAc(&W~ufsF65Gx3cic=-4O5c~W@j z`s1Bz?OkfMdffSwXyf7R!X&FGB)Hoi9{zRhe3&={OQ0>=wER03sBKXv)m7zb*;j0z zl>!FbUx_4@%@8}%=)HTF^@6K9C}#1G%4w!-Zr5)_PP&KRB<3yRb;~`mI+49Yz+K__ z?Pud4Rofk*VE2XtDPJ;2iQ$@bLt^MCUe>DBc2!mQB+05$DOXp>MsXoa4t%hr1NwV4 zx?fI~e*8C1%02TRI0o(%6|oW80wu!eV~YgoJal@NI~%-y5ytlaA*aznL`vkbE4I<$ zpy0{!gkqnSZL9Q-ugohMsx}Wm1cruHMfu+4BkArEpOBu*y)LX5)f*2YPpYn zMdAEICu?q>=SSQ57SR={nfqrMO>tSSZ{M1JzMh{&z?wvkaN%@VHWsZ8!!!tVC?O~B zgBRaW*}{r6uU*{tBr(c}kRx){D*EKv6E!Iz6Iq-JzcTBVni%;-zi<9%5L$NX(RfR0 z9E1d&i}g-OnC_lWlH9)31+rLh7cnO#%5VL^+uwLD3t6xoLV@J_JH- z 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
0c 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 literal 0 HcmV?d00001 diff --git a/docs/images/hero-light.png b/docs/images/hero-light.png new file mode 100644 index 0000000000000000000000000000000000000000..21d5ffb95bda5e67919d0549f1301dc64bc2c702 GIT binary patch literal 94351 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≠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 literal 0 HcmV?d00001 diff --git a/docs/images/message-anatomy-dark.png b/docs/images/message-anatomy-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..a3255568681a9baadda6b36111137445a9bae306 GIT binary patch literal 71062 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 z + + diff --git a/docs/images/src/message-anatomy.html b/docs/images/src/message-anatomy.html new file mode 100644 index 0000000..8ae240a --- /dev/null +++ b/docs/images/src/message-anatomy.html @@ -0,0 +1,130 @@ + + + + + +IRC message anatomy + + + + + + +
+

One line from Twitch, four parts parse_line() in twitch_chat.py · STEP 6

+ +
@color=#1E90FF;display-name=Alice :alice!alice@alice.tmi.twitch.tv PRIVMSG #demo :look: a colon\r\n
+ + + +
+
+

1tags

+

Only if you asked with CAP REQ. Starts with @, ends at the first space; ; between pairs.

+
{"color": "#1E90FF", + "display-name": "Alice"}
+
+
+

2prefix

+

Who sent it. Starts with :, ends at the next space. The login is what comes before !.

+
nick = "alice"
+
+
+

3command

+

What kind of line this is: PRIVMSG is chat. Others: PING, JOIN, NOTICE, 001.

+
command = "PRIVMSG"
+
+
+

4params

+

Split at spaces. A : right after a space starts the last one, which keeps its spaces and colons.

+
["#demo", + "look: a colon"]
+
+
+ +
+
2019 version: line.split(":") (without tags)✗ text = "look"
+
now: parse_line(line).trailing✓ text = "look: a colon"
+
+
+ + + diff --git a/docs/images/src/terminal-demo.html b/docs/images/src/terminal-demo.html new file mode 100644 index 0000000..7e0d364 --- /dev/null +++ b/docs/images/src/terminal-demo.html @@ -0,0 +1,54 @@ + + +terminal demo + + +

Practice run, not the real Twitch. Recorded on 2026-11-04 against tools/fake_twitch_server.py on 127.0.0.1:6667, with a dummy token. The bot runs the same code it runs against Twitch, except for TLS.

+
Terminal 1 · the fake Twitch chat
+
$ python tools/fake_twitch_server.py # chat lines piped in: "alice: hi bot!", "/ping", "Bob: …"
+[server] fake Twitch chat listening on 127.0.0.1:6667 (plain TCP, not the real Twitch)
+[server] point the bot here, for example with these lines in .env:
+           TWITCH_IRC_HOST=127.0.0.1  TWITCH_IRC_PORT=6667  TWITCH_IRC_TLS=false
+           TWITCH_CHANNEL=demo  TWITCH_BOT_NAME=any_name  TWITCH_OAUTH_TOKEN=oauth:anything
+Type a chat line as  name: message   (example:  alice: hello there)
+Commands:            /ping   /reconnect   /quit
+Lines you type before a bot joins wait until one does.
+[server] bot #1 logged in as echo_bot
+[server] bot #1 joined #demo
+[chat]   alice: hi bot!
+[server] echo_bot -> #demo: hi bot!
+[server] PING sent
+[server] bot #1 answered: PONG :tmi.twitch.tv
+[chat]   Bob: 冒號也沒問題: https://dev.twitch.tv
+[server] echo_bot -> #demo: 冒號也沒問題: https://dev.twitch.tv
+[server] bot #1 disconnected
+
Terminal 2 · the bot
+
$ TWITCH_IRC_HOST=127.0.0.1 TWITCH_IRC_PORT=6667 TWITCH_IRC_TLS=false python main.py # also set: TWITCH_CHANNEL=demo TWITCH_BOT_NAME=echo_bot TWITCH_OAUTH_TOKEN=oauth:not-a-real-token
+23:17:02 INFO    connecting to 127.0.0.1:6667 (plain text)
+23:17:02 INFO    joined #demo as echo_bot
+#demo alice: hi bot!
+#demo echo_bot (bot): hi bot!
+#demo Bob: 冒號也沒問題: https://dev.twitch.tv
+#demo echo_bot (bot): 冒號也沒問題: https://dev.twitch.tv
+bye
+ diff --git a/docs/images/terminal-demo.png b/docs/images/terminal-demo.png new file mode 100644 index 0000000000000000000000000000000000000000..cc00c218af8c2373391a1d4afcd5a77500137932 GIT binary patch literal 93724 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

F{nh2#3()w_MU;D#Y_w2!vAj)=L z9y#PAI0Wm?;2kc=TM&t`4{-cdt(^m`=bmz`kgE23Z^#q0oxmcmGD|Vl&L?}T{T{%2 z9Ko#ebP~iuJ;PFS52%*P049z`p~U1(eTvTV7d0lQk^&1@P6&La{7vVM>uL=tm~yNQ z6r^sUQ?dgs^w z=C=HPo9TLkjMUAC1jSCu_3Po-sxUEq(3g6V(6I$y!k2$AKl%>0C!8+8BuV$o%FB^BS!;W9@C-3{ z_v6>n*1ot~ptGmG3KzH#W`f@n_AzVPi_S|&>C$*WHv51IyY^ZE6S}Wt^gu-1G;=BE zlFR!%0F?yuc>oK3TDHnKI|ta#oGLpTj-XlYB;lF-r(^*6YRn&2?WzCww5b2;kU4oD zPyIKaYT`6D=!D&*rEy|T^1P#kJliOva*PZzN-PDSN)kWQ8%*9NE>CZ)tjMsu-z%SR zc5>U~n*uS-ZLZH;DL*l(fQq2dew+I-CLcvg>zCfpFcmII{!CAE1U^<HYD&N zr43{oWK$r)h~rJlFH}!-20qush`|Oqd#nQ9g9|BW8c9q0d5$yfi2))4L`bF#Jrv=8_x6x2^d%+naN0P^xHDKlG&fgaig8HF@<(6|6Ix2)Dv=MGfuCS^lIH zFswGro*kf`ASqjOiXp3Wy+Rf(X+1Lyg_v~cV!T*dk5Dgs@VT(c`FOG6D8Jps72Bgt z&L*DRp6av-TecEKJQ4vl>s)-oO79cBDQDVcMyHn0Sc>6=yH64e1Zf|ddkTL)+*v&g z4&IEVHBp=3*cLjP%u-ZVq&-0c8E2v%Nj^4VLHs?KdA~kC-`)MphAoYPx0WmQj13Ed zEN7KUzUaf2RushUOR3y#pviE^;t74vV@nneL$e({7mrTWENUR z*cm|_j`IG!HNBy@t=KILM`TdxM}DZFtoljVfJK2hwRj07AXAF4Rc$IUN`d69cx{;k zjf!Vty=$tpP=W3EBJH79xuup^XKwK>MzbVX)Lr)rOZCTXekPwMEdRbdz-oRWgK8tiEmB6NcPSJKEF>fZtp+Q? zNl|+hMB){N>(%k*f*LS1Eb4OuR%SjKaJ4)20jmKl=vKo#W|E`5mKwGxe(AVvE!}qy zjf=!zI)a?sCy~D`)l|d2aKYJ*dssuUJs^xX9fo<+aNP_R01+Vixw%%6XK7vPn7;ji z3%qcLMIvBd7N%V{FT1!+i4-^uIZjS&-?H?byyP5#uc9H;*6rUo!@tyH+|Yo9ya57? zx-UgthJRUI{PVPFz@-UQU5CT*TaORJL-*w9K!0c*33;2w`|F(79~r>xJsS$5vrYJK z<#9aKl2Pb2N&j*$E9L5YMy_oh4fU3kr4oUq9?%n(;c*Fdddx`J<-Qkqkt(K_Fr#bG zUqPh3nBo}!UEt|o%)HPhWDOuv-5K(yEwcI--4}@M%=BKw;f4_kdU|J-z0m@;Vv@*J z<)feX7t+TgBt$%PYN*XDD*1f%uYulI<@sMYJW=!m0JVf*pjY=8mCeh%7=2cB72Q> zI<5j%{y@>yK#Mf`$mDVFH^Gd$`0^QdOVifPjcd$gy#kB9YO-Lfr0tnJw}tJ zAG|#h2$2wZ?&j4eBdODxT9x0abvZUVQz4m8s<^k32m-yfWeHg9U0yD}!avy1=XMSF zD9a0XLSH8H+R*OHN-?81H0M>ot`z|(%I778x0Aj_WuN`oBPaLTmPdSi*sH-D#M>Vi zYdM`t2hZ=fK6eYKFvy|MBy-7)(WXG*aQ00>0{74YL#}h#U6_zm@i*H2nS5DLoKMcm zHtWRj<&#Z+{Q@k?eeA}_#O$C4;X6VdrX7>5VB`x~>Tl9yJ#WJKum6JwyBOcUa{vm~ z#0FKEk*#zCA@g}NsARK02MdsxC%t^Bmp6a*>{3an-(exj4GxZuiGd4j z_3CN?@Y8vgryz{2KcCA?D1+B$FMtnwW+n!~uU{u+goD2=)oSeao# z)WGKp$5=j(gB9z%5>X*+FerfKieFX^zQPaRzUV1jZpxWw7c|3};&ATd756;@?1;a% z{Ym5G#h%x4OJGv=@GeGKSxa+yN!W*oIyTlGc&a?`o*>NHvNv>boH~zb$7=@E^7#im z>g@hkG;N1a%{Eeb!Rxgg$mJ?|$bnRF@u<5P4!1-)Kmhai;8#k=eQcEJuMfs3gL-G_ zJ4E*)#p()p#XT%_et2+(&&M`=;%-zNTE6MUgrVy@aWeg?^%b9v|2m!)4ICl|WHFav z1P6*K8qREBUShTIy(cflvBq+bZz?-cN-Xdj$1{rM5vTS<^9mhQ4e6Qf-cHc!29imz zl=7Y>(EwfFmd{1Vx<3-!ZM$K>M~g6{AprDMJ^7gvV>1_SpoV2kvoX>^c^qGjW&IOBTMOyC-H7)U~V z+t}F#rORM~&|vg8$aKTWAEpKVu;>~I{Je-$!$DAUAq5E(2;TDF$t`)4wuyS}>41nL zUzO$_F-s;VrzeII0RQJLx_?gqf(*DbUtemlkF$Vj0u7@C%W(X@`n}D%pMZPYQ*nQf8=QgLD>y$}R4_mEeOI2o@8K{6AG{szp4ZWA_Gs^lY{%R_p4}@QrDT zd7wd$*-boo0VL2x9e=kS=n36NSOzT6z74J`cZ@d1LvE~}Ezo7uX)snz_b9l`GG zO18CVC1#2xXnXt<;VsAGlI8@?QJp;HXg#3~ctn1N+sM^U1ihdLA0_EkHejF4O_zzx z>g6Aawj?F+pL`EHu(`AaNZ(nYZi#*=2FlB`Zb{{RY|fl7Y$C^$dJeE{etXr@8xEWE z0OFY`HVlGZKTRiA)mKI|&CBiUT5wP|azS*Sx45E*s_~Mf_I>5Ohd6p>t7F4!5-n;L z4byT?U3G-PuMEL?cM6o45$Qn0`dRai8La;F>(+ChzFkox)Mx94%Jr-xh<5c3)pRZJ*k z@fZ`4kTlcG8K0nT7d;lNazR!hlWQZ}n~WPm66zZLwqfnJDq5M)Ff% z-#xdt81J>sTSvL!c!;oHM#ScN4BE`<>tW5eXnE`7?zZV>(<}>No0jGg1I31x`@tQD z!2$bw=BG?7GY*BTN6_a08|LUx!Xm#9sbaj;G6T7|W{I$||AV$gP_&)?X4@8A3UqZ! zvPi``hjXpf?7+-odbAJDLu6mSwEx-Dm?{dAny7Vo%znZ!O4(vIrX&DV+mxboMpOu+~qrSHJDR(A8 zX|wD<$`?mw1`(3Z^b7TBH$szN-Vr)Ls=u7Om{Hi@CKeAPXwV3Kd)^Dudr< zP3)WL5AHxDYZ9{ZLAx?fVD3XuqwTlkAVjsq;QLI|nO3#noE-E5zg+ zfbQGeuaTy;w4`RNcJd_bl_5IOlYU1h4OkoD?gWdjVaxOjvE;e8;ovn3`~Mrgic3cJ)D7fMnSD%9zzRHmpm@F$KrdlVY;j-AM7R^OY&3v8>g>b* z_6S6jz>jm9GQ&Pouvp-ch5o@9aa$`YhJ^5dc|AIMbEX?1;hRz$E?RO#gn)dMd*vWj z03i4kGL5WIokSllr-9=(R;y-6ZFG&ofMXG_Pt57J$f<4I3<3~z4O6gmpY8T-hdr3car!YaNKO6FW%PKOLrwhzss|8nC(7=Z(5rc#?FjY z4EOQ|*lJ5Zt`jxQ?7B~n5&MIs`Kr~LL+-yYTuWh?Jo1Q}v&~zx{BZNZ@se2QaA_&U z{Mc7sp^qx+jc5*khe$LZ3Zn(hsaDC(vBdRv5$*8JPdAvW=IU_HfR*aMIk|IB#Ro1! zkYh|Q*933LO(ZciDW`2ygM4HWO*2QP( zt+zLS(r^6ml4Qj9YQ^KJ(voBXJRAIps1;y2F<>~)3C^Tr^E~RL_&P@3IMhm2iM{og zvQ0Ctj{_jHg;dSjBiTu$(e?GSqOw`y&6PDHG9#W4r35&4?9dX zRhMRSqxfM4nU)j-bv*93%&0sF0E zhqU7r)rtFCqn!B0l$e)2qGpzvx$IR^CKV3KIrv{rJqhWd;cA&AGCZq4ntOWIPEza!I6~iORD>Q_p zcL`o@%op=!Ogs`0_SCC>{&%`M1DYxv7<|q`yD%IRPjH*YCKqMu6FJS9rX~zwanX^c zzyT?9t_2$e)|P4JmVdxu!O0FKsA+h1HBB;0T+nYDi)_BP0jtOpc^sqx$dP5;FVqo{ z5}z_7?^fe@+$)6BLC{8AP{xG?cAH;8zxNK2QUN)5zoBXWziGPs1ySV4ke`0)L|+`$ z;b;y3tQ8SM8t=Th?3m#GjBd7xYUMK6VlCwPciRv^J`!=bKeO6*=(o`GRkKvfylt%8 zFCKh)DiRO>oA%rB>))k`{Z%T!e#2+|lFP!ubEyF);gL>UlymRSQwRbhPwyRU8{D_oytl-y+t7`2eedCltS^M(0DAk5=7`>_|zA|~> zPDpaH=FVvf9xw|D8x&@?5RU2!tob1IT_(XR4Z~2L&V>dj!c~EK&%*%j&&u8FW&}A= zekTSX+q!WWiLdwe-J7I8LHf*KlgA+Fl-&wa(Re2IZ?^98GOw40%gmN=hK#+UW0pN% z6dv+SU}X9dtC+SXVHX>g`D?@F)+dkGnkzSF`|IrtQ|p+t8u%Scb)~R9St*{S)SIRN z-a0}*l$U31@D=VdzIo~dK&*beH(g(k*9z8HZJ*X@mcp9#@&o6R2$>F}ki2B%HMW8q zKRi5))EkqtUEj=Q(+1jT=6V|42tEKmH6eZ4I(c98cV+WOZQ{(IB9bc=vl zQjSU1&#vDA0*xu;ZI}^mMffuvy8aI)-5R(i0mg!JDQtMuMjxhD;3^-#@;wvo*0YL}%gbi`@U>DlRv!~Od<{};S2u0q2TWYJvH&9V-#hYXzn2>#=`GK^w>8##BYIzXD1E<-5tQkP1M8#xcv8%|m(vQ&-P$>9 zXOCu~-Gr>dlS9B@-%4SwmRizlcoVT^)&;)w4`;`;AJJ>Uo2SH&A~81jy>IkemO(+9 z62%70KiWSmH}$woV7O{2+U6&p(u7hCZK};Qv-!Soz7)r2$|f;2VjmEweybxgMcMTU zF2Hpkh{(>;NW)3|jq`q$mo^cJZX?8o!l+eaAoJsG|(VdwsY;Z`FTA&C=X zvr&raAx5vGNu4M3om1;Nut@OmEr6QSJu|Xmeyj{|ZG#`~@YPGVq|Q%;=@SZ8lZwDs zyrmUCKYx2WXWW2uKpXmBz+KKgs5M?GA1m`nLkZM{h`ha`_blkW7S9t zv|_{UL!xrit>aELfx$cj^b609V|Du{9?wexl{|yph7_je*u@^o3WY_{_3)eN%gbBk z?&1=QjlwS5Nri=SX74@irGX!fpD)U={Ie&0%rWb%CI*_kD~UwVrbD0aT*6{A%q;FU8cB(+Wb&>^ z>FbT|^R2`XD~PddAi(l(!N%>GTeg;|@PeHk{)S$y#&DEC>+G)rSjgj|pqCTt%j`Bb z_mTG-s_ti*!Ttlb8_K|JJZqNK4_1I}y+B?_W$k_D;;{XB;@KckWAgJM+_WmV%XM8rw7I!f6&iZ4!!nNRsn+?R3G*}hC919$ zmYjYN?^y__+}NnN-yHR!hH?4>=MCn7{8|rYpgp4Q*&B{Par zV}`Qjh%?{ciQ#UzyFCuP!U4UQUEnq7$AnO*Np!UhN$O4!MCmtp>Fp$QTWd;t`8^(A zuleYHhZ{L#d~;*=+X*4(DGR|T0&k?{h;6F+;uPzP$DlmCN@Gr%n@$sE9{!EdtrNJ0 zVQm{aT-d)3WTBrI|98Dz5p8W`iZwUJyDSK1^?KvR4H^9Vg@Qp#!uE8r@b^{XjK#x| zA9f=0zU_j9%FQe&P|V!=3o9@*B{r$|mK@&{c%;mBU!l-5Fyf~mF@k0SFS~8 z^k1=Arg;qOP*Lu`n*`Jd<$2GU-xOaS3F?EU0YGExvrLyJpyR8i_S~`xf!&8kt;-aF z(>78BjTOx+K)Llbkc^&r?)Ko&#p+ikBB%#9{otZ?cRZ(z$bC`IW8=bwd{Ll^5Pf++ zTK2Al@5;x{f@~3Cl=ZsRk8oQcIbEUqtqyd~&W^}Uid6u9zCikriDr>{q_=5@4a&B+ z3da}sq=4i6;;uv|&8^k6~7o;g-n8LiL_QFO{8fY?og3Pa_G z#Z=qB$>S_tYjf#aRMGpzNv#fmnTvkb1u$Mjz;2{+Q_KRzi6Axrbuk$fy52e3_eDOK zN#U@hjr7yu;jp@vx_R}^o9@*wch_VqfHrk<&r(){EPY%38aB1zh4Y|oMCG3ZRZ9`d zDaGhX7<`ohMzuPmz|KQD-~i191$qQKeTpU4op2O(h5Ed0Xg)#>HsC`I6;#)Dg4Ilo zwdNnxh?&*1a$seABmPC)EhtR{Ebo}W0&1C}t{nBg3?GBEWHR&yIs)rnlkNKHm7C^U z{cfKisDC*Fx(&-*uT<~j?cQ+_oS%;^%%x^&=*5Tto6NA-q}N+&BG{U#Jt(mKe1BZ3 zjB?|@OW-#S--o!rFprDLpnhekHrUBD!#P}R>1i9lG_|}+%M+`iUE*9;^gIaI&4|Ki zA681Xh-@KG|Mjd}Pl=b88n38vIt6al6G1jyu#z6g&^I@Ey&#v~d$6xtfqT~gnr`Ik zy{x#++O`vPDnlZ+wASO9OQylhhuXJOGh))BzTNw%U+-y|H;%0i`87HGF){+cP=H4flr5B^^cSEnsPKgZ=<#Pn`|LP6_nB8H$zjf*(x=e_Lia zucAs)KW1NmH#K!Aw}+ZKfk8_x+3oIuN)S*#~2%@=rMuW#E@TvV|L!(TxAnWN*vu!(v!=ZY0;^*GPGb$ z{SnF{_1(D-py%G3lHXW=Ry}=5oiH-_xg-`pCCh19zy^*S@y<2}0 zSaZpUAmHXDO`x4A(ej&IU+zOByCRV7oCJU8fYkLxY;rpo%C;^Q+CaKx@sWiCl;)Mv z7=Z9EE3&_vXW!|cvL}i3KC{=lOf|GvN$9Q2{#R{(RuwfC4s-i#|HeI?c>{Itp|{-| z#MwaJ$Do{HUeyK6I(*>DWpDVykr%%n2@VTXsG%a$0k&a+fI9J{`|$T_*ySt z8L?xD+sT#*&GucEvz{qB7m^$Q)5j@#`2mS6H9R$u$uIBs%*G}&nm%pD#cSvS)0zgz z8rRu>1G{^tr>!w~VeNmW!iZG}Qz_#7zAitAoz|^>h<&qD<|4!c16TL^8sYC=Z$lAqeK>(?{&X5UW&FPyb|I0^3`xN zaOGW!3OHl7LD`SLV(nrlX_YCU8>b0G@T*Bgm{GVNMA?QeuuG(hG?@wXH1lu+rQG68 zy^5emVrNB-{Etk94VMP|d^|`Jm*C-p*=&xbgCfoYsLA;rFTs`G2FYWTvlGT-!oPT)0Nw24Vm zDG#t`JYw=PXlT;7MHzZ2&Q6IPHrf0JY0f%t5s3RkK8S?v{ZrvThZqc*84z-yB^ zx54UhlGv`YHhhZn^NWe0KHj&)t`V*U+Ux%Wvd9l)2I#1L+JW9W^5d6`8hru-eufn* zFzb|My4!O>=IZy%$fsL`#eNOBnb(^t_bvgU-Ph%#)HJc?3S!eo0}DC(ip$wjejz$7T)ofT zfzoOzzO}vAvyn^@)B7Ig+$_^(2v%7zn?`@&VO*mZ@=P zmiiU3mJ9WoD)g5n|H9J$sqM-Fn#i(fY!$Q-5!rVY0TCrl5M-buAe$(n0+L3S&?Xv% zC?HB$Lg+zRMbl|<5D-Kb*#$%dfe>WhF)R`g69S?@LPCT#VeeP8&iu^h%tt<6<>pnr zS1+&X+uQ}toJPx8wU))pm$^NeVx-Y8F@3+U`6G1plN+szkE}gr$ zU6~m2Q9(+eB}mBV)byZ>T}7KSG1qf$$)WenV5g3f7H{z7sGOCIV*%`h`8vIdi_NZY z@5X_3BR`@4zAy)ajG#ESeI<3>Jk}WY<`xMRW3#ie0oI=~NoWSb2Y7z`{xt z#lX2(QZPyK#N|yT$6UOZ&L0O*7v3e!NiyI7kxrm9D~qmnDc~_Kr5F5Ewgx7j~I1|N( z)ipcaE^w@>I*Nci4m3qy681SB=*kdVACfzN~A;Z1CQce zmXQ4HSfj3}Hj}|V^+m>`F+E=^QjT|=eS3-Qf=K~Aa3pyP{p7RGI#BsgGQTP>mcK{l zRf7XzD49a1H^j9^iZkwC`LRihc2 z8d-21pq!5QUG*Oib>aDMDAM$RxP=zX-_Tb;VKOOi^c;Q`4+|A{RC2DE$RY+l4@hh= zaZlIY{pPZrxLA#yT@Cr%L(W?9+{GxbbLygHB3wq3EWP^L|8=3SccjJ(led??pVCN=n}h8s_W2xms1|KYs^<)xbJZ*du;h zLB{34!%l0VqrEm-sVcJugcQt9=vUYDkk!l@ZO5oD&5u6w>5b!y)Qr65ezIW6XOLx* z71{8m=~?4C{kHOfQPiqKG|kJR*Mp}{*=-h)Q`N0ipY3B&bSP9T>6Zsi;L3;Eam6oN z@wel>u^$Dyu6x^p0IB`(c#Wi@tSr{w%4wyz$Us7Edd2nRO*%sY0OY*+{$xzDz%u-I ziN&(cq++B^GN#XW+al`TCZC!5MMIh#^BsXA*@hJ$?T);Txo6c{{6J2PR*B!CMU8Y* zo=tCnfN@P!+MzmXBw$xy+!NviJVaAv7%}r>YTX5p`TP8OVS`T3m}C`*V>LL+qf6Cv zPXox{jru{bRi#s8+kG4Wq#+520|MKo2*sxUU#fZElwMkLMQemBy{_(HKZg;u0JE%o zb>w^Nzrytvnkc$wr%drfw^Dk!)reWmS+btotduRH*a@Bn~HMHJTtIpDy{-<;8 z>|YNT#bh-$>Qq+$4E6U4^r!B($GpM%*7TS$2pgU7<8jD+Z$UZke0iMX!V|{K7hne> z?d$zLT-?ib6XdnqdHS9lsFHNz3L~&~9VUUSw*r0$*qCJ;v*&blZObzGXg`JLX1Y^* z{QdqYu!dpvX^7^^fZ!@uK3C$DnvbMK>g{&czOwRKko zaKm8?9{AE!npurrp5PLEM<9|etQjy}Y2{CJorzZAs~1@QhnLkh7-floeRWAC)DR3) zMWz#~cv{}umP=FaTQPUoP#d%nfEqN_PQ6DY%MaToj<87_;pRsC4iCcUqZp7Y0&y6d zg+pxivCPWw%O4B+SHlmt@Y&_7jo~=5lu)QP^6z=ri82VSn!l=d{Zmmu)Bc>3n$@G` z#LSSwyO1CdJ_2|Wa}Y=NbH|Y*Iw5Y9`m>X+3eX7{+d+;nBEMk=ME-`I%UkOa7BlBwD%S{6Q+jXV!<O zt>Bg>=n_kT^b-o#vmW&oUx5Ve`k|imhHS&s;Fi4)pynqhxgW#l?-kW4E<@d=wyB>F z%kK=7tObq}An3Ty9mAWGTcn-c+>;Ek(T$@{+^%K1&xPz9^lpSUi&D1Bz#VII+@%@d zCN(M>l!tmj%RD@99lFj}AsoM>Q3zxagS+=YwvLF0a_j<){8yxjZW?JDG!*Yf5gW~d oJ`qyep}YF7U5XXKKTx}_ag?LTIU~AC1qWgFHjdWMk9$Y{1sF;NRR910 literal 0 HcmV?d00001 diff --git a/readme.md b/readme.md deleted file mode 100644 index c64fe2b..0000000 --- a/readme.md +++ /dev/null @@ -1,44 +0,0 @@ -Twitch Echo Bot with Python -======== -[![License: GPL v3](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE) [![Python 3](https://img.shields.io/badge/python-3-blue.svg)](https://www.python.org/) - -Fast and easy way to use. - -## Features - -- Join the twitch channel. -- Send message. -- Get new message. - -## Usage - -```bash -git clone https://github.com/NatLee/Twitch-Echo-Bot-with-Python.git -``` - -## Example (in main.py) - -```python - -from twitchSocket import twitchSocket - -ts = twitchSocket(channelName='', - botName ='', - botAuth ='

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 )l?yZ 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 Z|Lm;KUB10ml@bT3^mO%eS?83{1OQRX4kG{n literal 0 HcmV?d00001 diff --git a/docs/images/message-anatomy-light.png b/docs/images/message-anatomy-light.png new file mode 100644 index 0000000000000000000000000000000000000000..2995731a21ddb41f0bec74fc7621ef067fb1d71b GIT binary patch literal 67679 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 literal 0 HcmV?d00001 diff --git a/docs/images/src/hero.html b/docs/images/src/hero.html new file mode 100644 index 0000000..25aa699 --- /dev/null +++ b/docs/images/src/hero.html @@ -0,0 +1,157 @@ + + + + + +twitch-echo-bot-with-python cover + + + + + + +