我如何在每条消息中收听 Discord 中的提及?

How can I listen to mentions in Disord in every message?

我私下不和,偶然发现了一个关于提及的问题。

我对如何在没有 运行 命令的情况下收集消息中提及的内容一无所知。这是我的场景:

我有一个命令可以为使用该命令的用户设置个人注释 - 例如“!Setnote我回来了16:15”。我的目标是当用户被提及(并且有一个活跃的笔记)时,机器人应该用笔记回复。

我知道如何在与命令结合使用时收集消息中的提及(使用 属性 MentionedUsers)。然而,我不知道如何在不使用命令的情况下始终听取提及。

我正在使用 Discord .Net API。我已经尝试寻找这几天,但我发现大多数人遇到麻烦/不知道 Context.Message.

中的 属性 MentionedUsers

我马上就要睡觉了,所以我会在早上检查这个,如果有任何问题,我会回复你的答案/问题(竖起大拇指)!提前致谢。

编辑:我希望这没问题,但我意识到这不是 post 中的一个实际问题。这里是:

即使没有执行命令,我如何始终收听消息中的提及?

我从来没有用过Discord.NET...因此,我想我会重复你已经知道的东西(我会保留它,因为我不知道其中有多少是合理的假设,也不知道有多少可能会帮助其他人)。

根据我在文档和存储库中找到的内容,您可以创建一个客户端:

var client = new DiscordSocketClient();

然后hook到MessageReceived(你还想调用LoginAsyncStartAsync)。

client.MessageReceived += MessageReceived;

Task MessageReceived(SocketMessage message)
{
    // ...
}

然后你可以阅读SocketMessage.MentionedUsers(你提到你已经知道该怎么做),这将是提到的用户(SocketUser)的集合。我猜你会搜索它并发现它是否与你的列表相交......假设你通过名称识别它们,并且有一个方法 UsersWithNotes return 一个 IEnumerable<string> 与你想要的名字匹配,你可以这样做:

Task MessageReceived(SocketMessage message)
{
    // ...
    var foundUsers = message.MentionedUsers.Select(u => u.Username).Intersect(UsersWithNotes());
    // ...
}

查看源代码中的示例,似乎 SocketMessage 获取所有消息,然后您继续过滤掉命令。示例:

async Task HandleCommandAsync(SocketMessage messageParam)
{
    // Filter out system messages
    var message = messageParam as SocketUserMessage;
    if (message == null)
    {
        return;
    }

    // Filter out non commands
    int argPos = 0;
    if (!(message.HasCharPrefix('!', ref argPos) || 
        message.HasMentionPrefix(_client.CurrentUser, ref argPos)) ||
        message.Author.IsBot)
        return;

    //...
}

好吧,如果您需要阅读所有消息中的 SocketMessage.MentionedUsers,那么请不管 那些检查。

注意:显然你的机器人也会收到它发送的消息,所以你可能仍然想过滤掉来自它自己的消息。此外,您可以获得带有 message.Content 的消息文本,这意味着您可以根据需要对其进行解析。

另请参阅How can I have my Discord C# respond to mentions? 显示了当您的机器人被提及时如何处理。

我没有测试我在这里所说的任何内容。我从未使用过 Discord.NET,现在仍然没有使用它。持保留态度

在 Theraot 的帮助下,我开始真正地再次查看代码并试图理解实际发生的事情。

我真正做的唯一一件事是制作一个每次收到消息时都会执行的方法(我真正不明白的是如何让提到的用户进入该方法)现在我觉得这很愚蠢,因为感觉如此简单。早些时候我并不真正理解 message_recieved 是如何工作的,因为前 100 行代码只是获取机器人 运行 的模板,之后我编写了自己的命令。

我删除了下面的一些代码行以进一步清理它,以便最有用的行脱颖而出:

private async Task Client_MessageReceived(SocketMessage messageParams)
    {
        var message = messageParams as SocketUserMessage;
        var context = new SocketCommandContext(Client, message);

        if (context.Message == null || context.Message.Content == "")
            return;

        if (context.User.IsBot)
            return;

        NoteCommands.CheckIfUserIsMentioned(context);

        var result = await _commands.ExecuteAsync(context, argPos);
    }

然后在方法 (Notecommands.CheckIfUserIsMentioned) 中,我使用 context.Message.MentionedUsers 获取了提及项(如果有的话)并检查它们是否有活跃的笔记。

再次感谢。 :) 我希望有人需要像我一样的帮助。