private async Task Step3_ReadDiscordBotkeyAsync(SocketMessage msg)
        {
            if (msg.Channel.Id == UserChannel.Id && msg.Author.Id == GuildUser.Id)
            {
                await _verificationService.InvokeVerificationMessageAsync(this, msg).ConfigureAwait(false);

                if (!await ReceiveAbortAsync(msg))
                {
                    var keyString = VerificationKeyManager.GetKeyString(GuildUser.GuildId, GuildUser.Id, ForumUserId, VerificationKeyScope.Discord);
                    if (!msg.Content.Equals(keyString))
                    {
                        await ErrorAsync("dm_no_botkey").ConfigureAwait(false);

                        return;
                    }

                    try {
                        await _verificationService.SetVerifiedAsync(GuildUser, ForumUserId);
                        await EmbedAsync("process_completed");

                        _verificationService.EndVerification(this);

                        await _verificationService.InvokeVerificationStepAsync(this, VerificationStep.Ended).ConfigureAwait(false);
                    } catch (UserCannotVerifyException) {
                        await ErrorAsync("user_cannot_verify").ConfigureAwait(false);
                    }
                }
            }
        }
        private async Task Step2_ReadPrivateForumMessageAsync(SocketMessage msg)
        {
            if (msg.Channel.Id == UserChannel.Id && msg.Author.Id == GuildUser.Id)
            {
                await _verificationService.InvokeVerificationMessageAsync(this, msg).ConfigureAwait(false);

                if (!await ReceiveAbortAsync(msg).ConfigureAwait(false))
                {
                    if (_fs.LoggedIn)
                    {
                        var conversations = await _fs.Forum.GetConversations(startPage : 1, pageCount : 2).ConfigureAwait(false);

                        var conversation = conversations.Where(c => c.Author is UserInfo).FirstOrDefault(c => (c.Author as UserInfo).Id == ForumUserId);

                        if (conversation is null)
                        {
                            await ErrorAsync("no_message_by_author");

                            return;
                        }
                        await conversation.DownloadMessagesAsync().ConfigureAwait(false);

                        using var uow = _db.UnitOfWork;
                        var verifystring = uow.GuildConfigs.For(GuildUser.GuildId).VerifyString;
                        if (!string.IsNullOrWhiteSpace(verifystring) && !conversation.Title.Contains(verifystring, StringComparison.OrdinalIgnoreCase))
                        {
                            await ErrorAsync("message_wrong_title_try_again").ConfigureAwait(false);

                            return;
                        }
                        var message = conversation.Messages.First().Content;

                        var verificationKey = VerificationKeyManager.GetKeyString(GuildUser.GuildId, GuildUser.Id, ForumUserId, VerificationKeyScope.Forum);
                        if (!message.Contains(verificationKey))
                        {
                            await ErrorAsync("message_no_botkey_try_again").ConfigureAwait(false);

                            return;
                        }
                        if (!message.Contains(GuildUser.ToString(), StringComparison.OrdinalIgnoreCase) && !message.Contains(GuildUser.Id.ToString(), StringComparison.OrdinalIgnoreCase))
                        {
                            await ErrorAsync("message_no_discorduser_try_again").ConfigureAwait(false);

                            return;
                        }

                        //prepare Step 3
                        var key     = VerificationKeyManager.GenerateVerificationKey(GuildUser.GuildId, GuildUser.Id, ForumUserId, VerificationKeyScope.Discord);
                        var success = await conversation.Reply(key.Key).ConfigureAwait(false);

                        if (!success)
                        {
                            await ErrorAsync("conversation_answer_failed_try_again").ConfigureAwait(false);

                            VerificationKeyManager.RemoveKey(GuildUser.GuildId, GuildUser.Id, ForumUserId, VerificationKeyScope.Discord);
                            return;
                        }

                        await _verificationService.InvokeVerificationStepAsync(this, VerificationStep.ForumConversationCreated).ConfigureAwait(false);

                        //complete Step 2
                        //this has to be below Step 3 preparation to allow handling the failure of sending the second verification key.
                        VerificationKeyManager.RemoveKey(GuildUser.GuildId, GuildUser.Id, ForumUserId, VerificationKeyScope.Forum);

                        await EmbedAsync("send_botkey_in_dm").ConfigureAwait(false);

                        _client.MessageReceived -= Step2_ReadPrivateForumMessageAsync;
                        _client.MessageReceived += Step3_ReadDiscordBotkeyAsync;
                    }
                    else
                    {
                        await ErrorAsync("forum_not_logged_in").ConfigureAwait(false);
                    }
                }
            }
        }