Task HandleReactionAsync(IMessageChannel channel, SocketReaction reaction, ReactionEvent eventType) { if (reaction.UserId != _discord.CurrentUser.Id) { _ = Task.Run(async() => { // retrieve message if (!(await channel.GetMessageAsync(reaction.MessageId) is IUserMessage message)) { return; } // retrieve user if (!(await channel.GetUserAsync(reaction.UserId) is IUser user)) { return; } // create context var context = new ReactionContext { Client = _discord, Message = message, User = user, GuildSettings = _guildSettingsCache[message.Channel], Reaction = reaction, Event = eventType }; try { foreach (var handler in _reactionHandlers) { if (await handler.TryHandleAsync(context)) { HandledReactions.Increment(); break; } } } catch (Exception e) { await _errorReporter.ReportAsync(e, context, false); } finally { ReceivedReactions.Increment(); } }); } return(Task.CompletedTask); }
public async Task <bool> TryCreateEventAsync(ulong guildId, ulong channelId, CurrencyEvent.Type type, EventOptions opts, Func <CurrencyEvent.Type, EventOptions, long, EmbedBuilder> embed) { SocketGuild g = _client.GetGuild(guildId); SocketTextChannel ch = g?.GetChannel(channelId) as SocketTextChannel; if (ch == null) { return(false); } ICurrencyEvent ce; if (type == CurrencyEvent.Type.Reaction) { ce = new ReactionEvent(_client, _cs, _bc, g, ch, opts, embed); } //else if (type == Event.Type.NotRaid) //{ // ce = new NotRaidEvent(_client, _cs, _bc, g, ch, opts, embed); //} else { return(false); } var added = _events.TryAdd(guildId, ce); if (added) { try { ce.OnEnded += OnEventEnded; await ce.StartEvent().ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); _events.TryRemove(guildId, out ce); return(false); } } return(added); }
public async Task <bool> TryCreateEventAsync(ulong guildId, ulong channelId, CurrencyEvent.Type type, EventOptions opts, Func <CurrencyEvent.Type, EventOptions, long, EmbedBuilder> embed) { SocketGuild g = _client.GetGuild(guildId); SocketTextChannel ch = g?.GetChannel(channelId) as SocketTextChannel; if (ch == null) { return(false); } ICurrencyEvent ce; if (type == CurrencyEvent.Type.Reaction) { ce = new ReactionEvent(_client, _cs, g, ch, opts, _configService.Data, embed); } else if (type == CurrencyEvent.Type.GameStatus) { ce = new GameStatusEvent(_client, _cs, g, ch, opts, embed); } else { return(false); } var added = _events.TryAdd(guildId, ce); if (added) { try { ce.OnEnded += OnEventEnded; await ce.StartEvent().ConfigureAwait(false); } catch (Exception ex) { Log.Warning(ex, "Error starting event"); _events.TryRemove(guildId, out ce); return(false); } } return(added); }
private async Task DiscordClient_ReactionChanged(Cacheable <IUserMessage, ulong> userMessage, ISocketMessageChannel channel, SocketReaction reaction, ReactionEvent eventType) { var message = await userMessage.GetOrDownloadAsync(); if (message == null) { return; } var user = reaction.User.IsSpecified ? reaction.User.Value : await DiscordClient.Rest.GetUserAsync(reaction.UserId); if (user == null) { return; } var ownUser = DiscordClient.CurrentUser; var ownId = ownUser.Id; if (user.Id == ownId) { return; } foreach (var reactionHandler in ReactionHandlers) { try { bool reactionHandled = await reactionHandler.HandleReactionChangedAsync(message, reaction.Emote, user, eventType); if (reactionHandled) { break; } if (eventType == ReactionEvent.Added) { reactionHandled = await reactionHandler.HandleReactionAddedAsync(message, reaction.Emote, user); } else { reactionHandled = await reactionHandler.HandleReactionRemovedAsync(message, reaction.Emote, user); } if (reactionHandled) { break; } } catch (Exception e) { Logger.LogError( e, "Reaction handler {0} threw an exception when handling reaction {1} added to message {2}.", reactionHandler, reaction.Emote.Name, message.Id ); } } }
public async Task <bool> HandleReactionChangedAsync(IUserMessage message, IEmote reaction, IUser user, ReactionEvent eventType) { // Basic check to optimize number of queries to db if (!message.Content.StartsWith("**\n")) { return(false); } var channel = message.Channel as ITextChannel; using var dbContext = DatabaseFactory.Create(); var data = await dbContext.RoleMenuMessageRoles.AsQueryable() .Where(i => i.GuildId == channel.GuildId && i.ChannelId == channel.Id && i.MessageId == message.Id) .ToArrayAsync(); // check if message is role picker message if (data.Length == 0) { return(false); } var role = Array.Find(data, d => d.Emote == reaction.ToString()); // Invalid reaction if (role == null) { await message.RemoveReactionAsync(reaction, user); return(true); } var guildRoles = channel.Guild.Roles.Where(r => data.Any(e => r.Id == e.RoleId)); var selectedRole = guildRoles.FirstOrDefault(r => r.Id == role.RoleId); // Role does not exists if (selectedRole == null) { // TODO Remove role from db return(true); } if (user is not IGuildUser guildUser) { await message.RemoveReactionAsync(reaction, user); return(true); } if (eventType == ReactionEvent.Removed) { await guildUser.RemoveRoleAsync(selectedRole); return(true); } // Remove roles when in exclusive mode if (dbContext.RoleMenuMessages.Any(m => m.GuildId == channel.GuildId && m.ChannelId == channel.Id && m.MessageId == message.Id && !m.CanSelectMultiple)) { var removeReactions = message.Reactions .Where(kv => kv.Value.IsMe && kv.Key.ToString() != reaction.ToString()) .Select(kv => kv.Key) .ToArray(); await message.RemoveReactionsAsync(user, removeReactions); var removeRoles = guildRoles.Where(r => guildUser.RoleIds.Contains(r.Id)); await guildUser.RemoveRolesAsync(removeRoles); } await guildUser.AddRoleAsync(selectedRole); return(true); }
public async Task <bool> HandleReactionChangedAsync(IUserMessage message, IEmote reaction, IUser user, ReactionEvent eventType) { if (user.IsBot) { return(false); } if (await VoteService.ParseVoteCommand(message) is not VoteDefinition voteDefinition) { return(false); } if (voteDefinition.IsPastDeadline()) { // vote already finished await message.RemoveReactionAsync(reaction, user); return(true); } if (!voteDefinition.Options.ContainsKey(reaction)) { // not a vote option await message.RemoveReactionAsync(reaction, user); return(true); } var newText = VoteService.ComposeSummary(message, voteDefinition); await VoteService.UpdateVoteReplyAsync(message, newText); return(true); }
public void RemoveReactionEvent(ReactionEvent reactionEvent) { _reactionEvents.Remove(reactionEvent); }
public void AddReactionEvent(ReactionEvent reactionEvent) { _reactionEvents.Add(reactionEvent); }