Inheritance: ReplyFactory
        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 async override Task<HttpResponseMessage> SendReply(TelegramBot bot)
 {
     if(Text.Length >= 4000)
     {
         var newlineLength = Environment.NewLine.Length;
         var split = 4000;
         for(; split >= 0; split--)
         {
             if (Text.Substring(split, newlineLength) == Environment.NewLine)
                 break;
         }
         var left = new ReplyMessage(ChatId, Text.Substring(0, split)) { DisableWebPagePreview = DisableWebPagePreview, ReplyMarkup = ReplyMarkup, ReplyToMessageID = ReplyToMessageID, UserMarkup = UserMarkup };
         var right = new ReplyMessage(ChatId, Text.Substring(split + 1)){ DisableWebPagePreview = DisableWebPagePreview, ReplyMarkup = ReplyMarkup, ReplyToMessageID = ReplyToMessageID, UserMarkup = UserMarkup };
         await left.SendReply(bot);
         return await right.SendReply(bot);
     }
     else
     {
         var fields = GetDefaultResponse();
         fields.Add(new KeyValuePair<string, string>("text", Text));
         if (DisableWebPagePreview)
             fields.Add(new KeyValuePair<string, string>("disable_web_page_preview", true.ToString()));
         if (UserMarkup)
             fields.Add(new KeyValuePair<string, string>("parse_mode", "HTML"));
         return await bot.HttpClient.PostAsync(bot.SendMessageLoc, new FormUrlEncodedContent(fields));
     }
 }
 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."));
     }
 }
 protected async override Task<HttpResponseMessage> SendReply(TelegramBot bot)
 {
     var content = GetDefaultResponse();
     content.Add(new KeyValuePair<string, string>("latitude", Latitude));
     content.Add(new KeyValuePair<string, string>("longitude", Longitude));
     return await bot.HttpClient.PostAsync(bot.SendLocationLoc, new FormUrlEncodedContent(content));
 }
        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 NoContactHandler(TelegramBotReply reply, Chat originalGroup, User u, TelegramBot.TelegramBot bot)
 {
     reply.OnMessageNotSent += OnMessageNotSent;
     this.originalGroup = originalGroup;
     user = u;
     this.bot = bot;
 }
        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 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.");
     }
 }
 protected override async Task<HttpResponseMessage> SendReply(TelegramBot bot)
 {
     ReplyToMessageID = -1;  //enforce not being able to reply, not supported with statusses
     ReplyMarkup = null;     //enforce replymarkups aswell, not supported.
     var content = GetDefaultResponse();
     content.Add(new KeyValuePair<string, string>("action", _action.ToString()));
     return await bot.HttpClient.PostAsync(bot.SendChatActionLoc, new FormUrlEncodedContent(content));
 }
 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 override async Task<HttpResponseMessage> SendReply(TelegramBot bot)
 {
     using(var multipart = GetDefaultResponseMultipart("photo"))
     {
         if (Caption != null)
             multipart.Add(new StringContent(Caption), "caption");
         return await bot.HttpClient.PostAsync(bot.SendPhotoLoc, multipart);
     }
 }
 internal static void Start(TelegramBot bot)
 {
     if (!hasStarted)
     {
         TelegramConsole.bot = bot;
         worker = new Thread(new ThreadStart(WaitForInput));
         worker.Start();
     }
 }
 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 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);
 }
 private async Task AnnounceMessage(User u, TelegramBot.TelegramBot bot, string message)
 {
     GameRegistry.Game game;
     GameRegistry.IsInGame(u, out game);
     var msg = Message(-1, $"{u.Bold()} {message}", userMarkup: true);
     foreach(var user in game.Players)
     {
         msg.ChatId = user.ID;
         await msg.HandleReply(bot);
     }
 }
 protected override async Task<HttpResponseMessage> SendReply(TelegramBot bot)
 {
     using(var content = GetDefaultResponseMultipart("video"))
     {
         if (Duration != -1)
             content.Add(new StringContent(Duration.ToString()), "duration");
         if (Caption != null)
             content.Add(new StringContent(Caption), "caption");
         return await bot.HttpClient.PostAsync(bot.SendVideoLoc, content);
     }
 }
 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 override async Task<HttpResponseMessage> SendReply(TelegramBot bot)
 {
     using (var multipartFormDataContent = GetDefaultResponseMultipart("audio"))
     {
         if (Performer != null)
             multipartFormDataContent.Add(new StringContent(Performer), "performer");
         if(Title != null)
             multipartFormDataContent.Add(new StringContent(Title), "title");
         if(Duration != -1)
             multipartFormDataContent.Add(new StringContent(Duration.ToString()), "duration");
         return await bot.HttpClient.PostAsync(bot.SendAudioLoc, multipartFormDataContent);
     }
 }
        internal async Task GetInlineMessageResult(InlineQuery query, TelegramBot bot)
        {
            await HandleInlineMessage(query, bot);
            var jsonEncodeResult = JsonConvert.SerializeObject(results);
            var keyPairs = new KeyValuePair<string, string>[] {
                new KeyValuePair<string, string>("inline_query_id", query.ID),
                new KeyValuePair<string, string>("results", jsonEncodeResult),
                new KeyValuePair<string, string>("is_personal", true.ToString()),
                new KeyValuePair<string, string>("cache_time", "0")
            };
            var reply = await bot.HttpClient.PostAsync(bot.AnswerInlineLoc, new FormUrlEncodedContent(keyPairs));

        }
 public virtual async Task<Message> HandleReply(TelegramBot bot)
 {
     HttpResponseMessage response = await SendReply(bot);
     if (response.StatusCode == HttpStatusCode.OK)
     {
         var obj = JsonConvert.DeserializeObject<ReplyFromTelegram<Message>>(await response.Content.ReadAsStringAsync());
         if (!obj.Ok)
             return null;
         return obj.Result;
     }
     else
     {
         OnMessageNotSent?.Invoke(response, this);
         return null;
     }
 }
 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!");
        }
 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");
 }