from __future__ import annotations from dataclasses import dataclass, field from enum import StrEnum from typing import Any class ReactionNotifyMode(StrEnum): OFF = "off" ALL = "all" ALLOWLIST = "allowlist" @dataclass class ReactionNotifyConfig: mode: ReactionNotifyMode = ReactionNotifyMode.OFF allowlist: set[str] = field(default_factory=set) @classmethod def from_config(cls, config: dict[str, Any] | None) -> ReactionNotifyConfig: if not config: return cls() mode_raw = str(config.get("reaction_notifications", "off")).strip().lower() mode_map = { "off": ReactionNotifyMode.OFF, "all": ReactionNotifyMode.ALL, "allowlist": ReactionNotifyMode.ALLOWLIST, } mode = mode_map.get(mode_raw, ReactionNotifyMode.OFF) allowlist_raw = config.get("reaction_allowlist", []) if isinstance(allowlist_raw, str): allowlist_raw = [x.strip() for x in allowlist_raw.split(",") if x.strip()] elif not isinstance(allowlist_raw, (list, tuple)): allowlist_raw = [] allowlist = {str(e) for e in allowlist_raw if e} return cls(mode=mode, allowlist=allowlist) def should_notify(self, emoji: str) -> bool: if self.mode == ReactionNotifyMode.OFF: return False if self.mode == ReactionNotifyMode.ALL: return True if self.mode == ReactionNotifyMode.ALLOWLIST: if "*" in self.allowlist: return True return emoji in self.allowlist return False