private void BotOnOnCallbackQuery(object sender, CallbackQueryEventArgs callbackQueryEventArgs)
        {
            var query   = callbackQueryEventArgs.CallbackQuery;
            var trigger = query.Data.Split('|')[0];
            var args    = query.Data.Replace(trigger + "|", "");
            var user    = UserHelper.GetTelegramUser(Db, LoadedSetting.TelegramDefaultAdminUserId, cbQuery: query);


            //extract the trigger


            if (user.Grounded)
            {
                return;
            }
            Log.WriteLine(query.From.FirstName, LogLevel.Info, ConsoleColor.Cyan, "telegram.log");
            Log.WriteLine(query.Data, LogLevel.Info, ConsoleColor.White, "telegram.log");
            foreach (var callback in CallbackCommands)
            {
                if (String.Equals(callback.Key.Trigger, trigger, StringComparison.InvariantCultureIgnoreCase))
                {
                    var eArgs = new CallbackEventArgs()
                    {
                        SourceUser       = user,
                        DatabaseInstance = Db,
                        Parameters       = args,
                        Target           = query.Message.Chat.Id.ToString(),
                        Messenger        = Messenger,
                        Bot   = Bot,
                        Query = query
                    };
                    var response = callback.Value.Invoke(eArgs);
                    if (!String.IsNullOrWhiteSpace(response?.Text))
                    {
                        Send(response, query.Message, true);
                    }
                }
            }
            if (UsersWaitingAnswers.ContainsKey(query.Message.Chat.Id) && CurrentUserUpdatingObjects != null && CurrentUserUpdatingObjects.ContainsKey(query.Message.Chat.Id))
            {
                query.Message.Text = args;
                // query.Message.Type = MessageType.Text;
                var h = SurveyAnswersHandlers.FirstOrDefault(c => c.Key.Name == CurrentUserUpdatingObjects[query.Message.Chat.Id].GetType().Name);

                var customAnswerHandler = h.Value == null?SurveyAnswersHandlers.FirstOrDefault() : h;

                var response = customAnswerHandler.Value.Invoke(query.Message);
                Send(response, query.Message);
                return;
            }
        }
        internal void Handle(Update update)
        {
            try
            {
                if (update.Type == UpdateType.CallbackQuery && String.IsNullOrEmpty(update.Message.Text))
                {
                    var trigger = update.CallbackQuery.Data.Split('|')[0];
                    var args    = update.CallbackQuery.Data.Replace(trigger + "|", "");

                    update.Message.Text = args;
                }
                var msg  = (update.Message.From.Username ?? update.Message.From.FirstName) + ": " + update.Message.Text;
                var chat = update.Message.Chat.Title;
                if (String.IsNullOrWhiteSpace(chat))
                {
                    chat = "Private Message";
                }

                var user = UserHelper.GetTelegramUser(Db, LoadedSetting.TelegramDefaultAdminUserId, update);

                if (user.Grounded)
                {
                    return;
                }
                TelegramBotGroup group;
                if (update.Message.Chat.Type != ChatType.Private)
                {
                    group = GroupHelper.GetGroup(Db, update);
                    Log.WriteLine($"{update.Type} in group {group.GroupId}: {JsonConvert.SerializeObject(update)}", LogLevel.Info, ConsoleColor.Cyan, "groups.log");
                }
                Log.WriteLine(chat, LogLevel.Info, ConsoleColor.Cyan, "telegram.log");
                Log.WriteLine(msg, LogLevel.Info, ConsoleColor.White, "telegram.log");

                if (Options.ShouldApprooveNewUsers)
                {
                    if (!user.IsBotAdmin)
                    {
                        Bot.SendTextMessageAsync(update.Message.Chat, "You must be approved to use this bot, write to admin");
                        return;
                    }
                }

                foreach (var m in Modules)
                {
                    if (m.Value.GetType().IsAssignableTo(typeof(ITelegramBotCrudModule)))
                    {
                        var module = m.Value as ITelegramBotCrudModule;
                        if (module == null)
                        {
                            Log.WriteLine($"Can not cast module {m.Key.Name} to ITelegramBotCrudModule ");
                            continue;
                        }

                        if (module.IsCurrentUserSubmitsEntityFieldValue(user.Id))
                        {
                            if (update.Message.Text.StartsWith("!") || update.Message.Text.StartsWith("/"))
                            {
                                Send(new MessageSentEventArgs()
                                {
                                    Target   = user.UserId.ToString(),
                                    Response = new CommandResponse("Operation aborted due to new command catched")
                                });
                                module.Clear(user.Id);
                                return;
                            }
                            Send(new MessageSentEventArgs()
                            {
                                Target   = user.UserId.ToString(),
                                Response = module.SubmitValue(user.Id, update.Message.Text)
                            });
                            return;
                        }
                    }
                }



                if (UsersWaitingAnswers.ContainsKey(update.Message.Chat.Id) && UsersWaitingAnswers[update.Message.Chat.Id].Count > 0)
                {
                    if (!SurveyAnswersHandlers.Any())
                    {
                        Send(new MessageSentEventArgs()
                        {
                            Target = LoadedSetting.TelegramDefaultAdminUserId.ToString(), Response = new CommandResponse($"Here is any answer handlers for \n{JsonConvert.SerializeObject(UsersWaitingAnswers[update.Message.Chat.Id])}")
                        });
                        return;
                    }
                    if (SurveyAnswersHandlers.Any(c => c.Key.Name == CurrentUserUpdatingObjects[update.Message.Chat.Id].GetType().Name))
                    {
                        if (update.Type == UpdateType.CallbackQuery && String.IsNullOrEmpty(update.Message.Text))
                        {
                            var trigger = update.CallbackQuery.Data.Split('|')[0];
                            var args    = update.CallbackQuery.Data.Replace(trigger + "|", "");
                            update.Message.Text = args;
                        }
                        var customAnswerHandler = SurveyAnswersHandlers.FirstOrDefault(c => c.Key.Name == CurrentUserUpdatingObjects[update.Message.Chat.Id].GetType().Name);
                        var response            = customAnswerHandler.Value.Invoke(update.Message);
                        Send(response, update.Message);
                    }
                    else
                    {
                        var customAnswerHandler = SurveyAnswersHandlers.FirstOrDefault();
                        var response            = customAnswerHandler.Value.Invoke(update.Message);
                        Send(response, update.Message);
                    }
                    return;
                }
                if ((update.Message?.Text ?? "").StartsWith("!") || (update.Message?.Text ?? "").StartsWith("/"))
                {
                    var args = GetParameters(update.Message.Text);
                    foreach (var command in Commands)
                    {
                        if (command.Key.Triggers.Contains(args[0].ToLower()))
                        {
                            //check for access
                            var att = command.Key;
                            if (att.DevOnly &&
                                update.Message.From.Id != LoadedSetting.TelegramDefaultAdminUserId)
                            {
                                Send(new CommandResponse("You are not the developer!"), update);
                                return;
                            }
                            if (att.BotAdminOnly & !user.IsBotAdmin & LoadedSetting.TelegramDefaultAdminUserId != update.Message.From.Id)
                            {
                                Send(new CommandResponse("You are not a bot admin!"), update);
                                return;
                            }
                            if (att.GroupAdminOnly)
                            {
                                if (update.Message.Chat.Type == ChatType.Private)
                                {
                                    Send(new CommandResponse("You need to run this in a group"), update);
                                    return;
                                }
                                //is the user an admin of the group?
                                var status =
                                    Bot.GetChatMemberAsync(update.Message.Chat.Id, update.Message.From.Id)
                                    .Result.Status;
                                if (status != ChatMemberStatus.Administrator && status != ChatMemberStatus.Creator)
                                {
                                    Send(new CommandResponse("You are not a group admin!"), update);
                                    return;
                                }
                            }
                            if (att.InGroupOnly && update.Message.Chat.Type == ChatType.Private)
                            {
                                Send(new CommandResponse("You need to run this in a group"), update);
                                return;
                            }
                            if (att.InPrivateOnly)
                            {
                                Send(new CommandResponse("You need to run this in private"), update);
                                return;
                            }
                            var eArgs = new CommandEventArgs
                            {
                                SourceUser = user,

                                Parameters = args[1],
                                Target     = update.Message.Chat.Id.ToString(),
                                Messenger  = Messenger,
                                Bot        = Bot,
                                Message    = update.Message
                            };
                            var response = command.Value.Invoke(eArgs);
                            if (!String.IsNullOrWhiteSpace(response.Text))
                            {
                                Send(response, update);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Log.WriteLine("Exception happend at handling update:\n" + ex.ToString(), LogLevel.Error, ConsoleColor.Cyan, "error.log");
            }
        }