generated from HoloTech/holotech-plugin-template
Add rudimentary websocket channel.
This commit is contained in:
+48
-20
@@ -16,17 +16,41 @@ from .data import (
|
|||||||
CampaignData,
|
CampaignData,
|
||||||
EarnedReward,
|
EarnedReward,
|
||||||
)
|
)
|
||||||
from .campaign import CampaignRegistry
|
from .campaign import CampaignRegistry, RewardCampaign
|
||||||
|
|
||||||
|
|
||||||
# ISO formatted timestamp
|
# ISO formatted timestamp
|
||||||
ISOTimestamp: TypeAlias = str
|
ISOTimestamp: TypeAlias = str
|
||||||
|
|
||||||
|
|
||||||
async def prepare_campaign(
|
class CampaignPayload(TypedDict):
|
||||||
profiler: ProfilesRegistry, campaign: Campaign
|
communityid: int
|
||||||
):
|
campaign_id: int
|
||||||
return {}
|
campaign_name: str
|
||||||
|
|
||||||
|
started_at: ISOTimestamp | None
|
||||||
|
completed_at: ISOTimestamp | None
|
||||||
|
|
||||||
|
reward_progress: int
|
||||||
|
reward_cap: int | None
|
||||||
|
|
||||||
|
|
||||||
|
async def prepare_campaign(campaign: RewardCampaign) -> CampaignPayload:
|
||||||
|
reward_progress = len(await campaign.get_rewards())
|
||||||
|
|
||||||
|
return CampaignPayload(
|
||||||
|
communityid=campaign.row.communityid,
|
||||||
|
campaign_id=campaign.row.campaign_id,
|
||||||
|
campaign_name=campaign.row.campaign_name,
|
||||||
|
started_at=campaign.row.started_at.isoformat()
|
||||||
|
if campaign.row.started_at
|
||||||
|
else None,
|
||||||
|
completed_at=campaign.row.completed_at.isoformat()
|
||||||
|
if campaign.row.completed_at
|
||||||
|
else None,
|
||||||
|
reward_progress=reward_progress,
|
||||||
|
reward_cap=campaign.row.target_rewards,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class CampaignChannel(Channel):
|
class CampaignChannel(Channel):
|
||||||
@@ -61,30 +85,36 @@ class CampaignChannel(Channel):
|
|||||||
await super().on_connection(websocket, event)
|
await super().on_connection(websocket, event)
|
||||||
self.communities[cid].add(websocket)
|
self.communities[cid].add(websocket)
|
||||||
|
|
||||||
# TODO: Prepare campaign for sending
|
# Fetch active campaign for this cid and send if it exists
|
||||||
if campaign:
|
active = await self.campaigns.fetch_campaigns(cid)
|
||||||
payload = await prepare_campaign(self.profiler, campaign)
|
if active:
|
||||||
|
# TODO: Presumes only one active campaign
|
||||||
|
campaign = active[0]
|
||||||
|
payload = await prepare_campaign(campaign)
|
||||||
await self.send_campaign_update(cid, payload, websocket)
|
await self.send_campaign_update(cid, payload, websocket)
|
||||||
else:
|
else:
|
||||||
await self.send_no_campaign(cid, websocket)
|
await self.send_no_campaign(cid, websocket)
|
||||||
|
|
||||||
async def send_sample(self, websocket):
|
async def send_sample(self, websocket):
|
||||||
import json
|
|
||||||
import random
|
import random
|
||||||
with open("sample-payload.json") as f:
|
|
||||||
payload = json.load(f)
|
payload = CampaignPayload(
|
||||||
ending = utc_now() + timedelta(seconds=10)
|
communityid=1,
|
||||||
payload['args']['end_at'] = ending.isoformat()
|
campaign_id=1,
|
||||||
await self.send_event(payload, websocket=websocket)
|
campaign_name="PartnerPlus2026",
|
||||||
|
started_at=utc_now().isoformat(),
|
||||||
|
completed_at=None,
|
||||||
|
reward_progress=random.randint(0, 105),
|
||||||
|
reward_cap=150,
|
||||||
|
)
|
||||||
|
await self.send_event(payload, websocket=websocket)
|
||||||
|
|
||||||
async def del_connection(self, websocket):
|
async def del_connection(self, websocket):
|
||||||
for wss in self.communities.values():
|
for wss in self.communities.values():
|
||||||
wss.discard(websocket)
|
wss.discard(websocket)
|
||||||
await super().del_connection(websocket)
|
await super().del_connection(websocket)
|
||||||
|
|
||||||
async def send_campaign_update(
|
async def send_campaign_update(self, communityid: int, payload, websocket=None):
|
||||||
self, communityid: int, payload, websocket=None
|
|
||||||
):
|
|
||||||
for ws in (websocket,) if websocket else self.communities[communityid]:
|
for ws in (websocket,) if websocket else self.communities[communityid]:
|
||||||
await self.send_event(
|
await self.send_event(
|
||||||
{
|
{
|
||||||
@@ -95,9 +125,7 @@ class CampaignChannel(Channel):
|
|||||||
websocket=ws,
|
websocket=ws,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def send_campaign_ended(
|
async def send_campaign_ended(self, communityid: int, payload, websocket=None):
|
||||||
self, communityid: int, payload, websocket=None
|
|
||||||
):
|
|
||||||
for ws in (websocket,) if websocket else self.communities[communityid]:
|
for ws in (websocket,) if websocket else self.communities[communityid]:
|
||||||
await self.send_event(
|
await self.send_event(
|
||||||
{
|
{
|
||||||
|
|||||||
+32
-12
@@ -11,7 +11,8 @@ from utils.lib import utc_now
|
|||||||
from . import logger
|
from . import logger
|
||||||
|
|
||||||
from ..data import CampaignData
|
from ..data import CampaignData
|
||||||
from ..campaign import CampaignRegistry
|
from ..campaign import CampaignRegistry, RewardCampaign
|
||||||
|
from ..channel import CampaignPayload, prepare_campaign, CampaignChannel
|
||||||
|
|
||||||
|
|
||||||
class CampaignComponent(cmds.Component):
|
class CampaignComponent(cmds.Component):
|
||||||
@@ -20,6 +21,9 @@ class CampaignComponent(cmds.Component):
|
|||||||
|
|
||||||
self.data = bot.dbconn.load_registry(CampaignData())
|
self.data = bot.dbconn.load_registry(CampaignData())
|
||||||
self.campaigns = CampaignRegistry(self.data)
|
self.campaigns = CampaignRegistry(self.data)
|
||||||
|
self.channel = CampaignChannel(self.bot.profiles.profiles, self.campaigns)
|
||||||
|
|
||||||
|
register_channel("Campaign", self.channel)
|
||||||
|
|
||||||
# ----- API -----
|
# ----- API -----
|
||||||
async def component_load(self):
|
async def component_load(self):
|
||||||
@@ -30,6 +34,11 @@ class CampaignComponent(cmds.Component):
|
|||||||
async def component_teardown(self):
|
async def component_teardown(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
async def dispatch_update(self, campaign: RewardCampaign):
|
||||||
|
cid = campaign.row.communityid
|
||||||
|
payload = await prepare_campaign(campaign)
|
||||||
|
await self.channel.send_campaign_update(cid, payload)
|
||||||
|
|
||||||
# ------ Event Handlers -----
|
# ------ Event Handlers -----
|
||||||
@cmds.Component.listener()
|
@cmds.Component.listener()
|
||||||
async def event_safe_event_chat_notice_sub(self, payload):
|
async def event_safe_event_chat_notice_sub(self, payload):
|
||||||
@@ -55,16 +64,23 @@ class CampaignComponent(cmds.Component):
|
|||||||
campaigns = await self.campaigns.fetch_campaigns(event_row["communityid"])
|
campaigns = await self.campaigns.fetch_campaigns(event_row["communityid"])
|
||||||
|
|
||||||
for campaign in campaigns:
|
for campaign in campaigns:
|
||||||
# Add a reward to the database with the correct info.
|
reward_progress = len(await campaign.get_rewards())
|
||||||
await campaign.add_reward(
|
|
||||||
profileid=event_row["profileid"],
|
if (
|
||||||
earned_reason=f"(SUB NOTICE): User subscribed for {duration} months at tier {tier}",
|
campaign.row.target_rewards is None
|
||||||
event_id=event_row["event_id"],
|
or reward_progress < campaign.row.target_rewards
|
||||||
twitch_user_id=data["chatter_user_id"],
|
):
|
||||||
twitch_user_name=data["chatter_user_name"],
|
# Add a reward to the database with the correct info.
|
||||||
)
|
await campaign.add_reward(
|
||||||
# TODO: Webhook logging maybe..
|
profileid=event_row["profileid"],
|
||||||
# Or just general logging.
|
earned_reason=f"(SUB NOTICE): User subscribed for {duration} months at tier {tier}",
|
||||||
|
event_id=event_row["event_id"],
|
||||||
|
twitch_user_id=data["chatter_user_id"],
|
||||||
|
twitch_user_name=data["chatter_user_name"],
|
||||||
|
)
|
||||||
|
await self.dispatch_update(campaign)
|
||||||
|
# TODO: Webhook logging maybe..
|
||||||
|
# Or just general logging.
|
||||||
|
|
||||||
@cmds.Component.listener()
|
@cmds.Component.listener()
|
||||||
async def event_safe_event_chat_notice_resub(self, payload):
|
async def event_safe_event_chat_notice_resub(self, payload):
|
||||||
@@ -178,6 +194,7 @@ class CampaignComponent(cmds.Component):
|
|||||||
f"Success! Your campaign '{name}' has been created and started. "
|
f"Success! Your campaign '{name}' has been created and started. "
|
||||||
"Best of luck!"
|
"Best of luck!"
|
||||||
)
|
)
|
||||||
|
await self.dispatch_update(campaign)
|
||||||
|
|
||||||
@group_campaign.command(name="finish", aliases=["stop", "complete", "end"])
|
@group_campaign.command(name="finish", aliases=["stop", "complete", "end"])
|
||||||
@cmds.is_moderator()
|
@cmds.is_moderator()
|
||||||
@@ -221,7 +238,9 @@ class CampaignComponent(cmds.Component):
|
|||||||
given=rewards_earned,
|
given=rewards_earned,
|
||||||
cap=reward_cap,
|
cap=reward_cap,
|
||||||
)
|
)
|
||||||
await ctx.reply(formatted)
|
await ctx.reply(formatte
|
||||||
|
await self.dispatch_update(campaign)
|
||||||
|
)
|
||||||
|
|
||||||
@group_campaign.command(name="reward")
|
@group_campaign.command(name="reward")
|
||||||
@cmds.is_moderator()
|
@cmds.is_moderator()
|
||||||
@@ -258,3 +277,4 @@ class CampaignComponent(cmds.Component):
|
|||||||
await ctx.reply(
|
await ctx.reply(
|
||||||
f"Successfully added campaign reward to {user.mention}'s account."
|
f"Successfully added campaign reward to {user.mention}'s account."
|
||||||
)
|
)
|
||||||
|
await self.dispatch_update(campaign)
|
||||||
|
|||||||
Reference in New Issue
Block a user