Add pubnub-watching zulip bot

Which also records all pubnub messages for archival to a file SEGMENTS/pubnub-log.json.
We ran this for most of last year, but not as part of wubloader.
pull/414/head
Mike Lang 2 months ago committed by Mike Lang
parent c378a1e4ab
commit 9b19c12a53

@ -31,6 +31,7 @@
schedulebot: false, schedulebot: false,
tootbot: false, tootbot: false,
twitchbot: false, twitchbot: false,
pubbot: false,
bus_analyzer: false, bus_analyzer: false,
graphs: false, graphs: false,
}, },
@ -297,6 +298,11 @@
args:: [], args:: [],
}, },
pubbot:: {
zulip_email: "blog-bot@chat.videostrike.team",
zulip_api_key: "",
},
// template for donation data urls // template for donation data urls
donation_url_template:: "https://example.com/DB{}/DB{}.json", donation_url_template:: "https://example.com/DB{}/DB{}.json",
@ -659,7 +665,7 @@
environment: $.env, environment: $.env,
}, },
local bot_service(name, config, args, subcommand=null) = { local bot_service(name, config, args=[], subcommand=null) = {
image: $.get_image("zulip_bots"), image: $.get_image("zulip_bots"),
restart: "always", restart: "always",
entrypoint: ["python3", "-m", "zulip_bots.%s" % name] entrypoint: ["python3", "-m", "zulip_bots.%s" % name]
@ -686,7 +692,14 @@
[if $.enabled.twitchbot then "twitchbot"]: [if $.enabled.twitchbot then "twitchbot"]:
bot_service("twitchbot", $.twitchbot + { bot_service("twitchbot", $.twitchbot + {
zulip_url: $.zulip_url, zulip_url: $.zulip_url,
}, $.tootbot.args), }),
[if $.enabled.pubbot then "pubbot"]:
bot_service("pubbot", $.pubbot + {
zulip_url: $.zulip_url,
}, ["/mnt/pubnub-log.json"]) + {
volumes: ["%s:/mnt" % $.segments_path],
},
}, },

@ -0,0 +1,107 @@
import json
import logging
import time
from .config import get_config
from .zulip import Client
import requests
session = requests.Session()
def stream():
tt = 0
tr = 0
while True:
resp = session.get("https://ps8.pndsn.com/v2/subscribe/sub-cbd7f5f5-1d3f-11e2-ac11-877a976e347c/db_total%2Cdb_vue/0",
params={
"tt": tt,
"tr": tr,
},
)
resp.raise_for_status()
data = resp.json()
for msg in data.get("m", []):
yield msg
tt = data["t"]["t"]
tr = data["t"]["r"]
def get_prize(prize_id):
resp = session.get("https://desertbus.org/wapi/prize/{}".format(prize_id))
resp.raise_for_status()
return resp.json()["prize"]
giveaway_cache = [None, None]
def get_giveaway():
REFRESH_RISING = 30
REFRESH_FALLING = 300
t, g = giveaway_cache
now = time.time()
timeout = REFRESH_RISING if g is None else REFRESH_FALLING
if t is None or now - t > timeout:
resp = session.get("https://desertbus.org/wapi/currentGiveaway")
resp.raise_for_status()
g = resp.json()["giveaway"]
giveaway_cache[0] = t
giveaway_cache[1] = g
return g
def main(conf_file, message_log_file):
"""Config:
zulip_url
zulip_email
zulip_api_key
"""
logging.basicConfig(level="INFO")
config = get_config(conf_file)
client = Client(config["zulip_url"], config["zulip_email"], config["zulip_api_key"])
message_log = open(message_log_file, "a")
prizes = {}
total = None
for msg in stream():
message_log.write(json.dumps(msg) + '\n')
if msg["c"] == "db_total":
increase = None if total is None else msg["d"] - total
increase_str = "" if increase is None else " (+${:.2f})".format(msg["d"] - total)
giveaway = get_giveaway()
entries_str = ""
if increase is not None and giveaway is not None:
amount = giveaway["amount"]
if (increase + 0.005) % amount < 0.01:
entries = int((increase + 0.005) / amount)
entries_str = " ({} entries of ${:.2f})".format(entries, amount)
logging.info("New donation total: {}{}{}".format(msg["d"], increase_str, entries_str))
client.send_to_stream("bot-spam", "Donation Firehose", "Donation total is now ${:.2f}{}{}".format(msg["d"], increase_str, entries_str))
if increase is not None and increase >= 500:
client.send_to_stream("bot-spam", "Notable Donations", "Large donation of ${:.2f} (total ${:.2f}){}".format(increase, msg['d'], entries_str))
total = msg["d"]
elif msg["c"] == "db_vue" and msg["d"].get("channel").startswith("prize:"):
d = msg["d"]
prize_id = msg["d"]["channel"].split(":")[1]
data = d["data"]
logging.info(f"Prize update for {prize_id}: {data}")
if prize_id not in prizes:
prizes[prize_id] = get_prize(prize_id)
if "bidder" in data and "bid" in data:
client.send_to_stream("bot-spam", "Bids", "At <time:{time}>, {bidder} bid ${bid:.2f} for [{title}](https://desertbus.org/prize/{prize_id})".format(
time = float(msg["p"]["t"]) / 10000000,
bidder = data["bidder"],
bid = data["bid"],
title = prizes[prize_id]["title"],
prize_id = prize_id,
))
else:
logging.warning("Unknown message: {}".format(msg))
if __name__ == '__main__':
import argh
argh.dispatch_command(main)
Loading…
Cancel
Save