private async Task<TelegramBotReply> Step1(Message m)
        {
            if(m.Text == dezeWeek || m.Text == volgendeWeek)
            {
                isNextWeek = m.Text == volgendeWeek;
                var preferences = PreferenceRegistry.GetUserPreferencesForUser(m.From);
                var date = DateTime.Now.WeekendDate();
                if ((bool)isNextWeek)
                    date = date.AddDays(7);
                var roosterResult = await WindesheimRoosterConvertor.GetRooster(preferences, date);
                if (roosterResult.Success)
                {
                    var rooster = roosterResult.Rooster;
                    lessen = new List<string>();
                    if(rooster.Lessen.Count == 0)
                        return Message(m, "Je hebt in deze week geen lessen.");
                    foreach (var les in rooster.Lessen)
                        if (!lessen.Contains(les.Omschrijving))
                            lessen.Add(les.Omschrijving);
                    MessageFlow.Failed(); //step 2 of step 1 als het niet goed gaat
                    return Message(m, ReplyWithInstruction("Welke les wil je negeren?"), replyMarkup: KeyboardForResults(preferences));
                }
                else
                    return Message(m, "De roostersite is niet geschikbaar. Probeer het later nog eens.");

            }
            MessageFlow.Failed(); //step 2 of step 1 als het niet goed gaat
            return FailedInstruction(m);
        }
 protected async override Task<TelegramBotReply> HandleMessageAsync(TelegramBot.TelegramBot bot, Message m, MessageHandlerType type)
 {
     var preferences = PreferenceRegistry.GetUserPreferencesForUser(m.From);
     var klassenLijst = await WindesheimRoosterConvertor.GetKlassenLijst();
     if (!m.HasArguments)
     {
         if (preferences.RoosterFor != null)
             return Message(m, AddingKlasFailed("Je hebt al een klas opgegeven.\n\rOm deze aan te passen, typ: '/klas [klasnaam]'"));
         else
             return Message(m, AddingKlasFailed("Geef je klas op zoals deze op https://roosters.windesheim.nl/ staat, bijvoorbeeld: '/klas ICTM1a'"));
     }
     else
     {
         var klasStr = string.Join("", m.Arguments).ToLower();
         foreach (Klas k in klassenLijst)
             if (k.Name.ToLower() == klasStr)
             {
                 if (preferences.RoosterFor != null)
                 {
                     if (preferences.RoosterFor == k)
                         return Message(m, $"Je bent al gekoppeld aan de klas {k.Bold()}", userMarkup: true);
                     var roosterMessageFlow = new AddRoosterFlow(preferences, k);
                     m.From.MessageFlow = new MessageFlow(m.From, new FlowObject { Handler = roosterMessageFlow });
                     return roosterMessageFlow.DefaultReply(m);
                 }
                 else
                 { 
                     PreferenceRegistry.GetUserPreferencesForUser(m.From).RoosterFor = k;
                     return Message(m, $"Je bent gekoppeld aan klas: {k.Name}");
                 }
             }
         return Message(m, AddingKlasFailed($"De klas {string.Join(" ", m.Arguments)} kon ik niet vinden."));
     }
 }
        private TelegramBotReply Step2(Message m)
        {
            if(m.Text == stop)
                return Message(m, "Ok, ik heb de wijzigingen doorgevoerd.");
            MessageFlow.Failed();
            bool textIgnored = TextStartsWith(m.Text, ignored);
            bool textShown = TextStartsWith(m.Text, shown);
            var userpreferences = PreferenceRegistry.GetUserPreferencesForUser(m.From);
            if (m.Text.Length > 3 && (textIgnored || textShown))
            {
                var les = m.Text.Substring(m.Text.IndexOf(' ') + 1);
                foreach (string lesName in lessen)
                {
                    if(lesName == les)
                    {
                        if (textShown)
                        {
                            userpreferences.AddIgnoredLes(lesName);
                            return Message(m, $"De les {ignored} {les} wordt niet meer getoond.", replyMarkup: KeyboardForResults(userpreferences));

                        }
                        else
                        {
                            userpreferences.RemoveIgnoredLes(lesName);
                            return Message(m, $"De les {shown} {les} wordt weer getoond.", replyMarkup: KeyboardForResults(userpreferences));
                        }
                    }
                }
            }
            return Message(m, ReplyWithInstruction("Kon de les niet vinden!"), replyMarkup: KeyboardForResults(userpreferences));
        }
 protected override TelegramBotReply HandleMessage(TelegramBot.TelegramBot bot, Message m, MessageHandlerType type)
 {
     if (IsInGame(m.From))
         return Message(m, "You're allready in a game! Leave that one first.");
     HostGame(m.From);
     return Message(m, "You are now hosting a game. People can join you with the /join command", replyMarkup: HostKeyboard);
 }
 protected async override Task<TelegramBotReply> HandleMessageAsync(TelegramBot.TelegramBot bot, Message m, MessageHandlerType type)
 {
     var docent = PreferenceRegistry.GetRoosterForUser(m.From);
     if (!m.HasArguments)
     {
         if (docent != null)
             return Message(m, "Je hebt al een docentcode opgegeven.\n\rOm deze aan te passen, typ: '/docent [docentcode]'");
         else
             return Message(m, "Geef je docentcode op zoals deze op https://roosters.windesheim.nl/ staat, bijvoorbeeld: '/docent EES01'");
     }
     else
     {
         var docentStr = string.Join("", m.Arguments).ToLower();
         foreach (Docent d in await WindesheimRoosterConvertor.GetDocentenLijst())
             if (d.Name.ToLower() == docentStr)
             {
                 var preferences = PreferenceRegistry.GetUserPreferencesForUser(m.From);
                 if (preferences.RoosterFor != null)
                 {
                     if(preferences.RoosterFor == d)
                         return Message(m, $"Je bent al gekoppeld aan de docent {d.Bold()}", userMarkup: true);
                     var roosterMessageFlow = new AddRoosterFlow(preferences, d);
                     m.From.MessageFlow = new MessageFlow(m.From, new FlowObject { Handler = roosterMessageFlow });
                     return roosterMessageFlow.DefaultReply(m);
                 }
                 else
                 {
                     preferences.RoosterFor = d;
                     return Message(m, $"Je bent gekoppeld aan de docent: {d.Bold()}");
                 }
             }
         return Message(m, $"De docentcode {string.Join(" ", m.Arguments)} kon ik niet vinden.");
     }
 }
 public TelegramBotReply Step1(Message m, MessageHandlerType type)
 {
     if (type != MessageHandlerType.Message)
         return Message(m, "You can only use text as a description.");
     Spoiler.Description = m.Text;
     return Message(m, $"Okay, what is the spoiler?", replyMarkup: ForceReply.Instance);
 }
        protected async override Task<TelegramBotReply> HandleMessageAsync(TelegramBot.TelegramBot bot, Message m, MessageHandlerType type)
        {
            if (m.Text == "Yes")
                if (IsHost)
                {
                    var byeMsg = Message(-1, "The host has quit. The game is no longer available", replyMarkup: SecretHitlerBot.DefaultKeyboard);
                    foreach (var player in game.Players)
                        if (player != user)
                        {
                            byeMsg.ChatId = player.ID;
                            await byeMsg.HandleReply(bot);
                        }
                    GameRegistry.RemoveGame(game);
                    return Message(m, "The game has ended", replyMarkup: SecretHitlerBot.DefaultKeyboard);
                }
                else
                {
                    var leaveMsg = Message(-1, $"Player {user} left. The game can't continue. The host must restart the game");
                    foreach(var player in game.Players)
                        if(player != user)
                        {
                            leaveMsg.ChatId = player.ID;
                            await leaveMsg.HandleReply(bot);
                        }
                    game.Leave(m.From);
                    return Message(m, "You have left the game", replyMarkup: SecretHitlerBot.DefaultKeyboard);
                }
            else if (m.Text == "No")
                return Message(m, "Okay, thanks for staying!", replyMarkup: IsHost ? HostMessageHandler.HostKeyboard : JoinMessageHandler.JoinedPlayerKeyboard);
            MessageFlow.Failed();
            return Message(m, "Invalid response, use the yes or no buttons", replyMarkup: LeaveMessageHandler.YesNoKeyboard);

        }
        protected async override Task<TelegramBotReply> HandleMessageAsync(TelegramBot.TelegramBot bot, Message m, MessageHandlerType type)
        {
            var roosterFor = PreferenceRegistry.GetRoosterForUser(m.From);
            var preferences = PreferenceRegistry.GetUserPreferencesForUser(m.From);
            if (roosterFor == null)
                return Message(m, "Je hebt nog geen klas of docent gekoppeld!\n\rGebruik /klas om een klas te koppelen, en /docent om een docent te koppelen.");
            var date = DateTime.Now;
            var result = await WindesheimRoosterConvertor.GetRooster(preferences, date, restrictToDate: date);
            var rooster = result.Rooster;
            if (rooster.Lessen.Count == 0)
                return Message(m, "Je hebt nu geen lessen.");
            var nu = rooster.GetLesForTime(date, preferences.GetIgnoredLessen());
            var na = rooster.GetFirstLesAfterTime(date, preferences.GetIgnoredLessen());
            if (nu == null && na == null)
                return Message(m, "Je hebt vandaag geen les meer!");
            var nuDisplay = nu == null ? "Je hebt nu geen les!" : RoosterFormatProvider.Instance.FormatLes(nu, preferences);
            var naDisplay = na == null ? "Je hebt hierna geen les!" : RoosterFormatProvider.Instance.FormatLes(na, preferences);
            return Message(m,
$@"Nu:
{nuDisplay}

Straks:
{naDisplay}");

        }
            public TelegramBotReply Step2(Message m, MessageHandlerType type)
            {
                Spoiler.Type = type;
                switch (type)
                {
                    case MessageHandlerType.Message:
                        Spoiler.Text = m.Text; break;
                    case MessageHandlerType.Sticker:
                        Spoiler.Sticker = m.Sticker; break;
                    case MessageHandlerType.Voice:
                        Spoiler.Voice = m.Voice; break;
                    case MessageHandlerType.Document:
                        Spoiler.Document = m.Document; break;
                    case MessageHandlerType.Audio:
                        Spoiler.Audio = m.Audio; break;
                    case MessageHandlerType.Location:
                        Spoiler.Location = m.Location; break;
                    case MessageHandlerType.Video:
                        Spoiler.Video = m.Video; break;
                    case MessageHandlerType.Photo:
                        Spoiler.Photo = m.Photo[m.Photo.Length - 1]; break;
                    default:
                        Spoiler.Type = MessageHandlerType.Unknown; break;
                }
                return Message(m,
$@"Okay the description is as follows:
{Spoiler.Description}

The spoiler that I'll keep secret is:
{GetDescription(Spoiler)}

Would you like to submit this to the group '{Group.Title}'", replyMarkup: keyboard);
            }
        protected override TelegramBotReply HandleMessage(TelegramBot.TelegramBot bot, Message m, MessageHandlerType type)
        {
            User u = null;
            if (!m.HasArguments)
                return Message(m, "Geen parameters");
            else
            {
                Func<string, User, bool> func = null;
                string searchString = (m.Arguments[0].Contains("@") ? m.Arguments[0].Substring(1) : m.Arguments[0]).ToLower();
                if (m.Text.Contains("@"))
                    func = HasUserUsername;
                else
                    func = HasUserName;
                foreach(var user in PreferenceRegistry.GetUsers())
                    if(func(searchString, user))
                    {
                        u = user;
                        break;
                    }
                if (u != null)
                {
                    PreferenceRegistry.RemoveUser(u);
                    UserManager.Instance.RemoveValue(u);
                    return Message(m, $"Gebruiker {u} verwijderd.");
                }
                else
                    return Message(m, "Gebruiker niet gevonden");


            }
        }
 protected async override Task<TelegramBotReply> HandleMessageAsync(TelegramBot.TelegramBot bot, Message m, MessageHandlerType type)
 {
     m.Text = m.Text.ToLower().Trim();
     if (m.Text.Length == 0)
         m.From.MessageFlow.Failed();
     else
     {
         foreach (var klas in await WindesheimRoosterConvertor.GetKlassenLijst())
             if (klas.Name.ToLower() == m.Text)
             {
                 PreferenceRegistry.GetUserPreferencesForUser(m.From).RoosterFor = klas;
                 return Message(m, $"Het is gelukt! Je bent gekoppeld aan: {klas.Name}\r\nJe kunt onderstaand toetsenbord gebruiken om je rooster met 1 klik op te vragen!\r\nGa je toch nog switchen van klas? Typ dan '/klas'.");
             }
         foreach(var docent in await WindesheimRoosterConvertor.GetDocentenLijst())
         {
             if (docent.Name.ToLower() == m.Text)
             {
                 PreferenceRegistry.GetUserPreferencesForUser(m.From).RoosterFor = docent;
                 return Message(m, $"Het is gelukt! Je bent gekoppeld aan: {docent.DisplayName}\r\nJe kunt onderstaand toetsenbord gebruiken om je rooster met 1 klik op te vragen!\r\nBen je toch aan de verkeerde docent gekoppeld? Typ dan '/docent'.");
             }
         }
     }
     m.From.MessageFlow.Failed();
     return null;
 }
 protected override TelegramBotReply HandleMessage(TelegramBot.TelegramBot bot, Message m, MessageHandlerType type)
 {
     GameRegistry.Game game;
     if (!GameRegistry.IsInGame(m.From, out game))
         return Message(m, "You are not in a game", replyMarkup: SecretHitlerBot.DefaultKeyboard);
     m.From.MessageFlow = new MessageFlow(m.From, new FlowObject { Handler = new LeaveMessageConfirm(game, m.From) });
     return Message(m, "Are you sure you want to leave?", replyMarkup: YesNoKeyboard);
 }
        protected override TelegramBotReply HandleMessage(TelegramBot.TelegramBot bot, Message m, MessageHandlerType type)
        {
            GameRegistry.Game game;
            if (!GameRegistry.IsInGame(m.From, out game))
                return Message(m, "You are not in a game.");
            return Message(m, $"Current players:\r\n - {(string.Join("\r\n - ", (IEnumerable<User>)game.Players))}");

        }
 protected async override Task<TelegramBotReply> HandleMessageAsync(TelegramBot.TelegramBot bot, Message m, MessageHandlerType type)
 {
     if (m.Chat.IsChat) return null; //Niks doen met berichten in groepschats
     if (Spoiler.Description == null)
         return Step1(m, type);
     else if (Spoiler.Type == MessageHandlerType.Unknown)
         return Step2(m, type);
     else
         return await Step3(m, bot);
 }
 protected async override Task<TelegramBotReply> HandleMessageAsync(TelegramBot.TelegramBot bot, Message m, MessageHandlerType type)
 {
     var flow = MessageFlow.CurrentObject as CustomRoosterMessageFlowObject;
     if (flow.DocentCount == 0 && flow.Klas == null)
         return await Step1(bot, m, flow);
     else if (flow.DocentCount > 1)
         return Step2(bot, m, flow);
     else
         return await Step3(bot, m, flow);
 }
 protected override TelegramBotReply HandleMessage(TelegramBot.TelegramBot bot, Message m, MessageHandlerType type)
 {
     GameRegistry.Game game;
     if (!GameRegistry.IsInGame(m.From, out game))
         return Message(m, "You are not in a game");
     if (game.Host != m.From)
         return Message(m, "Only the host has access to this command");
     var flow = new PickPlayerFlow(game, onPlayerPicked);
     m.From.MessageFlow = new MessageFlow(m.From, new FlowObject { Handler = flow });
     return Message(m, "Who may view someone's membership", replyMarkup: flow.GetKeyboard());
 }
 protected override TelegramBotReply HandleMessage(TelegramBot.TelegramBot bot, Message m, MessageHandlerType type)
 {
     GameRegistry.Game game;
     ReplyKeyboardMarkup keyboard;
     if (!GameRegistry.IsInGame(m.From, out game))
         keyboard = SecretHitlerBot.DefaultKeyboard;
     else if (game.Host == m.From)
         keyboard = HostMessageHandler.HostKeyboard;
     else
         keyboard = JoinMessageHandler.JoinedPlayerKeyboard;
     return Message(m, "Unknown command", replyMarkup: keyboard);
 }
 protected async override Task<TelegramBotReply> HandleMessageAsync(TelegramBot.TelegramBot bot, Message m, MessageHandlerType type)
 {
     foreach(var user in game.Players)
     {
         if(user.ToString() == m.Text)
         {
             var val = await onPlayerPicked(user, bot, m, game);
             if (val != null)
                 return val;
             MessageFlow.Failed();
             return Message(m, "Wrong user", replyMarkup: GetKeyboard());
         }
     }
     MessageFlow.Failed();
     return Message(m, "Wrong user", replyMarkup: GetKeyboard());
 }
 private async Task<TelegramBotReply> Step1(TelegramBot.TelegramBot bot, Message m, CustomRoosterMessageFlowObject flow)
 {
     //Step1 faalt altijd, er is altijd step 3 vereist
     MessageFlow.Failed();
     if (flow.IsDocent)
     {
         var values = m.Text.ToLower().Trim().Split(' ');
         foreach (var doc in await WindesheimRoosterConvertor.GetDocentenLijst())
         {
             string docCode = doc.Name.ToLower(), docName = doc.DisplayName.ToLower();
             bool hit = true;
             foreach(var value in values)
             {
                 if (!docCode.Contains(value) && !docName.ToLower().Contains(value))
                 {
                     hit = false;
                     break;
                 }
             }
             if (hit && flow.AddDocent(doc) > 10) //als we een hit hebben, voegen we een docent toe, als deze docent de 11e is stoppen we met toevoegen want dat zijn teveel resultaten
                 break;
         }
         var count = flow.DocentCount;
         if (count == 1)
             return Message(m, $"Ok, welk rooster wil je van '{flow.Docent}' zien?", replyMarkup: Keyboard);
         else if (count > 10)
         {
             flow.Docenten = null;
             return Message(m, "Er zijn meer dan 10 docenten gevonden die aan je zoekopdracht voldoen.\r\nJe dient iets specifieker te zijn in je vraag.", replyMarkup: ForceReply.Instance);
         }
         else if (count > 1) //count zit tussen 2 en 10
             return Message(m, "Er zijn meerdere docenten gevonden! Van welke docent wil je het rooster zien?", replyMarkup: KeyboardForDocenten(flow.Docenten));
     }
     else
     {
         var value = m.Text.ToLower().Trim();
         foreach (var klas in await WindesheimRoosterConvertor.GetKlassenLijst())
             if (klas.Name.ToLower() == value)
             {
                 flow.Klas = klas;
                 return Message(m, $"Ok, welk rooster wil je van de klas {klas} zien?", replyMarkup: Keyboard);
             }
     }
     var codeType = flow.IsDocent ? "docentcode" : "klascode";
     return Message(m, $"Het is niet gelukt! De {codeType} {m.Text} is niet gevonden!\r\nJe kunt op /annuleer tikken om te stoppen.", replyMarkup: ForceReply.Instance);
 }
 private async Task<TelegramBotReply> onPlayerPicked(User u, TelegramBot.TelegramBot bot, Message m, GameRegistry.Game game)
 {
     const string viewMembership = "is picking someone to view his/her membership";
     var flowObj = new PickPlayerFlow(game, onPickedMembershipTarget);
     if (u == m.From)
     {
         await AnnounceMessage(u, bot, viewMembership);
         m.From.MessageFlow = new MessageFlow(u, new FlowObject { Handler = flowObj });
         return Message(m, "You cheating bastard! Pick the one you would like to view the membership off.", replyMarkup: flowObj.GetKeyboard());
     }
     else
     {
         await AnnounceMessage(u, bot, viewMembership);
         u.MessageFlow = new MessageFlow(u, new FlowObject { Handler = flowObj });
         await Message(u.ID, "You've been chosen to view somebody's membership. Please pick one.", replyMarkup: flowObj.GetKeyboard()).HandleReply(bot);
     }
     return Message(m, $"You have chosen {u.Bold()} to pick a player", replyMarkup: HostMessageHandler.HostKeyboard, userMarkup: true);
 }
        protected async override Task<TelegramBotReply> HandleMessageAsync(TelegramBot.TelegramBot bot, Message m, MessageHandlerType type)
        {
            if (!m.HasArguments)
                return Message(m, "Je dient argumenten mee te geven voor een reply");
            User user = null;
            string username = null;
            if (m.Arguments[0].Contains("@"))
            {
                username = m.Arguments[0].Substring(1).ToLower();
                foreach (var u in PreferenceRegistry.GetUsers())
                    if (u.Username != null && u.Username.ToLower() == username)
                    {
                        user = u;
                        break;
                    }
            }
            else if (m.Text.Contains("[") && m.Text.Contains("]"))
            {
                username = m.Arguments[0].ToLower();
                foreach(var u in PreferenceRegistry.GetUsers())
                    if(username == u.ToString().ToLower())
                    {
                        user = u;
                        break;
                    }
            }
            else
                return Message(m, "Je moet beginnen met de username van de gebruiker: /reply @windesheimroosterbot [bericht]");
            if (user == null)
                return Message(m, $"De gebruiker @{username} is niet bekend.");
            string[] msg = new string[m.Arguments.Length - 1];
            for(var i = 1; i < m.Arguments.Length; i++)
                msg[i - 1] = m.Arguments[i];
            var temp = await Message(user.ID,
$@"Hoi!

Je hebt onlangs contact gezocht met de auteur van de bot.
Je hebt onderstaande reactie ontvangen van {m.From}:

{string.Join(" ", msg)}").HandleReply(bot);
            return Message(m, $"Het bericht is verzonden naar {user}");
        }
        protected async override Task<TelegramBotReply> HandleMessageAsync(TelegramBot.TelegramBot bot, Message m, MessageHandlerType type)
        {
            if (InvocatedByMessageFlow)
            {
                var bericht = m.Text;
                var userNameDisplay = m.From.Username != null ? $" (@{m.From.Username})" : string.Empty;
                foreach (User u in bot.Admins)
                {
                    await Message(u.ID, 
$@"Beste {u},

Er is een contact verzoek ontvangen van {m.From}{userNameDisplay}.

Het bericht is als volgt:

{m.Text}").HandleReply(bot);
                }
            }
            return Message(m.From.ID, "Je bericht is verzonden!");
        }
            public async Task<TelegramBotReply> Step3(Message m, TelegramBot.TelegramBot bot)
            {
                switch (m.Text)
                {
                    case optionYes:
                        int id = DirectoryManager.Instance.AddSpoiler(Spoiler);
                        await Message(Group.ID,
$@"I just received a new spoiler from [{m.From}]:
*{Spoiler.Description}*

Would you like to see this spoiler? Click /showspoiler{id} and I'll whisper you the dirty little secret.", userMarkup: true).HandleReply(bot);
                        return Message(m, $"Your message has been sent to the group '{Group.Title}'");
                    case optionNo:
                        return Message(m, "Okay, I'll stop disturbing you now. If you want to resend a spoiler, add me to a group and use /spoiler in that group");
                    case optionEdit:
                        Spoiler = new Spoiler { ChatId = Group.ID };
                        return Message(m, $"Okay, let's try that again then. What is the description of the spoiler, you know, the part that's publically visible!");
                    default:
                        return Message(m, "Woops something went wrong, make sure you use the buttons on the keyboard!", replyMarkup: keyboard);
                }
            }
 protected override TelegramBotReply HandleMessage(TelegramBot.TelegramBot bot, Message m, MessageHandlerType type)
 {
     if (IsInGame(m.From))
         return Message(m, "You're allready in a game");
     bool gameAvailable = false;
     var games = GetGames();
     foreach(Game game in games)
         if (!game.Playing)
         {
             gameAvailable = true;
             break;
         }
     if (gameAvailable)
     {
         var flow = new JoinMessageFlow(GetGames());
         m.From.MessageFlow = new MessageFlow(m.From, new FlowObject { Handler = flow });
         return flow.UserMessage(m);
     }
     else
         return Message(m, "There are currently no games available");
 }
        public async Task<TelegramBotReply> DoNext(TelegramBot bot, Message m, MessageHandlerType type)
        {

            if (!HasNext)
                return null;
            else
            {
                CurrentObject = _flow[Position++];
                if (!CurrentObject.RequiresSlash && m.Text != null)
                    m.Arguments = m.Text.Split(' ');
                _cancelled = false;
                _canCancel = true;
                CurrentObject.Handler.MessageFlow = this;
                TelegramBotReply reply = await CurrentObject.Handler.HandleMessages(bot, m, type);
                _canCancel = false;
                if (_cancelled)
                {
                    if (CurrentObject.HasFailedMessage)
                    {
                        CurrentObject.FailedMessage.ChatId = m.Chat.ID;
                        return CurrentObject.FailedMessage;
                    }
                    else
                        return reply;
                }
                else
                {
                    CurrentObject.Handler.MessageFlow = null;
                    if (!HasNext && _user.MessageFlow == this)
                        _user.MessageFlow = null;
                    if (reply == null || CurrentObject.ReturnDefaultMessage)
                        return reply;
                    else
                    {
                        CurrentObject.CustomMessage.ChatId = m.Chat.ID;
                        return CurrentObject.CustomMessage;
                    }
                }
            }
        }
        protected async override Task<TelegramBotReply> HandleMessageAsync(TelegramBot.TelegramBot bot, Message m, MessageHandlerType type)
        {
            int id;
            if (!int.TryParse(m.Text.Substring(0, m.Text.IndexOf(')')), out id) || id >= games.Length)
            {
                MessageFlow.Failed();

                return Message(m, "Invalid reply, please use the keyboard!", replyMarkup: keyboard);
            }
            else
            {
                int joinResponse = JoinGame(games[id].Host, m.From);
                if(joinResponse != JOIN_SUCCESS)
                {
                    string msg = null;
                    switch (joinResponse)
                    {
                        case JOIN_ALLREADYJOINED:
                            msg = "You allready joined this game!"; break;
                        case JOIN_HOSTNOTFOUND:
                            msg = "Host not found"; break;
                        case JOIN_JOINISHOST:
                            msg = "You are allready hosting a game"; break;
                        case JOIN_PARTYFULL:
                            msg = "This party is full"; break;
                    }
                    return Message(m, msg ?? "Unknown error at joining the game");
                }
            }
            var joinMsg = Message(-1, $"{m.From} has joined the game");
            foreach(var player in games[id].Players)
            {
                if(player != m.From)
                {
                    joinMsg.ChatId = player.ID;
                    await joinMsg.HandleReply(bot);
                }
            }
            return Message(m, $"Successfuly joined the game from: {games[id].Host}", replyMarkup: JoinMessageHandler.JoinedPlayerKeyboard);
        }
 private MessageHandlerType GetMessageType(Message m)
 {
     if (m.Sticker != null)
         return MessageHandlerType.Sticker;
     else if (m.Document != null)
         return MessageHandlerType.Document;
     else if (m.Video != null)
         return MessageHandlerType.Video;
     else if (m.Audio != null)
         return MessageHandlerType.Audio;
     else if (m.Contact != null)
         return MessageHandlerType.Contact;
     else if (m.Location != null)
         return MessageHandlerType.Location;
     else if (m.Voice != null)
         return MessageHandlerType.Voice;
     else if (m.Text != null)
         return MessageHandlerType.Message;
     else if (m.Photo != null)
         return MessageHandlerType.Photo;
     return MessageHandlerType.Unknown;
 }
        protected override TelegramBotReply HandleMessage(TelegramBot.TelegramBot bot, Message m, MessageHandlerType type)
        {
            return Message(m,
@"/rooster - Haalt het rooster van vandaag op. In weekenden van de hieropvolgende komende week
/vandaag - Haalt het rooster van vandaag op
/morgen - Haalt het rooster van morgen op
/volgendeweek - Haalt het rooster van de volgende week op. In weekenden haalt hij het rooster voor over 2 weken op
/nu - Haalt de huidige en eerstvolgende les op
/klas - Pas de klas aan waaraan je gekoppeld bent
/docent - Pas de docent aan waaraan je gekoppeld bent
/klasrooster - Haal het rooster op voor een klas waar je niet aan gekoppeld bent
/docentrooster - Haal het rooster op van een docent waar je niet aan gekoppeld bent
/instellingen - Pas gebruikersinstellingen aan
/afmelden - Meld je af voor de bot
/annuleer - Annuleer de huidige operatie.
/contact - Toon contactgegevens
/nieuwbericht - Maak een nieuw bericht voor de auteur van deze bot
/help - Toont hulp voor de bot

Op zaterdagen en zondagen wordt het rooster voor de aankomende week getoond.
Het /volgendeweek commando laat dan van de hieropvolgende week het rooster zien.");
        }
 internal async Task HandleMessage(TelegramBot bot, Message m)
 {
     try
     {
         ProcessedRequestCount++;
         bot.PrintNotification($"Handling message '{m.Text}' from '{m.From}'");
         MessageHandlerResult result = await SendMessageToHandler(bot, m, GetMessageType(m));
         if (result.Success && result.Reply != null && result.Reply.ReplyMarkup == null)
             result.Reply.ReplyMarkup = bot.DefaultMarkup;
         if (result.Reply != null)
             if (result.Reply.ChatId < 0)
                 Console.WriteLine($"Reply received for debug account {result.Reply.ChatId}: {result.Reply}");
             else
                 await result.Reply.HandleReply(bot);
     }
     catch (Exception ex)
     {
         bot.PrintError("Er is iets fout gegaan bij het verzoek.");
         bot.PrintError(ex.Message);
         bot.PrintError(ex.StackTrace);
     }
 }
        protected override TelegramBotReply HandleMessage(TelegramBot.TelegramBot bot, Message m, MessageHandlerType type)
        {
            var roosterFor = PreferenceRegistry.GetRoosterForUser(m.From);
            if (roosterFor == null)
            {
                m.From.MessageFlow = new MessageFlow(m.From, new FlowObject
                {
                    Handler = _responseHandler,
                    RequiresSlash = false,
                    FailedMessage = _failedMessage
                });
                return Message(m,
@"Welkom bij de Windesheim Rooster bot!
Je hebt bijna toegang tot de makkelijkste manier om je Windesheim rooster te checken!
Nu moet je alleen nog even je klas of docentcode invullen:"
                , replyMarkup: ForceReply.Instance);
            }
            else
                return Message(m,
$@"Leuk dat je weer terug bent bij de bot!
Je hebt eerder gebruik gemaakt van de bot, en je staat geregistreerd voor: {roosterFor}.
Als je dit wilt veranderen kun je '/klas' typen."
            );
        }