コード例 #1
0
        private Task MessageReceived(SocketMessage message)
        {
            if (message.Author.Id == _bot.DiscordClient.CurrentUser.Id)
            {
                return(Task.CompletedTask);
            }

            if (!(message.Author is SocketGuildUser guildUser))
            {
                return(Task.CompletedTask);
            }

            if (!(message.Channel is SocketTextChannel messageChannel))
            {
                return(Task.CompletedTask);
            }

            if (!(messageChannel.Category is SocketCategoryChannel categoryChannel))
            {
                return(Task.CompletedTask);
            }

            if (messageChannel.Category.Name != TranslationConstants.CategoryName)
            {
                return(Task.CompletedTask);
            }

            if (TranslationConstants.PermanentChannels.Contains(messageChannel.Name))
            {
                return(Task.CompletedTask);
            }

            var guildLang     = _serverConfig.GetLanguageForGuild(messageChannel.Guild.Id);
            var safeGuildLang = GetSafeLangString(guildLang);
            var lang          = messageChannel.GetLangFromChannelName(safeGuildLang);

            if (lang == null)
            {
                return(Task.CompletedTask);
            }

            var safeLang = GetSafeLangString(lang);

            if (!_channelPairs.TryGetValue(safeLang, out var pair))
            {
                _logger.LogWarning("Message received from a loc channel without a valid pair");
                return(Task.CompletedTask);
            }

            _logger.LogDebug("Starting translation of message");

            _bot.ExecuteHandlerAsyncronously <(SocketCategoryChannel category, Translation?translation)>(
                handler: async discord =>
            {
                if (pair?.TranslationChannel == null || pair?.StandardLangChanel == null)
                {
                    throw new InvalidOperationException("Invalid channel pair");
                }

                Translation?translation = null;
                if (messageChannel.Id == pair.StandardLangChanel.Id)
                {
                    translation = await SendMessageToPartner(message, $"{guildUser.Nickname ?? guildUser.Username}", pair.TranslationChannel, guildLang, lang, Foreign);
                }
                else if (messageChannel.Id == pair.TranslationChannel.Id)
                {
                    translation = await SendMessageToPartner(message, $"{guildUser.Nickname ?? guildUser.Username}", pair.StandardLangChanel, lang, guildLang, GuildLocale);
                }

                return(categoryChannel, translation);
            },
                callback: async result =>
            {
                var(category, translation) = result;
                if (category == null)
                {
                    return;
                }

                var historyChannel = category.Channels.OfType <SocketTextChannel>()
                                     .SingleOrDefault(a => a.Name == TranslationConstants.HistoryChannelName);
                if (historyChannel == null)
                {
                    return;
                }

                _logger.LogDebug("Sending messages to the history channel");

                var nickname = guildUser.Nickname ?? guildUser.Username;
                var avatar   = guildUser.GetAvatarUrl() ?? guildUser.GetDefaultAvatarUrl();

                var embed = new EmbedBuilder()
                            .WithAuthor(nickname, avatar, message.GetJumpUrl());

                // Translations still look better side to side when brief.
                // In case any one of them exceeds 1024 limit, it will be split into chunks
                // and all of them will be inlined.

                var guildLocal = translation?.GuildLocal;
                var foreign    = translation?.Foreign;

                if (!string.IsNullOrEmpty(guildLocal?.Text) && !string.IsNullOrEmpty(foreign?.Text))
                {
                    const int fieldLength = 1024;
                    var lengthIsBrief     =
                        guildLocal.Text.Length < fieldLength &&
                        foreign.Text.Length < fieldLength;
                    var hasCodeBlocks = TranslationService.CodeBlockPattern.IsMatch(translation !.Translated.Text);

                    if (lengthIsBrief && !hasCodeBlocks)
                    {
                        embed
                        .AddField(guildLocal.Language, guildLocal.Text, true)
                        .AddField(foreign.Language, foreign.Text, true);
                    }
                    else
                    {
                        embed
                        .AddChunks(guildLocal.Text.ChunkUpTo(fieldLength), guildLocal.Language)
                        .AddChunks(foreign.Text.ChunkUpTo(fieldLength), foreign.Language);
                    }
                }

                if (message.Attachments.Any())
                {
                    embed.WithImageUrl(message.Attachments.First().Url);

                    var others = message.Attachments.Skip(1).Select(x => x.Url).ToArray();
                    if (others.Length > 0)
                    {
                        embed.AddField("Attachments", string.Join("\n", others));
                    }
                }

                await historyChannel.SendMessageAsync(embed: embed.Build());

                _logger.LogDebug("Completed translating messages");
            });

            return(Task.CompletedTask);
        }