Как я могу слушать упоминания в Disord в каждом сообщении?

Я развил частную дискуссию и наткнулся на проблему с упоминаниями.

У меня нет понимания, как я должен собирать упоминания в сообщениях, не запуская команду. Это мой сценарий:

У меня есть команда, которая устанавливает личную заметку для пользователя, который использует команду, например. «!Заметьте, что я вернулся в 16:15». Моя цель состоит в том, что когда пользователь упоминается (и имеет активную заметку), бот должен ответить заметкой.

Я умею собирать упоминания в сообщении при объединении с командой (используя свойство MentionedUsers). Я, однако, не знаю, как ВСЕГДА слушать упоминания, даже когда команда не используется.

Я использую Discord .Net API. Я пытался искать об этом несколько дней, но в основном я нашел людей, у которых возникли проблемы/не знали о свойстве MentionedUsers в Context.Message.

Я лягу спать в любую минуту, так что я проверю это утром и отвечу на ваши ответы/вопросы, если они есть (скрестив пальцы)! Заранее спасибо.

Редактировать: я надеюсь, что все в порядке, но я понял, что это не был вопрос в посте. Вот оно:

Как я могу всегда отслеживать упоминания в сообщении, даже если команда не выполняется?


person rango    schedule 03.01.2019    source источник
comment
Спокойной ночи ... вопрос будет закрыт утром, так как в нем нет вопроса   -  person Selvin    schedule 03.01.2019
comment
О, дерьмо! Я даже не понял. Спасибо, что упомянули об этом.   -  person rango    schedule 03.01.2019


Ответы (2)


Я никогда не использовал Discord.NET... Таким образом, я думаю, что повторю то, что вы уже знаете (я оставлю это, потому что я не знаю, насколько это разумные предположения, и насколько это может помочь другим).

Из того, что я нашел в документации и репозиториях, вы можете создать клиент:

var client = new DiscordSocketClient();

Затем подключитесь к MessageReceived (вы также хотите вызвать LoginAsync и StartAsync).

client.MessageReceived += MessageReceived;

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

Затем вы можете прочитать SocketMessage.MentionedUsers (которое вы упомянули, вы уже умеете это делать), которое будет собранием упомянутых пользователей (SocketUser). Я думаю, вы будете искать его и найдете, пересекается ли он с вашим списком... если вы узнаете их по имени и у вас есть метод UsersWithNotes, который возвращает 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, что означает, что вы можете разобрать его, как хотите.

См. также: Как заставить мой Discord C# отвечать на упоминания?, который показывает, как обращаться с при упоминании вашего бота.

Я ничего не проверял из того, что говорю здесь. Я никогда не использовал Discord.NET и до сих пор не использовал его. Принимайте с недоверием.

person Theraot    schedule 03.01.2019
comment
Спасибо за огромный ответ с большим количеством информации. Я пытаюсь научиться читать документацию по API и действительно понимать их. Я делаю это ежедневно, так как это, очевидно, необходимо. Я экспериментировал с message_recieved, но вы заставили меня снова посмотреть на код, и я думаю, что после вашей информации у меня есть план! Я благодарен за ответ, и я надеюсь, что я придумаю решение с этой информацией. - person rango; 03.01.2019

С помощью 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 и проверил, есть ли у них активная заметка.

Спасибо еще раз. :) Надеюсь, кому-то нужна такая же помощь, как и мне.

person rango    schedule 03.01.2019