Files
checkbot/app/chat/base.py
T
patrickandClaude Sonnet 5.5 347f55cf7c
test / pytest (3.11) (push) Waiting to run
test / pytest (3.13) (push) Waiting to run
feat: Phase 6c baseline, ack, host alarms, outage notice, send limit, privacy mode, UI link
Includes atomic migrations, per-rule reminder semantics, first-run helper script
and the note on the undecided UI chat idea.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-06 03:06:23 +01:00

63 lines
1.2 KiB
Python

from dataclasses import dataclass
from typing import NamedTuple, Protocol
from urllib.parse import quote
import httpx
MASK = "***"
class ChatError(Exception):
pass
def mask_secret(text: str, secret: str) -> str:
if not secret:
return text
for variant in (secret, quote(secret, safe=""), quote(secret)):
text = text.replace(variant, MASK)
return text
def json_body(response: httpx.Response) -> dict:
try:
body = response.json()
except ValueError:
return {}
return body if isinstance(body, dict) else {}
@dataclass(frozen=True)
class Button:
label: str
data: str = ""
url: str = ""
Buttons = tuple[tuple[Button, ...], ...]
class Target(NamedTuple):
backend: str
target: str
@dataclass(frozen=True)
class MessageRef:
backend: str
target: str
message_id: str
class ChatAdapter(Protocol):
name: str
default_target: str
async def send(self, target: str, text: str, buttons: Buttons = (), silent: bool = False) -> MessageRef: ...
async def edit(self, ref: MessageRef, text: str, buttons: Buttons = (), silent: bool = False) -> None: ...
async def check(self) -> str: ...
async def aclose(self) -> None: ...