Skip to content

Commit

Permalink
app: Build follower giveaway system.
Browse files Browse the repository at this point in the history
  • Loading branch information
adambirds committed Jun 7, 2024
1 parent d217c87 commit 48e2935
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 2 deletions.
38 changes: 37 additions & 1 deletion app/modules/cogs/bom_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from twitchio.ext import commands
from discord.ext import commands as discord_commands

from app.models import Checkin, Clan, Player, Points, Season, Session, Channel, RaidSession, RaidCheckin, GiftedSubsLeaderboard
from app.models import Checkin, Clan, Player, Points, Season, Session, Channel, RaidSession, RaidCheckin, GiftedSubsLeaderboard, FollowerGiveaway, FollowerGiveawayEntry

if TYPE_CHECKING:
from bot import TwitchBot, DiscordBot
Expand Down Expand Up @@ -403,6 +403,42 @@ async def raid(self, ctx: commands.Context) -> None:
await ctx.send("No active seasons!")
else:
pass


@commands.command()
async def search(self, ctx: commands.Context, playername: str) -> None:
"""
?search command
"""

## This command should enter the follower giveaway for the user. Only one entry per user is allowed. If no playername is provided we will send an error message.

if playername == "":
await ctx.send(f"Type ?search @username in the chat to search new followers!")
else:
playername = playername.strip("@")

if await Channel.get_or_none(name=ctx.channel.name):
channel = await Channel.get(name=ctx.channel.name)
if await FollowerGiveaway.get_or_none(channel=channel, follower=playername):
follower_giveaway = await FollowerGiveaway.get(channel=channel, follower=playername)
# We need to check if the giveaway is still active by checking the end time.
if follower_giveaway.end_time > datetime.now(timezone.utc):
if await Player.get_or_none(name=ctx.author.name.lower(), channel=channel):
player = await Player.get(name=ctx.author.name.lower(), channel=channel)
if await FollowerGiveawayEntry.get_or_none(giveaway=follower_giveaway, player=player, channel=channel):
await ctx.send(f"You have already entered the giveaway.")
else:
await FollowerGiveawayEntry.create(giveaway=follower_giveaway, player=player, channel=channel)
await ctx.send(f"You have entered the giveaway.")
else:
pass
else:
await ctx.send(f"The giveaway has ended.")
else:
pass
else:
pass


def prepare(twitch_bot: commands.Bot, discord_bot: discord_commands.Bot) -> None:
Expand Down
71 changes: 71 additions & 0 deletions app/modules/cogs/bom_routines.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import logging
from twitchio.ext import commands, routines
from discord.ext import commands as discord_commands
import datetime
import random
from app.models import Channel, FollowerGiveaway, FollowerGiveawayEntry, Player, Points, Season, FollowerGiveawayPrize

logger = logging.getLogger(__name__)

class BomRoutinesCog(commands.Cog):
def __init__(self, twitch_bot: commands.Bot, discord_bot: discord_commands.Bot) -> None:
self.twitch_bot = twitch_bot
self.discord_bot = discord_bot

@routines.routine(seconds=5, wait_first=True)
async def check_follower_giveaway_winners(self) -> None:
logger.info("Checking for follower giveaway winners.")

channels = await Channel.all()

for channel in channels:
channel_object = await Channel.get(name=channel.name)
if await Season.active_seasons.all().filter(channel=channel_object).exists():
season = await Season.active_seasons.get(channel=channel_object)
giveaways = await FollowerGiveaway.filter(channel=channel_object, winner=None)
for giveaway in giveaways:
if giveaway.end_time <= datetime.datetime.now(tz=giveaway.end_time.tzinfo):
entries = await FollowerGiveawayEntry.filter(giveaway=giveaway)
if entries:
winner_entry = random.choice(entries)
winner = await winner_entry.player
giveaway.winner = winner
await giveaway.save()
prize = random.choice(await FollowerGiveawayPrize.filter(channel=channel_object))
if await Points.filter(player=winner, channel=channel_object, season=season).exists():
points = await Points.get(player=winner, channel=channel_object, season=season)
points.points += prize.vp_reward
await points.save()
else:
await Points.create(player=winner, channel=channel_object, season=season, points=prize.vp_reward, clan=winner.clan)
message = f"@{winner.name} has searched @{giveaway.follower} and found: {prize.message} Thank you @{giveaway.follower}, you may now enter VANDERHEIM!"
logger.info(f"Sending message to channel {channel_object.name}: {message}")
await self.send_twitch_message(channel_object.name, message)
else:
await FollowerGiveaway.filter(id=giveaway.id).delete()
message = f"The Follower Giveaway for {giveaway.follower} has ended. No one entered the giveaway."
logger.info(f"Sending message to channel {channel_object.name}: {message}")
await self.send_twitch_message(channel_object.name, message)
else:
pass
else:
pass
else:
pass

@check_follower_giveaway_winners.before_routine
async def before_check_follower_giveaway_winners(self) -> None:
self.twitch_bot.wait_for_ready()

async def send_twitch_message(self, channel_name: str, message: str) -> None:
channel = self.twitch_bot.get_channel(channel_name)
if channel:
logger.info(f"Channel {channel_name} found, sending message: {message}")
await channel.send(message)
else:
logger.warning(f"Channel {channel_name} not found, unable to send message")

def prepare(twitch_bot: commands.Bot, discord_bot: discord_commands.Bot) -> None:
cog = BomRoutinesCog(twitch_bot, discord_bot)
twitch_bot.add_cog(cog)
twitch_bot.check_follower_giveaways = cog.check_follower_giveaway_winners
19 changes: 18 additions & 1 deletion bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@
from twitchio.ext import commands, eventsub
from tortoise.functions import Count
from twitchio.models import PartialUser
import datetime

from app import settings
from app.models import EventSubscriptions, Player, Points, Season, Subscriptions, Clan, Channel, GiftedSubsLeaderboard
from app.models import EventSubscriptions, Player, Points, Season, Subscriptions, Clan, Channel, GiftedSubsLeaderboard, FollowerGiveaway


# Define function to process yaml config file
Expand Down Expand Up @@ -94,6 +95,9 @@ async def tinit(self) -> None:
)

await Tortoise.generate_schemas(safe=True)

async def routines_init(self) -> None:
self.check_follower_giveaways.start()

async def stop(self) -> None:
await self.session.close()
Expand Down Expand Up @@ -709,6 +713,17 @@ async def event_eventsub_notification_followV2(

twitch_logger.info("Received a new follow event.")

## Launch a giveaway for the new follower, the end time should be 30 seconds from now.
if await Channel.get_or_none(name=payload.data.broadcaster.name.lower()):
twitch_logger.info(f"Channel {payload.data.broadcaster.name} exists.")
channel = await Channel.get(name=payload.data.broadcaster.name.lower())
# We need to check if a giveaway exists for the new follower (they may have unfollowed and refollowed), so we need to delete the old giveaway and create a new one.
if await FollowerGiveaway.get_or_none(channel=channel, follower=player.name.lower()):
await FollowerGiveaway.get(channel=channel, follower=player.name.lower()).delete()
await FollowerGiveaway.create(channel=channel, end_time=datetime.datetime.now() + datetime.timedelta(seconds=30), follower=player.name.lower())
else:
pass

await twitch_bot.get_channel(payload.data.broadcaster.name).send(
f"🌲🌲🌲Who goes there!!? 👀 A weary traveller has emerged from the WOODLANDS. I need someone to ?search @{player.name} now before they enter VANDERHEIM!🌲🌲🌲"
)
Expand Down Expand Up @@ -892,6 +907,8 @@ async def get_eventsub_subscriptions() -> None:
twitch_bot.loop.create_task(discord_bot.start(conf_options["APP"]["DISCORD_TOKEN"]))
twitch_bot.loop.create_task(twitch_bot.tinit())
twitch_bot.loop.create_task(twitch_bot.connect())
twitch_bot.loop.create_task(twitch_bot.routines_init())

for channel in conf_options["APP"]["ACCOUNTS"]:
twitch_eventsubbot.loop.create_task(
subscribe_channel_subscriptions(channel_id=channel["id"], channel_name=channel["name"])
Expand Down

0 comments on commit 48e2935

Please sign in to comment.