diff --git a/plugin/campaign.py b/plugin/campaign.py index 8da95e8..e65712e 100644 --- a/plugin/campaign.py +++ b/plugin/campaign.py @@ -85,12 +85,27 @@ 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 diff --git a/plugin/discord/cog.py b/plugin/discord/cog.py index bf36d6d..a351b46 100644 --- a/plugin/discord/cog.py +++ b/plugin/discord/cog.py @@ -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 @@ -317,6 +318,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 +480,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 diff --git a/plugin/lib.py b/plugin/lib.py index e326d1c..6562a4f 100644 --- a/plugin/lib.py +++ b/plugin/lib.py @@ -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." diff --git a/plugin/twitch/component.py b/plugin/twitch/component.py index eb3d6aa..69f09eb 100644 --- a/plugin/twitch/component.py +++ b/plugin/twitch/component.py @@ -131,7 +131,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 +173,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()