Compare commits

...

5 Commits

4 changed files with 120 additions and 8 deletions
+20 -2
View File
@@ -62,6 +62,7 @@ class RewardCampaign:
twitch_user_id: Optional[str] = None,
twitch_user_name: Optional[str] = None,
earned_at: Optional[datetime] = None,
**kwargs,
) -> EarnedReward:
row = await EarnedReward.create(
campaign_id=self.row.campaign_id,
@@ -71,6 +72,7 @@ class RewardCampaign:
twitch_user_id=twitch_user_id,
twitch_user_name=twitch_user_name,
earned_at=earned_at or utc_now(),
**kwargs,
)
await self.try_to_log_reward(row)
@@ -85,12 +87,28 @@ class RewardCampaign:
await reward.update(**kwargs)
await self.try_to_log_reward(reward)
async def delete_reward(self, rewardid: int):
reward = await EarnedReward.fetch(rewardid)
if reward is None:
raise ValueError("Reward doesn't exist")
await self.try_to_unlog_reward(reward)
await reward.delete()
async def get_rewards(self) -> list[EarnedReward]:
rows = await EarnedReward.fetch_where(
campaign_id=self.row.campaign_id
).order_by("earned_at", direction=ORDER.ASC)
return rows
async def try_to_unlog_reward(self, reward: EarnedReward):
import discord
try:
if self.webhook and reward.log_messageid:
await self.webhook.delete_message(reward.log_messageid)
except discord.HTTPException:
pass
async def try_to_log_reward(self, reward: EarnedReward):
import discord
@@ -203,8 +221,8 @@ class CampaignRegistry:
condition = Campaign.communityid == cid
if active is not None:
active_condition = (
(Campaign.started_at != NULL) & (Campaign.completed_at == NULL)
active_condition = (Campaign.started_at != NULL) & (
Campaign.completed_at == NULL
)
if active:
condition = condition & active_condition
+52 -1
View File
@@ -7,6 +7,7 @@ from discord.ext import commands as cmds
from discord import Forbidden, User, app_commands as appcmds
from meta import LionBot, LionCog, LionContext
from meta import logger
from meta.errors import SafeCancellation, UserInputError
from meta.logger import log_wrap
from utils.lib import utc_now
@@ -79,6 +80,7 @@ class CampaignCog(LionCog):
sorted_campaigns = sorted(
campaigns,
key=lambda camp: (camp.is_active, camp.row.started_at, camp.row.created_at),
reverse=True,
)
names = [
camp.row.campaign_name
@@ -258,7 +260,7 @@ class CampaignCog(LionCog):
update_args["campaign_name"] = new_name
if new_cap is not None:
update_args["total_rewards"] = new_cap if new_cap > 0 else None
update_args["target_rewards"] = new_cap if new_cap > 0 else None
# If logging webhook is given, check that it works
if logging_webhook is not None:
@@ -317,6 +319,53 @@ class CampaignCog(LionCog):
campaign_rewards_cmd.autocomplete("campaign_name")(_campaign_acmpl)
@campaign_group.command(
name="delreward",
description="Remove a campaign reward",
)
@appcmds.describe(
rewardid="Earned reward to delete",
)
@appcmds.rename(rewardid="reward")
async def campaign_delreward_cmd(
self,
ctx: LionContext,
rewardid: str,
):
# For this we'll just open the reward editor
# Will need to identify the reward with autocomplete. Can use the reward id directly..
if not rewardid.isdigit():
raise UserInputError(
"Please enter the reward number or select a reward from the argument menu"
)
reward = await EarnedReward.fetch(int(rewardid))
if not reward:
raise UserInputError(
"Reward not found. Please enter the reward number or select a reward from the argument menu"
)
# Fetch campaign and then do a perm check
campaign = await self.campaigns.fetch_campaign(reward.campaign_id)
if campaign is None:
raise SafeCancellation("Something went wrong.. please try again soon.")
if campaign.row.communityid != ctx.community.communityid:
raise UserInputError("This reward doesn't belong to this community!")
if not await self.campaign_modcheck(campaign, ctx.author):
await ctx.interaction.response.send_message(
"You need to be an administrator or have the configured modrole to use that!",
ephemeral=True,
)
return
# Okay, they have permission, let's delete the reward.
await campaign.delete_reward(reward.earned_id)
# Ack
await ctx.reply(content="Campaign reward deleted!", ephemeral=True)
@campaign_group.command(
name="editreward",
description="Add or edit details for a given reward in a campaign (see also /campaign rewards)",
@@ -432,6 +481,7 @@ class CampaignCog(LionCog):
cname=campaign.row.campaign_name,
)
@campaign_delreward_cmd.autocomplete("rewardid")
@campaign_editreward_cmd.autocomplete("rewardid")
async def _reward_acmpl(
self, interaction: discord.Interaction, partial: str
@@ -457,6 +507,7 @@ class CampaignCog(LionCog):
sorted_campaigns = sorted(
campaigns,
key=lambda camp: (camp.is_active, camp.row.started_at, camp.row.created_at),
reverse=True,
)
for campaign in sorted_campaigns:
rewards = await campaign.get_rewards()
+10
View File
@@ -63,6 +63,16 @@ class ThreadedWebhook(discord.Webhook):
kwargs.setdefault("thread", discord.Object(self.thread_id))
return await super().edit_message(*args, **kwargs)
async def delete_message(self, *args, **kwargs):
if self.thread_id is not None:
kwargs.setdefault("thread", discord.Object(self.thread_id))
return await super().delete_message(*args, **kwargs)
async def fetch_message(self, *args, **kwargs):
if self.thread_id is not None:
kwargs.setdefault("thread", discord.Object(self.thread_id))
return await super().fetch_message(*args, **kwargs)
async def test_webhook(self):
embed = discord.Embed(
title="Testing", description="Testing logging webhook, feel free to delete."
+38 -5
View File
@@ -80,8 +80,41 @@ class CampaignComponent(cmds.Component):
twitch_user_name=data["chatter_user_name"],
)
await self.dispatch_update(campaign)
# TODO: Webhook logging maybe.. (do this in campaign)
# Or just general logging. (also do this in campaign, but we can do again here)
# @cmds.Component.listener()
async def event_custom_redemption_add(self, payload):
if payload.reward.title not in (
"hi!",
"hydrate",
"stretch",
"save file",
"pet lilac",
):
return
community = await self.bot.profiles.fetch_community(payload.broadcaster)
cid = community.communityid
profile = await self.bot.profiles.fetch_profile(payload.user)
pid = profile.profileid
campaigns = await self.campaigns.fetch_campaigns(cid)
for campaign in campaigns:
reward_progress = len(await campaign.get_rewards())
if (
campaign.row.target_rewards is None
or reward_progress < campaign.row.target_rewards
):
# Add a reward to the database with the correct info.
await campaign.add_reward(
profileid=pid,
earned_from=f"(REDEEM) User redeemed {payload.reward.title}",
event_id=None,
twitch_user_id=payload.user.id,
twitch_user_name=payload.user.name,
reference=f"Redeem text: {payload.user_input}",
)
await self.dispatch_update(campaign)
# @cmds.Component.listener()
async def event_message(self, payload):
@@ -131,7 +164,6 @@ class CampaignComponent(cmds.Component):
# ------ Commands -----
@cmds.group(name="campaign", invoke_fallback=True)
@cmds.is_moderator()
async def group_campaign(self, ctx: cmds.Context, name: Optional[str] = None):
"""Status of the current or named campaign."""
community = await self.bot.profiles.fetch_community(ctx.broadcaster)
@@ -174,6 +206,7 @@ class CampaignComponent(cmds.Component):
cap=reward_cap,
)
await ctx.reply(formatted)
await self.dispatch_update(campaign)
@group_campaign.command(name="setup", aliases=["start"])
@cmds.is_moderator()
@@ -261,9 +294,9 @@ class CampaignComponent(cmds.Component):
reward_cap = campaign.row.target_rewards
if reward_cap is not None:
response = f"Completed {name}: {rewards_earned} rewards earned out of {reward_cap}!"
response = "Completed {name}: {given} rewards earned out of {cap}!"
else:
response = f"Completed {name}: {rewards_earned} rewards earned so far!"
response = "Completed {name}: {given} rewards earned so far!"
formatted = response.format(
name=campaign.row.campaign_name,
given=rewards_earned,