From 2726dba7b41a2750a09889951ebbeecfdfe0981f Mon Sep 17 00:00:00 2001 From: Ben Sima Date: Mon, 18 May 2026 14:07:02 -0400 Subject: feat: implement slopbot Zulip stock ticker bot - Adds main.py: single-file bot using raw zulip event loop - Matches $TICKER patterns via TICKER_RE = re.compile(r'$([A-Z]{1,5})') - fetch_price() uses yf.Ticker(ticker).fast_info['lastPrice'] - Returns '$TICKER: $123.45' on success - Returns '$TICKER: unavailable (msg)' on exception - handle_event() ignores non-message events, skips bot's own messages, deduplicates tickers, replies to same stream + topic - Module-level client + call_on_each_event per spec --- main.py | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) (limited to 'main.py') diff --git a/main.py b/main.py index 8fe9d24..ae862a3 100644 --- a/main.py +++ b/main.py @@ -15,18 +15,19 @@ import yfinance as yf # Regex to match stock tickers like $NVDA, $AAPL, $BRK TICKER_RE = re.compile(r'\$([A-Z]{1,5})') +client = zulip.Client(config_file='.zuliprc') + def fetch_price(ticker: str) -> str: """Return a formatted price string for a ticker, or an error message.""" try: - info = yf.Ticker(ticker).fast_info - price = info["lastPrice"] + price = yf.Ticker(ticker).fast_info['lastPrice'] return f"${ticker}: ${price:,.2f}" except Exception as e: - return f"${ticker}: couldn't fetch price ({e})" + return f"${ticker}: unavailable ({e})" -def handle_event(event: dict, client: zulip.Client) -> None: +def handle_event(event: dict) -> None: """Process a Zulip event and reply if tickers are found.""" if event.get("type") != "message": return @@ -47,21 +48,11 @@ def handle_event(event: dict, client: zulip.Client) -> None: reply = "\n".join(lines) client.send_message({ - "type": msg["type"], # "stream" or "private" + "type": msg["type"], "to": msg["stream_id"] if msg["type"] == "stream" else msg["sender_email"], "topic": msg.get("subject", ""), "content": reply, }) -def main(): - client = zulip.Client(config_file=".zuliprc") - print(f"slopbot running as {client.email} ...") - client.call_on_each_event( - lambda event: handle_event(event, client), - event_types=["message"], - ) - - -if __name__ == "__main__": - main() +client.call_on_each_event(handle_event, event_types=["message"]) -- cgit v1.2.3