Exemple #1
0
        public async Task Reset(int newGameweek)
        {
            _currentGameweek         = newGameweek;
            _currentGameweekFixtures = await _fixtureClient.GetFixturesByGameweek(newGameweek);

            var settings = await _settingsClient.GetGlobalSettings();

            _players = settings.Players;
            _teams   = settings.Teams;
        }
        public async Task Handle(UpdateAllEntryStats notification, CancellationToken cancellationToken)
        {
            var allEntries = await _verifiedEntriesRepository.GetAllVerifiedEntries();

            var settings = await _settingsClient.GetGlobalSettings();

            var players = settings.Players;

            foreach (var entry in allEntries)
            {
                var newStats = await GetUpdatedStatsForEntry(entry.EntryId, players);

                await _verifiedEntriesRepository.UpdateAllStats(entry.EntryId, newStats);
            }
        }
Exemple #3
0
    // To test fixture event:
    private async Task PublishPrevGwFixtureEvents(int gwId)
    {
        var settings = await _settingsClient.GetGlobalSettings();

        var updated = await _fixtureClient.GetFixturesByGameweek(gwId);

        var previous = await _fixtureClient.GetFixturesByGameweek(gwId);

        foreach (var fixture in previous)
        {
            fixture.Stats = Array.Empty <FixtureStat>();
            // if (fixture.Id == 24)
            // {
            //     //int before = fixture.Stats.First(s => s.Identifier == "goals_scored").HomeStats.First().Value;
            //     //int after = before - 2;
            //     //_logger.LogInformation($"Before: {before}. After {after}");
            //     //fixture.Stats.First(s => s.Identifier == "goals_scored").HomeStats.First().Value = after;
            //     var newl = fixture.Stats.First(s => s.Identifier == "goals_scored").HomeStats
            //         .Where(c => c.Value != 2).ToList().AsEnumerable();
            //     fixture.Stats.First(s => s.Identifier == "goals_scored").HomeStats = newl.ToList();
            // }
        }
        //
        // var allFixtureEvents = LiveEventsExtractor.GetUpdatedFixtureEvents(updated,previous, settings.Players, settings.Teams);
        // await _session.Publish(new FixtureEventsOccured(allFixtureEvents.ToArray()[0..1].ToList()));
    }
    public async Task Handle(PublishAggregatedPLEntrySuggestions message, IMessageHandlerContext context)
    {
        string text;

        try
        {
            var entry = await _entryClient.Get(message.EntryId);

            var settings = await _settings.GetGlobalSettings();

            var player = settings.Players.Get(message.PlayerId);
            if (player != null)
            {
                var team = settings.Teams.Get(player.TeamId);
                text = $"{Link(entry)} for {player.FullName} ({team.ShortName}){Counting(message.SuggestionCount)}";
            }
            else
            {
                text = $"{Link(entry)} for unknown PL player {message.PlayerId}{Counting(message.SuggestionCount)}!";
            }
        }
        catch (Exception)
        {
            text = $"{message.EntryId} suggested{Counting(message.SuggestionCount)}, but it does not exist. ­ЪциРђЇРЎѓ№ИЈ";
        }

        await context.SendLocal(new PublishToSlack(ThrottleSuggestionConstants.TeamId, ThrottleSuggestionConstants.SlackChannel, "Verified suggestion: " + text));
    }
        public override async Task <EventHandledResponse> Handle(EventMetaData eventMetadata, AppMentionEvent message)
        {
            var globalSettings = await _globalSettingsClient.GetGlobalSettings();

            var players = globalSettings.Players;
            var teams   = globalSettings.Teams;

            var name = ParseArguments(message);

            var allPlayers = players.OrderByDescending(player => player.OwnershipPercentage);
            var mostPopularMatchingPlayer = FindMostPopularMatchingPlayer(allPlayers.ToArray(), name);

            if (mostPopularMatchingPlayer == null)
            {
                await _workSpacePublisher.PublishToWorkspace(eventMetadata.Team_Id, message.Channel, $"Couldn't find {name}");

                return(new EventHandledResponse($"Found no matching player for {name}: "));
            }

            var playerName = $"{mostPopularMatchingPlayer.FirstName} {mostPopularMatchingPlayer.SecondName}";

            await _workSpacePublisher.PublishToWorkspace(eventMetadata.Team_Id, new ChatPostMessageRequest
            {
                Channel = message.Channel,
                Blocks  = Formatter.GetPlayerCard(mostPopularMatchingPlayer, teams)
            });

            return(new EventHandledResponse($"Found matching player for {name}: " + playerName));
        }
Exemple #6
0
    public async Task Handle(PublishGameweekFinishedToGuild message, IMessageHandlerContext context)
    {
        var sub = await _repo.GetGuildSubscription(message.GuildId, message.ChannelId);

        if (sub != null && message.LeagueId.HasValue && sub.Subscriptions.ContainsSubscriptionFor(EventSubscription.Standings))
        {
            var settings = await _settingsClient.GetGlobalSettings();

            var           gameweeks = settings.Gameweeks;
            var           gw        = gameweeks.SingleOrDefault(g => g.Id == message.GameweekId);
            ClassicLeague league    = await _leagueClient.GetClassicLeague(message.LeagueId.Value, tolerate404 : true);

            if (league != null)
            {
                var messages  = new List <RichMesssage>();
                var intro     = Formatter.FormatGameweekFinished(gw, league);
                var standings = Formatter.GetStandings(league, gw, includeExternalLinks: false);
                var topThree  = Formatter.GetTopThreeGameweekEntries(league, gw, includeExternalLinks: false);
                var worst     = Formatter.GetWorstGameweekEntry(league, gw, includeExternalLinks: false);
                messages.AddRange(new RichMesssage[]
                {
                    new ("ℹ️ Gameweek finished!", intro),
                    new ("ℹ️ Standings", standings),
                    new ("ℹ️ Top 3", topThree),
                    new ("ℹ️ Lantern beige", worst)
                });
Exemple #7
0
    public async Task <IActionResult> OnPost(string teamId, EventSubscription[] subscriptions)
    {
        if (subscriptions == null || !subscriptions.Any())
        {
            TempData["msg"] += $"No subs selected..";
            return(RedirectToPage(nameof(PublishEvent)));
        }

        var teamIdToUpper = teamId.ToUpper();
        var team          = await _teamRepo.GetTeam(teamIdToUpper);

        if (subscriptions.Contains(EventSubscription.Standings))
        {
            var settings = await _gameweekClient.GetGlobalSettings();

            var gameweek = settings.Gameweeks.GetCurrentGameweek();
            if (team.FplbotLeagueId.HasValue && !string.IsNullOrEmpty(team.FplBotSlackChannel))
            {
                await _session.Send("FplBot.EventHandlers.Slack", new PublishStandingsToSlackWorkspace(team.TeamId, team.FplBotSlackChannel, team.FplbotLeagueId.Value, gameweek.Id));

                TempData["msg"] = $"Published standings to {teamId}";
            }
            else
            {
                TempData["msg"] = $"Did not publish. Missing fpl league id for {teamId}";
            }
        }
        else
        {
            TempData["msg"] += $"Unsupported event. Nothing published.";
        }

        return(RedirectToPage(nameof(PublishEvent)));
    }
Exemple #8
0
    public async Task EveryMinuteTick()
    {
        GlobalSettings globalSettings;

        try
        {
            globalSettings = await _globalSettingsClient.GetGlobalSettings();
        }
        catch (HttpRequestException hre) when(LogError(hre))
        {
            return;
        }
        var gweeks = globalSettings.Gameweeks;

        var next = gweeks.FirstOrDefault(gw => gw.IsNext);

        if (next != null)
        {
            if (_dateTimeUtils.IsWithinMinutesToDate(60, next.Deadline))
            {
                await _session.Publish(new OneHourToDeadline(new GameweekNearingDeadline(next.Id, next.Name, next.Deadline)));
            }

            if (_dateTimeUtils.IsWithinMinutesToDate(24 * 60, next.Deadline))
            {
                await _session.Publish(new TwentyFourHoursToDeadline(new GameweekNearingDeadline(next.Id, next.Name, next.Deadline)));
            }
        }
        else
        {
            _logger.LogInformation($"No next gameweek");
        }
    }
Exemple #9
0
    public async Task Handle(PublishFixtureEventsToSlackWorkspace message, IMessageHandlerContext messageContext)
    {
        _logger.LogInformation($"Publishing {message.FixtureEvents.Count} fixture events to {message.WorkspaceId}");
        var slackTeam = await _slackTeamRepo.GetTeam(message.WorkspaceId);

        TauntData tauntData = null;

        if (slackTeam.Subscriptions.ContainsSubscriptionFor(EventSubscription.Taunts) && slackTeam.FplbotLeagueId.HasValue)
        {
            var gws = await _globalSettingsClient.GetGlobalSettings();

            var currentGw  = gws.Gameweeks.GetCurrentGameweek();
            var slackUsers = await GetSlackUsers(slackTeam);

            var entries = await _leagueEntriesByGameweek.GetEntriesForGameweek(currentGw.Id, slackTeam.FplbotLeagueId.Value);

            var transfers = await _transfersByGameWeek.GetTransfersByGameweek(currentGw.Id, slackTeam.FplbotLeagueId.Value);

            tauntData = new TauntData(transfers, entries, entryName => SlackHandleHelper.GetSlackHandleOrFallback(slackUsers, entryName));
        }

        if (!string.IsNullOrEmpty(slackTeam.FplBotSlackChannel))
        {
            var eventMessages = GameweekEventsFormatter.FormatNewFixtureEvents(message.FixtureEvents, slackTeam.Subscriptions.ContainsStat, FormattingType.Slack, tauntData);
            var formattedStr  = eventMessages.Select(evtMsg => $"{evtMsg.Title}\n{evtMsg.Details}");
            await _publisher.PublishToWorkspace(slackTeam.TeamId, slackTeam.FplBotSlackChannel, formattedStr.ToArray());
        }
    }
    public async Task EveryOtherMinuteTick(CancellationToken token)
    {
        GlobalSettings globalSettings;

        try
        {
            globalSettings = await _gwClient.GetGlobalSettings();
        }
        catch (Exception e) when(LogError(e))
        {
            return;
        }

        var gameweeks      = globalSettings.Gameweeks;
        var fetchedCurrent = gameweeks.FirstOrDefault(gw => gw.IsCurrent);

        if (_storedCurrent == null)
        {
            _logger.LogDebug("Executing initial fetch");
            _storedCurrent = fetchedCurrent;
            if (fetchedCurrent != null)
            {
                await _mediator.Publish(new GameweekMonitoringStarted(fetchedCurrent), token);
            }
        }

        if (fetchedCurrent == null)
        {
            _logger.LogDebug("No gw marked as current");
            return;
        }

        _logger.LogDebug($"Stored: {_storedCurrent.Id} & Fetched: {fetchedCurrent.Id}");

        if (IsChangeToNewGameweek(fetchedCurrent) || IsFirstGameweekChangingToCurrent(fetchedCurrent))
        {
            await _session.Publish(new FplBot.Messaging.Contracts.Events.v1.GameweekJustBegan(new (fetchedCurrent.Id)));

            await _mediator.Publish(new GameweekJustBegan(fetchedCurrent), token);
        }
        else if (IsChangeToFinishedGameweek(fetchedCurrent))
        {
            await _session.Publish(new FplBot.Messaging.Contracts.Events.v1.GameweekFinished(new (fetchedCurrent.Id)));

            await _mediator.Publish(new GameweekFinished(fetchedCurrent), token);
        }
        else
        {
            if (!_storedCurrent.IsFinished)
            {
                await _mediator.Publish(new GameweekCurrentlyOnGoing(_storedCurrent), token);
            }
            else
            {
                await _mediator.Publish(new GameweekCurrentlyFinished(_storedCurrent), token);
            }
        }

        _storedCurrent = fetchedCurrent;
    }
Exemple #11
0
    public async Task <IEnumerable <EntryCaptainPick> > GetEntryCaptainPicks(int gameweek, int leagueId)
    {
        var leagueTask  = _leagueClient.GetClassicLeague(leagueId);
        var playersTask = _globalSettingsClient.GetGlobalSettings();

        var league  = await leagueTask;
        var players = await playersTask;

        var entries = new List <GenericEntry>();

        if (league.Standings.Entries.Any())
        {
            entries = league.Standings.Entries.OrderBy(x => x.Rank).ToList().Select(e => new GenericEntry
            {
                Entry     = e.Entry,
                EntryName = e.EntryName
            }).ToList();
        }
        else
        {
            entries = league.NewEntries.Entries.ToList().Select(e => new GenericEntry
            {
                Entry     = e.Entry,
                EntryName = e.EntryName
            }).ToList();
        }

        var entryCaptainPicks = await Task.WhenAll(entries.Select(entry => GetEntryCaptainPick(entry, gameweek, players.Players)));

        return(entryCaptainPicks.WhereNotNull());
    }
Exemple #12
0
        public async Task Handle(GameweekFinished notification, CancellationToken cancellationToken)
        {
            var gameweek = notification.Gameweek.Id;
            var settings = await _gameweekClient.GetGlobalSettings();

            var gameweeks = settings.Gameweeks;
            var gw        = gameweeks.SingleOrDefault(g => g.Id == gameweek);

            if (gw == null)
            {
                _logger.LogError("Found no gameweek with id {id}", gameweek);
                return;
            }

            var teams = await _teamRepo.GetAllTeams();

            foreach (var team in teams)
            {
                if (!team.Subscriptions.ContainsSubscriptionFor(EventSubscription.Standings))
                {
                    _logger.LogInformation("Team {team} hasn't subscribed for gw standings, so bypassing it", team.TeamId);
                    continue;
                }

                try
                {
                    await _mediator.Publish(new PublishStandingsCommand(team, gw), cancellationToken);
                }
                catch (Exception e)
                {
                    _logger.LogError(e, e.Message);
                }
            }
        }
        public override async Task <EventHandledResponse> Handle(EventMetaData eventMetadata, AppMentionEvent appMentioned)
        {
            var team = await _teamRepo.GetTeam(eventMetadata.Team_Id);

            var settings = await _globalSettingsClient.GetGlobalSettings();

            var gameweek = settings.Gameweeks.GetCurrentGameweek();
            await _mediator.Publish(new PublishStandingsCommand(team, gameweek));

            return(new EventHandledResponse("OK"));
        }
Exemple #14
0
    public async Task <IActionResult> OnPostAddEntry(AddEntry model)
    {
        if (!model.VerifiedEntryType.HasValue)
        {
            TempData["error"] += $"You must specify a {nameof(model.VerifiedEntryType)}";
            return(RedirectToPage("Verified"));
        }
        if (model.VerifiedEntryType == VerifiedEntryType.FootballerInPL && !model.PLPlayer.HasValue)
        {
            TempData["error"] += $"Cannot add {nameof(VerifiedEntryType.FootballerInPL)} without {nameof(model.PLPlayer)}";
            return(RedirectToPage("Verified"));
        }

        _logger.LogInformation("Adding new entry: {entryId}", model.EntryId);
        await _repo.Insert(new VerifiedEntry(
                               model.EntryId,
                               model.FullName,
                               model.EntryTeamName,
                               model.VerifiedEntryType.Value,
                               model.Alias,
                               model.Description));

        TempData["msg"] += $"Entry {model.EntryId} added!";

        await _mediator.Publish(new UpdateEntryStats(model.EntryId));

        if (model.PLPlayer.HasValue)
        {
            var settings = await _settings.GetGlobalSettings();

            var gameweek = settings.Gameweeks.GetCurrentGameweek();
            await _mediator.Publish(new ConnectEntryToPLPlayer(model.EntryId, model.PLPlayer.Value, gameweek?.Id));
        }

        await _mediator.Publish(new IndexEntry(model.EntryId));

        return(RedirectToPage("Verified"));
    }
    public override async Task <EventHandledResponse> Handle(EventMetaData eventMetadata, AppMentionEvent appMentioned)
    {
        var team = await _teamRepo.GetTeam(eventMetadata.Team_Id);

        var settings = await _globalSettingsClient.GetGlobalSettings();

        var gameweek = settings.Gameweeks.GetCurrentGameweek();

        if (team.HasChannelAndLeagueSetup())
        {
            await _session.Send("FplBot.EventHandlers.Slack", new PublishStandingsToSlackWorkspace(team.TeamId, appMentioned.Channel, team.FplbotLeagueId.Value, gameweek.Id));
        }

        return(new EventHandledResponse("OK"));
    }
Exemple #16
0
        public override async Task <EventHandledResponse> Handle(EventMetaData eventMetadata, AppMentionEvent message)
        {
            var globalSettings = await _globalSettingsClient.GetGlobalSettings();

            var injuredPlayers = FindInjuredPlayers(globalSettings.Players);

            var textToSend = Formatter.GetInjuredPlayers(injuredPlayers);

            if (string.IsNullOrEmpty(textToSend))
            {
                return(new EventHandledResponse("Not found"));
            }
            await _workspacePublisher.PublishToWorkspace(eventMetadata.Team_Id, message.Channel, textToSend);

            return(new EventHandledResponse(textToSend));
        }
        public async Task EveryMinuteTick()
        {
            var globalSettings = await _globalSettingsClient.GetGlobalSettings();

            var gweeks = globalSettings.Gameweeks;

            var current = gweeks.FirstOrDefault(gw => gw.IsCurrent);

            if (current == null)
            {
                current = gweeks.First();
            }

            if (current != null)
            {
                if (_dateTimeUtils.IsWithinMinutesToDate(60, current.Deadline))
                {
                    await _mediator.Publish(new OneHourToDeadline(current));
                }

                if (_dateTimeUtils.IsWithinMinutesToDate(24 * 60, current.Deadline))
                {
                    await _mediator.Publish(new TwentyFourHoursToDeadline(current));
                }
            }

            var next = gweeks.FirstOrDefault(gw => gw.IsNext);

            if (next != null)
            {
                if (_dateTimeUtils.IsWithinMinutesToDate(60, next.Deadline))
                {
                    await _mediator.Publish(new OneHourToDeadline(next));
                }

                if (_dateTimeUtils.IsWithinMinutesToDate(24 * 60, next.Deadline))
                {
                    await _mediator.Publish(new TwentyFourHoursToDeadline(next));
                }
            }
            else
            {
                _logger.LogInformation($"No next gameweek");
            }
        }
Exemple #18
0
    public async Task Handle(PublishDeadlineNotificationToSlackWorkspace message, IMessageHandlerContext context)
    {
        string notification = $"⏳ Gameweek {message.Gameweek.Id} deadline in 24 hours!";

        var team = await _teamRepo.GetTeam(message.WorkspaceId);

        await PublishToTeam();

        async Task PublishToTeam()
        {
            var slackClient = _builder.Build(team.AccessToken);
            var res         = await slackClient.ChatPostMessage(team.FplBotSlackChannel, notification);

            if (res.Ok)
            {
                await PublishFixtures(slackClient, res.ts);
            }
        }

        async Task PublishFixtures(ISlackClient slackClient, string ts)
        {
            var fixtures = await _fixtures.GetFixturesByGameweek(message.Gameweek.Id);

            var teams = (await _globalSettingsClient.GetGlobalSettings()).Teams;
            var users = await slackClient.UsersList();

            var user = users.Members.FirstOrDefault(u =>
                                                    u.Is_Admin); // could have selected app_install user here, if we had this stored
            var userTzOffset = user?.Tz_Offset ?? 0;
            var messageGameweekNearingDeadline = message.Gameweek;
            var fixturesList = Formatter.FixturesForGameweek(messageGameweekNearingDeadline.Id,
                                                             messageGameweekNearingDeadline.Name, messageGameweekNearingDeadline.Deadline, fixtures, teams,
                                                             tzOffset: userTzOffset);

            await slackClient.ChatPostMessage(new ChatPostMessageRequest
            {
                Channel      = team.FplBotSlackChannel,
                thread_ts    = ts,
                Text         = fixturesList,
                unfurl_links = "false"
            });
        }
    }
Exemple #19
0
        public override async Task <EventHandledResponse> Handle(EventMetaData eventMetadata, AppMentionEvent message)
        {
            var globalSettings = await _globalSettingsClient.GetGlobalSettings();

            var allPlayers = globalSettings.Players;
            var teams      = globalSettings.Teams;

            var priceChangedPlayers = allPlayers.Where(p => p.CostChangeEvent != 0 && p.IsRelevant());

            if (priceChangedPlayers.Any())
            {
                var messageToSend = Formatter.FormatPriceChanged(priceChangedPlayers, teams);
                await _workSpacePublisher.PublishToWorkspace(eventMetadata.Team_Id, message.Channel, messageToSend);
            }
            else
            {
                await _workSpacePublisher.PublishToWorkspace(eventMetadata.Team_Id, message.Channel, "No relevant price changes yet");
            }

            return(new EventHandledResponse("Ok"));
        }
Exemple #20
0
    public async Task Handle(SeedSelfishness message, IMessageHandlerContext context)
    {
        using var scope = _logger.BeginScope(new Dictionary <string, object> {
            ["Entry"] = message.EntryId
        });
        var verifiedPlEntry = await _plRepo.GetVerifiedPLEntry(message.EntryId);

        var settings = await _settingsClient.GetGlobalSettings();

        var allPlayers        = settings.Players;
        var currentGameweekId = settings.Gameweeks.GetCurrentGameweek().Id;
        var liveItems         = await GetAllLiveItems(currentGameweekId);

        var player        = allPlayers.Get(verifiedPlEntry.PlayerId);
        var selfOwnership = (await _calculator.CalculateSelfOwnershipPoints(verifiedPlEntry.EntryId, player.Id, Enumerable.Range(1, currentGameweekId), liveItems)).ToArray();
        await _plRepo.UpdateStats(verifiedPlEntry.EntryId, verifiedPlEntry.SelfOwnershipStats with
        {
            TotalPoints = selfOwnership.Sum(),
            WeekCount   = selfOwnership.Length,
            Gameweek    = currentGameweekId
        });
Exemple #21
0
        public async Task Handle(SeedSelfishness notification, CancellationToken cancellationToken)
        {
            var settings = await _settingsClient.GetGlobalSettings();

            var allPlayers = settings.Players;

            var allPlEntries = await _plRepo.GetAllVerifiedPLEntries();

            int currentGameweekId = settings.Gameweeks.GetCurrentGameweek().Id;
            var liveItems         = await GetAllLiveItems(currentGameweekId);

            foreach (var verifiedPlEntry in allPlEntries)
            {
                var player        = allPlayers.Get(verifiedPlEntry.PlayerId);
                var selfOwnership = (await _calculator.CalculateSelfOwnershipPoints(verifiedPlEntry.EntryId, player.Id, Enumerable.Range(1, currentGameweekId), liveItems)).ToArray();
                await _plRepo.UpdateStats(verifiedPlEntry.EntryId, verifiedPlEntry.SelfOwnershipStats with
                {
                    TotalPoints = selfOwnership.Sum(),
                    WeekCount   = selfOwnership.Length,
                    Gameweek    = currentGameweekId
                });
Exemple #22
0
    private async Task CheckForRemovedFixtures(ICollection <Fixture> updatedFixtures, int gw)
    {
        using var scope = _logger.AddContext("CheckForRemovedFixtures");
        var currentEvent = _currentFixtures.First().Event;
        var updatedEvent = updatedFixtures.First().Event;

        if (updatedEvent != currentEvent)
        {
            _logger.LogWarning("Checking fixtures for different gameweek. {Current} vs {Updated}. Aborting.", currentEvent, updatedEvent);
            return;
        }

        foreach (var currentFixture in _currentFixtures)
        {
            try
            {
                var isFixtureRemoved = updatedFixtures.All(f => f.Id != currentFixture.Id);
                if (isFixtureRemoved)
                {
                    var settings = await _globalSettingsClient.GetGlobalSettings();

                    var teams          = settings.Teams;
                    var homeTeam       = teams.First(t => t.Id == currentFixture.HomeTeamId);
                    var awayTeam       = teams.First(t => t.Id == currentFixture.AwayTeamId);
                    var removedFixture = new RemovedFixture(currentFixture.Id,
                                                            new (homeTeam.Id, homeTeam.Name, homeTeam.ShortName),
                                                            new (awayTeam.Id, awayTeam.Name, awayTeam.ShortName));
                    await _session.Publish(new FixtureRemovedFromGameweek(gw, removedFixture));
                }
                else
                {
                    _logger.LogDebug("Fixture {FixtureId} not removed", currentFixture.Id);
                }
            }
            catch (Exception e) when(LogError(e))
            {
            }
        }
    }
Exemple #23
0
    public async Task Handle(ConnectEntryToPLPlayer notification, CancellationToken cancellationToken)
    {
        var settings = await _settings.GetGlobalSettings();

        _logger.LogInformation($"Inserting hardcoded list");

        var allTeams   = settings.Teams.ToList();
        var allPlayers = settings.Players.ToList();

        var plPlayer = allPlayers.Get(notification.PlayerId);

        if (plPlayer != null)
        {
            _logger.LogInformation($"FOUND PLAYER {plPlayer.WebName}, INSERTING PL ENTRY {notification.EntryId}");
            var teamForPLEntry = allTeams.Get(plPlayer.TeamId);

            await _repo.Insert(new VerifiedPLEntry(
                                   EntryId : notification.EntryId,
                                   TeamId : teamForPLEntry.Id,
                                   TeamCode : teamForPLEntry.Code,
                                   TeamName : teamForPLEntry.Name,
                                   PlayerId : plPlayer.Id,
                                   PlayerCode : plPlayer.Code,
                                   PlayerWebName : plPlayer.WebName,
                                   PlayerFullName : plPlayer.FullName
                                   ));

            _logger.LogInformation($"{notification.EntryId} inserted");

            if (notification.Gameweek.HasValue)
            {
                await _mediator.Publish(new UpdateSelfishStatsForPLEntry(notification.Gameweek.Value, notification.EntryId), cancellationToken);
            }
        }
        else
        {
            _logger.LogError($"PL Player {plPlayer.Id} not found");
        }
    }
    public async Task Handle(PublishStandingsToSlackWorkspace message, IMessageHandlerContext context)
    {
        var settings = await _settingsClient.GetGlobalSettings();

        var           gameweeks = settings.Gameweeks;
        var           gw        = gameweeks.SingleOrDefault(g => g.Id == message.GameweekId);
        ClassicLeague league    = null;

        try
        {
            league = await _leagueClient.GetClassicLeague(message.LeagueId);

            var intro     = Formatter.FormatGameweekFinished(gw, league);
            var standings = Formatter.GetStandings(league, gw);
            var topThree  = Formatter.GetTopThreeGameweekEntries(league, gw);
            var worst     = Formatter.GetWorstGameweekEntry(league, gw);
            await _publisher.PublishToWorkspace(message.WorkspaceId, message.Channel, intro, standings, topThree, worst);
        }
        catch (HttpRequestException e) when(e.StatusCode == HttpStatusCode.NotFound)
        {
            await _publisher.PublishToWorkspace(message.WorkspaceId, message.Channel, $"League standings are now generally ready, but I could not seem to find a classic league with id `{message.LeagueId}`. Are you sure it's a valid classic league id?");
        }
    }
    public override async Task <EventHandledResponse> Handle(EventMetaData eventMetadata, AppMentionEvent slackEvent)
    {
        var team = await _tokenStore.GetTeam(eventMetadata.Team_Id);

        var slackClient = _slackClientService.Build(team.AccessToken);
        var usersTask   = slackClient.UsersList();
        var settings    = await _globalSettingsClient.GetGlobalSettings();

        var users     = await usersTask;
        var gameweeks = settings.Gameweeks;
        var teams     = settings.Teams;

        var nextGw   = gameweeks.First(gw => gw.IsNext);
        var fixtures = await _fixtureClient.GetFixturesByGameweek(nextGw.Id);

        var user         = users.Members.FirstOrDefault(x => x.Id == slackEvent.User);
        var userTzOffset = user?.Tz_Offset ?? 0;

        var textToSend = Formatter.FixturesForGameweek(nextGw.Id, nextGw.Name, nextGw.Deadline, fixtures, teams, userTzOffset);

        await _workspacePublisher.PublishToWorkspace(eventMetadata.Team_Id, slackEvent.Channel, textToSend);

        return(new EventHandledResponse(textToSend));
    }