Example #1
0
        public void LoadKeyboards(BaseChat chat)
        {
            //клавиатура с наивысшим приоритетом, коорая обновляется при каждой отправке сообщения ботом
            var keyboard = chat.BaseKeyboard = new Keyboard(null)
            {
                Id = "main_keyboard"
            };

            keyboard.Add(new KeyboardTextButton("Menu", (c, u, b, p) => c.SendKeyboardAsync("menu")));

            //вспомогательное меню с привязкой по Id
            var childKeyboard = new Keyboard("Menu opened")
            {
                Id = "menu", InMessage = true
            };

            childKeyboard.Add(new KeyboardTextButton("Test1", (c, u, b, p) => c.SendMessageAsync("test1!"))
            {
                Color = ButtonColor.Red
            });
            childKeyboard.Add(new KeyboardTextButton("Test2", (c, u, b, p) => c.SendMessageAsync("test2!"))
            {
                Color = ButtonColor.Red
            });
            chat.AddKeyboard(childKeyboard);

            //обработчик стандартной кнопки Начать
            chat.AddKeyboard(new StartKeyboard((c, u, b, p) => c.SendMessageAsync("start")));
        }
Example #2
0
        public async Task <bool> SendMessageEventAnswerAsync(EventId eventId, long userId, long peerId, EventData eventData)
        {
            try
            {
                string _eventId;
                lock (eventId)
                {
                    if (string.IsNullOrEmpty(eventId))
                    {
                        return(false);
                    }

                    _eventId = eventId;
                    eventId.Clear();
                }

                return(await VkApi.Messages.SendMessageEventAnswerAsync(_eventId, userId, peerId, eventData));
            }
            catch (ConversationAccessDeniedException e)
            {
                if (!BaseChat.IsUserConversation(peerId))
                {
                    VkApi.GetChat <Chat>(peerId).OnKick(null);
                    return(false);
                }
                throw e;
            }
        }
Example #3
0
        private bool UseCommand(User user, string message, BaseChat chat, Message messageData)
        {
            var starts = CommandStarts.Select(s => Regex.Escape(s)).ToList();

            foreach (var start in starts.ToArray())
            {
                starts.Add($@"\[(public|club){VkApi.GroupId}\|[\S\s]{{1,}}](,|) {start}");
            }

            string regStart = @"\A(" + string.Join('|', starts) + @")";

            message = Regex.Match(message, regStart + @"[\S\s]{1,}", RegexOptions.IgnoreCase).Value;

            if (!string.IsNullOrEmpty(message))
            {
                try
                {
                    message = Regex.Replace(message.Replace("ё", "е"), regStart, "", RegexOptions.IgnoreCase);

                    VkApi.Core.PluginManager.HandleCommand(user, chat, message, messageData);
                    return(true);
                }
                catch (Exception e)
                {
                    chat.SendMessageAsync("Команда задана неверно!");
                    VkApi.Core.Log.Error(e.ToString());
                }
            }
            return(false);
        }
Example #4
0
 public virtual void OnButtonClick(BaseChat chat, User user, string message, KeyboardButtonPayload payload, Message messageData)
 {
     if (!OnButtonClick(new ButtonClickEventArgs(chat, user, message, payload, messageData)))
     {
         return;
     }
     chat.InvokeButton(user, payload);
 }
Example #5
0
 public virtual void OnButtonClick(BaseChat chat, User user, KeyboardButtonPayload payload)
 {
     if (!OnButtonClick(new ButtonClickEventArgs(chat, user, payload)))
     {
         return;
     }
     chat.InvokeButton(user, payload);
 }
Example #6
0
 public CommandContext(BotCore core, User sender, BaseChat chat, Message messageData, MethodInfo command)
 {
     Core        = core;
     Sender      = sender;
     Chat        = chat;
     MessageData = messageData;
     Command     = command;
 }
Example #7
0
        public object HandleCommand(User user, BaseChat chat, string cmdline, Message messageData)
        {
            var    split       = Regex.Split(cmdline, "(?<=^[^\"]*(?:\"[^\"]*\"[^\"]*)*) (?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)");
            string commandName = split[0].ToLower();

            string[] arguments = split.Skip(1).ToArray();

            Command command = null;

            command = GetCommand(commandName, chat.VkApi.GroupId);

            bool showErrorLine = Core.Configuration.GetValue("Config:Plugins:Commands:ShowErrorLine", true);

            if (command == null)
            {
                //Log.Warn($"Found no command {commandName}");
                if (showErrorLine)
                {
                    chat.SendMessageAsync($"[❗] Неизвестная команда \"/{commandName}\"! Полный список команд /help");
                }
                return(null);
            }

            var overloads = PermittedOverloads(command.Overloads.Values.OrderByDescending(o => o.Method.GetParameters().Length), user, chat as Chat);

            foreach (var overload in overloads)
            {
                try
                {
                    MethodInfo method = overload.Method;

                    if (!IsAvailable(method, chat.VkApi.GroupId) || !CorrectlyUsage(method, chat))
                    {
                        continue;
                    }

                    if (ExecuteCommand(method, user, chat, arguments, messageData, out object retVal))
                    {
                        return(retVal);
                    }
                }
                catch (Exception e)
                {
                    Core.Log.Error(chat, e.ToString());
                    continue;
                }
                Core.Log.Debug("No result from execution");
            }
            if (showErrorLine)
            {
                chat.SendMessageAsync("[❗] Неверный синтаксис команды! /help чтобы посмотреть полный список команд");
            }

            return(null);
        }
Example #8
0
        internal bool CorrectlyUsage(MethodInfo method, BaseChat chat)
        {
            var usage = _pluginCommands[method].Usage;

            if (usage == CommandUsage.Everywhere)
            {
                return(true);
            }

            return((usage == CommandUsage.Conversation) == chat.IsConversation);
        }
Example #9
0
 /// <summary>
 /// Инициализирует новый диалог.
 /// </summary>
 public BaseChat GetChat(long peerId)
 {
     return(_chatsCache.GetOrAdd(peerId, _peerId =>
     {
         BaseChat chat = GetNewChat?.Invoke(this, _peerId) ?? (BaseChat.IsUserConversation(_peerId) ? (BaseChat) new Conversation(this, _peerId) : new Chat(this, _peerId));
         Core.VkApi.OnChatCreated(new ChatEventArgs(chat));
         if (Core.VkApi != this)
         {
             OnChatCreated(new ChatEventArgs(chat));
         }
         return chat;
     }));
 }
Example #10
0
 public async Task SendMessageAsync(MessagesSendParams message)
 {
     try
     {
         await VkApi.Messages.SendAsync(message);
     }
     catch (Exception e)
     {
         long peerId = message.PeerId.Value;
         if (!BaseChat.IsUserConversation(peerId))
         {
             VkApi.GetChat <Chat>(peerId).OnKick(null);
         }
         throw e;
     }
 }
Example #11
0
 public void SendMessage(MessagesSendParams message)
 {
     try
     {
         VkApi.Messages.Send(message);
     }
     catch (ConversationAccessDeniedException e)
     {
         long peerId = message.PeerId.Value;
         if (!BaseChat.IsUserConversation(peerId))
         {
             VkApi.GetChat <Chat>(peerId).OnKick(null);
             return;
         }
         throw e;
     }
 }
Example #12
0
 public async Task <bool> EditAsync(long peerId, long messageId, string message, Keyboard keyboard = null)
 {
     try
     {
         return(await VkApi.Messages.EditAsync(new MessageEditParams()
         {
             PeerId = peerId,
             ConversationMessageId = messageId,
             Message = message,
             Keyboard = keyboard.GetKeyboard(VkApi.GroupId)
         }));
     }
     catch (ConversationAccessDeniedException e)
     {
         if (!BaseChat.IsUserConversation(peerId))
         {
             VkApi.GetChat <Chat>(peerId).OnKick(null);
             return(false);
         }
         throw e;
     }
 }
Example #13
0
 private bool ClickButton(User user, string message, BaseChat chat, Message messageData)
 {
     if (!string.IsNullOrEmpty(messageData.Payload))
     {
         try
         {
             var payload = KeyboardButtonPayload.Deserialize(messageData.Payload);
             if (payload != null && payload.IsValid())
             {
                 if (payload.GroupId == VkApi.GroupId || payload.GroupId == 0)
                 {
                     OnButtonClick(chat, user, message, payload, messageData);
                 }
                 return(true);
             }
         }
         catch (Exception e)
         {
             VkApi.Core.Log.Error(e.ToString());
         }
     }
     return(false);
 }
Example #14
0
 internal bool ClickButton(BaseChat chat, User user, EventId eventId, string payload)
 {
     if (!string.IsNullOrEmpty(payload))
     {
         try
         {
             var _payload = KeyboardButtonPayload.Deserialize(payload);
             if (_payload != null && _payload.IsValid())
             {
                 _payload.EventId = eventId;
                 if (_payload.GroupId == VkApi.GroupId || _payload.GroupId == 0)
                 {
                     OnButtonClick(chat, user, _payload);
                 }
                 return(true);
             }
         }
         catch (Exception e)
         {
             VkApi.Core.Log.Error(e.ToString());
         }
     }
     return(false);
 }
Example #15
0
 public GetMessageEventArgs(BaseChat chat, IUser sender, string message, Message messageData) : base(chat, sender, message, messageData)
 {
 }
Example #16
0
        public virtual void OnMessage(IUser sender, string message, BaseChat chat, Message messageData)
        {
            //защита от дублированных или задержанных сообщений
            {
                long msgId = messageData.ConversationMessageId.Value;
                if (!_lastMessages.ContainsKey(chat))
                {
                    _lastMessages.Add(chat, new Queue <long>());
                }
                else
                {
                    if (_lastMessages[chat].Contains(msgId))
                    {
                        return;
                    }
                    _lastMessages[chat].Enqueue(msgId);
                    if (_lastMessages[chat].Count > 10)
                    {
                        _lastMessages[chat].Dequeue();
                    }
                }
            }
            //защита от дублированных или задержанных сообщений


            //actions
            if (messageData.Action != null && chat is Chat _chat)
            {
                if (messageData.Action.Type == MessageAction.ChatKickUser)
                {
                    //if (messageData.Action.MemberId == -VkApi.GroupId) //нет события при кике бота.
                    //	_chat.OnKick(sender);
                    //else
                    _chat.OnKickUser(VkApi.GetUser(messageData.Action.MemberId.Value), sender);
                    return;
                }
                else if (messageData.Action.Type == MessageAction.ChatInviteUser)
                {
                    if (messageData.Action.MemberId == -VkApi.GroupId)
                    {
                        _chat.Join(sender);
                    }
                    else
                    {
                        _chat.OnAddUser(VkApi.GetUser(messageData.Action.MemberId.Value), sender, false);
                    }
                    return;
                }
                else if (messageData.Action.Type == MessageAction.ChatInviteUserByLink)
                {
                    _chat.OnAddUser(sender, null, true);
                    return;
                }
            }

            if (sender is User user)
            {
                if (ClickButton(user, message, chat, messageData))
                {
                    return;
                }

                if (UseCommand(user, message, chat, messageData))
                {
                    return;
                }
            }

            if (!OnGetMessage(new GetMessageEventArgs(chat, sender, message, messageData)))
            {
                return;
            }

            chat.OnMessasge(sender, message, messageData);
        }
Example #17
0
        private bool ExecuteCommand(MethodInfo method, User user, BaseChat chat, string[] args, Message messageData, out object result)
        {
            Core.Log.Info($"Execute command {method}");

            result = new object();
            CommandContext context = new CommandContext(Core, user, chat, messageData, method);

            var parameters = method.GetParameters();

            int addLenght = 0;

            if (parameters.Length > 0 && typeof(CommandContext).IsAssignableFrom(parameters[0].ParameterType))
            {
                addLenght = 1;
            }

            object[] objectArgs = new object[parameters.Length];

            try
            {
                int i = 0;
                for (int k = 0; k < parameters.Length; k++)
                {
                    var parameter = parameters[k];
                    if (k == 0 && addLenght == 1)
                    {
                        if (typeof(CommandContext).IsAssignableFrom(parameter.ParameterType))
                        {
                            objectArgs[k] = context;
                            continue;
                        }
                        Core.Log.Warn(chat, $"Command method {method.Name} missing Player as first argument.");
                        return(false);
                    }

                    bool isStringParam = IsParams(parameter) && parameter.ParameterType == typeof(string[]);

                    if ((parameter.IsOptional || isStringParam) && args.Length <= i)
                    {
                        if (isStringParam)
                        {
                            objectArgs[k] = new string[0];
                        }
                        else
                        {
                            objectArgs[k] = parameter.DefaultValue;
                        }
                        continue;
                    }

                    if (args.Length < k && !isStringParam)
                    {
                        Core.Log.Debug(chat, $"No math {k} arguments");
                        return(false);
                    }

                    if (typeof(IParameterSerializer).IsAssignableFrom(parameter.ParameterType))
                    {
                        var ctor = parameter.ParameterType.GetConstructor(Type.EmptyTypes);
                        IParameterSerializer defaultValue = ctor.Invoke(null) as IParameterSerializer;
                        defaultValue?.Deserialize(user, args[i++]);

                        objectArgs[k] = defaultValue;

                        continue;
                    }

                    if (typeof(IUser).IsAssignableFrom(parameter.ParameterType))
                    {
                        long   id;
                        string _id = Regex.Match(args[i++].Split(' ', '|').First(), @"(club|public|id)[0-9]*").Value;
                        _id = Regex.Replace(_id.Replace("id", ""), @"(club|public)", "-");
                        if (!long.TryParse(_id, out id))
                        {
                            return(false);
                        }
                        var _user = user.VkApi.GetUser(id);
                        if (!parameter.ParameterType.IsAssignableFrom(_user.GetType()) && !_user.GetType().IsAssignableFrom(parameter.ParameterType))
                        {
                            return(false);
                        }
                        objectArgs[k] = _user;
                        continue;
                    }

                    if (parameter.ParameterType == typeof(string))
                    {
                        objectArgs[k] = args[i++];
                        continue;
                    }
                    if (parameter.ParameterType == typeof(byte))
                    {
                        byte value;
                        if (!byte.TryParse(args[i++], out value))
                        {
                            return(false);
                        }
                        objectArgs[k] = value;
                        continue;
                    }
                    if (parameter.ParameterType == typeof(short))
                    {
                        short value;
                        if (!short.TryParse(args[i++], out value))
                        {
                            return(false);
                        }
                        objectArgs[k] = value;
                        continue;
                    }
                    if (parameter.ParameterType == typeof(int))
                    {
                        int value;
                        if (!int.TryParse(args[i++], out value))
                        {
                            return(false);
                        }
                        objectArgs[k] = value;
                        continue;
                    }
                    if (parameter.ParameterType == typeof(long))
                    {
                        long value;
                        if (!long.TryParse(args[i++], out value))
                        {
                            return(false);
                        }
                        objectArgs[k] = value;
                        continue;
                    }
                    if (parameter.ParameterType == typeof(bool))
                    {
                        bool value;
                        if (!bool.TryParse(args[i++], out value))
                        {
                            return(false);
                        }
                        objectArgs[k] = value;
                        continue;
                    }
                    if (parameter.ParameterType == typeof(float))
                    {
                        float value;
                        if (!float.TryParse(args[i++], out value))
                        {
                            return(false);
                        }
                        objectArgs[k] = value;
                        continue;
                    }
                    if (parameter.ParameterType == typeof(double))
                    {
                        double value;
                        if (!double.TryParse(args[i++], out value))
                        {
                            return(false);
                        }
                        objectArgs[k] = value;
                        continue;
                    }
                    if (parameter.ParameterType.IsEnum)
                    {
                        string val = args[i++];

                        if (long.TryParse(val, out _) || !Enum.TryParse(parameter.ParameterType, val, true, out object value) || value as Enum == null)
                        {
                            Core.Log.Warn($"Could not convert to valid enum value: {val}");
                            return(false);
                        }

                        objectArgs[k] = value;
                        continue;
                    }

                    if (isStringParam)
                    {
                        List <string> strings = new List <string>();
                        for (; i < args.Length; i++)
                        {
                            strings.Add(args[i]);
                        }
                        objectArgs[k] = strings.ToArray();
                        continue;
                    }

                    return(false);
                }

                if (i < args.Length)
                {
                    return(false);
                }
            }
            catch (Exception e)
            {
                //if (Log.IsDebugEnabled)
                //{
                //	Log.Error("Trying to execute command overload", e);
                //}
                //chat.SendMessage(e);
                Core.Log.Error(chat, e.ToString());

                return(false);
            }

            try
            {
                object pluginInstance = _plugins.FirstOrDefault(plugin => method.DeclaringType.IsInstanceOfType(plugin)) ?? method.DeclaringType;
                if (pluginInstance == null)
                {
                    return(false);
                }

                if (!OnCommandExecute(new CommandEventArgs(chat, user, messageData.Text, method, args, messageData)))
                {
                    return(true);
                }

                ICommandFilter filter = pluginInstance as ICommandFilter;
                if (filter != null)
                {
                    filter.OnCommandExecuting(user);
                }

                if (method.IsStatic)
                {
                    result = method.Invoke(null, objectArgs);
                }
                else
                {
                    if (method.DeclaringType == null)
                    {
                        return(false);
                    }

                    Plugin.CurrentContext = context;                  // Setting thread local for call
                    result = method.Invoke(pluginInstance, objectArgs);
                    Plugin.CurrentContext = null;                     // Done with thread local, we using pool to make sure it's reset.
                }

                if (filter != null)
                {
                    filter.OnCommandExecuted();
                }

                return(true);
            }
            catch (Exception e)
            {
                Core.Log.Error(chat, e.ToString());
                //Log.Error($"Error while executing command {method}", e);
                //chat.SendMessage(e);
            }

            return(false);
        }
Example #18
0
 public CommandEventArgs(BaseChat chat, User sender, string message, MethodInfo command, string[] args, Message messageData) : base(chat, sender, message, messageData)
 {
     Command = command;
     Args    = args;
 }
Example #19
0
 public ChatEventArgs(BaseChat chat)
 {
     Chat = chat;
 }
Example #20
0
        public IActionResult Callback([FromBody] Updates updates)
        {
            try
            {
                if (updates.SecretKey != _secretKey)
                {
                    return(BadRequest("Secret key is incorrect!"));
                }

                if (updates.Type == CallbackReceive.Confirmation)
                {
                    return(Ok(Core.Configuration.GetValue($"Config:Groups:{updates.GroupId}:Confirmation", Core.Configuration["Config:Confirmation"])));
                }

                new Thread(() =>
                {
                    Stopwatch stopwatch = new Stopwatch();
                    stopwatch.Start();
                    try
                    {
                        VkCoreApiBase vkApi = Core.VkApi.Get(updates.GroupId);
                        Core.PluginManager.PluginCallbackHandler(ref updates, vkApi);
                        if (updates == null)
                        {
                            return;
                        }

                        var response = new VkResponse(updates.Object);

                        var update = GroupUpdate.FromJson(response);

                        switch (updates.Type)
                        {
                        case CallbackReceive.Message.New:
                            {
                                var msg = Message.FromJson(response);

                                if (msg.Date.HasValue && (DateTime.UtcNow - msg.Date.Value).TotalSeconds > _messageResendBlockTime)
                                {
                                    return;
                                }

                                IUser user    = vkApi.GetUser(msg.FromId.Value);
                                BaseChat chat = vkApi.GetChat(msg.PeerId.Value);

                                lock (chat)
                                {
                                    vkApi.MessageHandler.OnMessage(user, msg.Text, chat, msg);
                                }
                                break;
                            }

                        case CallbackReceive.Message.Event:
                            {
                                var msgEvent = MessageEvent.FromJson(response);

                                IUser user = vkApi.GetUser(msgEvent.UserId.Value);

                                if (user is User _user)
                                {
                                    BaseChat chat = vkApi.GetChat(msgEvent.PeerId.Value);

                                    lock (chat)
                                    {
                                        vkApi.MessageHandler.ClickButton(chat, _user, new UI.EventId(msgEvent.EventId), msgEvent.Payload);
                                    }
                                }
                                break;
                            }

                        case CallbackReceive.Group.OfficersEdit:
                            {
                                var msgEvent = GroupOfficersEdit.FromJson(response);

                                var userId = msgEvent.UserId.Value;

                                vkApi.Group.Managers.Remove(userId);

                                var level = (int)msgEvent.LevelNew.Value;

                                if (level > 0)
                                {
                                    var permissionLevel = (int)Math.Pow(10, level + 1);
                                    vkApi.Group.Managers.Add(userId, (UserPermission)level);
                                }
                                break;
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        Core.Log.Error(e.ToString());
                    }
                    Core.Log.Debug(stopwatch.ElapsedMilliseconds.ToString());
                    stopwatch.Stop();
                })
                {
                    IsBackground = true
                }.Start();
            }
Example #21
0
 public ButtonClickEventArgs(BaseChat chat, User sender, KeyboardButtonPayload payload) : base(chat, sender, null, null)
 {
     Payload = payload;
 }
Example #22
0
 public ButtonClickEventArgs(BaseChat chat, User sender, string message, KeyboardButtonPayload payload, Message messageData) : base(chat, sender, message, messageData)
 {
     Payload = payload;
 }