DSharpPlus-对现有消息的WaitForReaction

时间:2020-11-05 18:38:23

标签: c# discord dsharp+

我正在尝试使用DSharpPlus库创建一个discord机器人,如果您对带有特定表情符号的消息做出反应,您将获得特定角色。这个概念很简单,但是我没有弄清楚一个非常重要的概念。就是说,我如何让机器人始终听取对现有消息的反应。

我尝试通过命令来执行此操作,但使它正常工作,但是据我了解,这种方法的问题在于,该机器人仅在键入命令后才侦听反应,并且仅持续一分钟左右(根据配置)。

public class RoleCommands : BaseCommandModule
{
    [Command("join")]
    public async Task Join(CommandContext ctx)
    {
        var joinEmbed = new DiscordEmbedBuilder
        {
            Title = "Reaction with thumbs up!",
            Color = DiscordColor.Green
        };

        var joinMessage = await ctx.Channel.SendMessageAsync(embed: joinEmbed).ConfigureAwait(false);

        var thumbsUpEmoji = DiscordEmoji.FromName(ctx.Client, ":+1:");
        var thumbsDownEmoji = DiscordEmoji.FromName(ctx.Client, ":-1:");

        await joinMessage.CreateReactionAsync(thumbsUpEmoji).ConfigureAwait(false);
        await joinMessage.CreateReactionAsync(thumbsDownEmoji).ConfigureAwait(false);

        var interactivity = ctx.Client.GetInteractivity();

        var reactionResult = await interactivity.WaitForReactionAsync(x =>
            x.Message == joinMessage
            && x.User == ctx.User
            && x.Emoji == thumbsUpEmoji);

        if (reactionResult.Result.Emoji == thumbsUpEmoji)
        {
            var role = ctx.Guild.GetRole(773965440913375282);
            await ctx.Member.GrantRoleAsync(role).ConfigureAwait(false);

            await joinMessage.DeleteAsync().ConfigureAwait(false);
        }
    }
}

我该如何在命令外执行此操作,在该命令中我可以向其传递消息ID,然后它一直在有限的时间内反对该消息以进行反应?

2 个答案:

答案 0 :(得分:0)

将消息ID存储在某个地方,然后将MessageReactionAdded事件挂在DiscordClient上,并在那里进行逻辑处理。

答案 1 :(得分:0)

我的问题的完整答案是使用DiscordClient.MessageReactionAdded += OnReactionAdded;并像这样实现该方法:

private async Task OnReactionAdded(DiscordClient sender, MessageReactionRemoveEventArgs e)
{
    var messageId = e.Message.Id;
    var guild = e.Message.Channel.Guild;
    var reactionName = e.Emoji.GetDiscordName();

    var reactionDetail = ReactionDetails.FirstOrDefault(x =>
        x.MessageId == messageId
        && x.GuildId == guild.Id
        && x.ReactionName == reactionName);

    if (reactionDetail != null)
    {
        var member = e.User as DiscordMember;
        if (member != null)
        {
            var role = guild.Roles.FirstOrDefault(x => x.Value.Id == reactionDetail.RoleId).Value;
            await member.GrantRoleAsync(role).ConfigureAwait(false);
        }
    }
}