-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathWorker.cs
110 lines (91 loc) · 4.61 KB
/
Worker.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
using DSharpPlus;
using DSharpPlus.Entities;
using MeetupBot.Data;
using MeetupBot.Helpers;
using MeetupBot.Services.Abstract;
using Microsoft.Extensions.Options;
using NodaTime;
namespace MeetupBot;
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
private readonly IOptionsMonitor<AppConfiguration> _configuration;
private readonly IMeetupService _meetupService;
private readonly IServiceScopeFactory _serviceScopeFactory;
private readonly DiscordClient _client;
public Worker(ILogger<Worker> logger, IOptionsMonitor<AppConfiguration> configuration, IMeetupService meetupService, IServiceScopeFactory serviceScopeFactory)
{
_logger = logger;
_configuration = configuration;
_meetupService = meetupService;
_serviceScopeFactory = serviceScopeFactory;
if (_configuration.CurrentValue.DiscordToken is null)
{
throw new Exception("DiscordToken is not set.");
}
_client = DiscordClientBuilder.CreateDefault(configuration.CurrentValue.DiscordToken!, DiscordIntents.AllUnprivileged)
.Build();
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
await _client.ConnectAsync(new DiscordActivity("\ud83d\udc40 looking for new meetups", DiscordActivityType.Custom));
_logger.LogInformation("Connected to discord");
using var scope = _serviceScopeFactory.CreateScope();
var context = scope.ServiceProvider.GetRequiredService<AppDbContext>();
await context.Database.EnsureCreatedAsync(stoppingToken);
while (!stoppingToken.IsCancellationRequested)
{
var groups = (await _meetupService.GetMeetupGroupsFromConfiguration(stoppingToken)).ToArray();
var events = groups.SelectMany(x => x.Events).ToArray();
var existingGroupUrls = context.MeetupGroups.Select(x => x.Url).ToHashSet();
var existingEventUrls = context.MeetupEvents.Select(x => x.Url).ToHashSet();
var newGroups = groups.Where(group => !existingGroupUrls.Contains(group.Url)).ToArray();
var newEvents = events.Where(@event => !existingEventUrls.Contains(@event.Url)).ToArray();
var newEventsWithGroups = newEvents
.Select(x => (groups.First(y => y.Events.Any(z => z.Url == x.Url)), x));
_logger.LogInformation("Found {count} new events", newEvents.Length);
if (newEvents.Length != 0)
{
var channels = await Task.WhenAll(_configuration.CurrentValue.DiscordChannels.Select(id => _client.GetChannelAsync(id)));
foreach (var (group, newEvent) in newEventsWithGroups)
{
foreach (var channel in channels)
{
var message = await new DiscordMessageBuilder()
.AddEmbed(DiscordHelpers.GetEmbedFromEvent(group, newEvent))
.SendAsync(channel);
await message.CreateReactionAsync(DiscordEmoji.FromUnicode("\ud83d\udc4d"));
await message.CreateReactionAsync(DiscordEmoji.FromUnicode("\ud83d\udc4e"));
await message.PinAsync();
}
}
await ClearOldMeetupsFromPinnedMessagesAsync(channels);
context.MeetupGroups.AddRange(newGroups);
context.MeetupEvents.AddRange(newEvents.Where(@event => newGroups.SelectMany(x => x.Events).All(groupEvent => groupEvent.Url != @event.Url)));
await context.SaveChangesAsync(stoppingToken);
}
await Task.Delay(TimeSpan.FromSeconds(_configuration.CurrentValue.MeetupAPITTLInSeconds), stoppingToken);
}
}
private static async Task ClearOldMeetupsFromPinnedMessagesAsync(IEnumerable<DiscordChannel> channels)
{
foreach (var channel in channels)
{
var pinnedBotMessages = (await channel.GetPinnedMessagesAsync())
.Where(x => x.Author?.IsCurrent == true)
.ToArray();
foreach (var message in pinnedBotMessages)
{
var date = DiscordHelpers.GetMeetupDateTimeFromEmbed(message.Embeds[0]);
if (date is null)
{
continue;
}
if (date.Value < LocalDateTime.FromDateTime(DateTime.UtcNow))
{
await message.UnpinAsync();
}
}
}
}
}