From 06b08dbbcb4b234a94be189f855ce5fec4c5c37b Mon Sep 17 00:00:00 2001 From: Ben Sima Date: Mon, 18 May 2026 13:54:55 -0400 Subject: init: slopbot scaffold --- main.py | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 main.py (limited to 'main.py') diff --git a/main.py b/main.py new file mode 100644 index 0000000..8fe9d24 --- /dev/null +++ b/main.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python3 +""" +slopbot - Zulip bot that replies with stock prices when it sees $TICKER patterns. + +Usage: + python main.py + +Requires a .zuliprc file in the same directory (see .zuliprc.example). +""" + +import re +import zulip +import yfinance as yf + +# Regex to match stock tickers like $NVDA, $AAPL, $BRK +TICKER_RE = re.compile(r'\$([A-Z]{1,5})') + + +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"] + return f"${ticker}: ${price:,.2f}" + except Exception as e: + return f"${ticker}: couldn't fetch price ({e})" + + +def handle_event(event: dict, client: zulip.Client) -> None: + """Process a Zulip event and reply if tickers are found.""" + if event.get("type") != "message": + return + + msg = event["message"] + + # Don't reply to ourselves + if msg["sender_email"] == client.email: + return + + content = msg.get("content", "") + tickers = TICKER_RE.findall(content.upper()) + + if not tickers: + return + + lines = [fetch_price(t) for t in dict.fromkeys(tickers)] # dedup, preserve order + reply = "\n".join(lines) + + client.send_message({ + "type": msg["type"], # "stream" or "private" + "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() -- cgit v1.2.3