├── README.md ├── example ├── Bot Slada │ ├── .htaccess │ ├── Config │ │ ├── Command.php │ │ ├── Event.php │ │ ├── Manager.php │ │ └── config.ini │ ├── Controller.php │ ├── Controller │ │ ├── ControllerAdmin.php │ │ ├── ControllerEvent.php │ │ ├── ControllerGame.php │ │ ├── ControllerMain.php │ │ └── ControllerManage.php │ ├── Data │ │ ├── Help.txt │ │ ├── Help2.txt │ │ └── who.txt │ ├── File │ │ └── blackmale.jpg │ └── Models │ │ ├── Account.php │ │ ├── FunctionHandler.php │ │ ├── Logger.php │ │ ├── Utils.php │ │ └── VK │ │ ├── BotConversation.php │ │ ├── BotGet.php │ │ ├── BotMessage.php │ │ ├── BotRequest.php │ │ ├── BotUploader.php │ │ ├── BotWall.php │ │ ├── Event.php │ │ └── Handler.php ├── Config │ └── Command.php └── Controller │ └── ControllerMain.php ├── img ├── 1.jpg ├── 2.jpg ├── 3.jpg ├── logo.png └── nameanton17.jpg ├── quick-start └── Install │ ├── Zip.php │ ├── act.php │ ├── image │ ├── 1.jpg │ ├── 2.jpg │ ├── 3.jpg │ ├── 4.jpg │ ├── 5.jpg │ └── 6.jpg │ ├── index.php │ ├── page │ ├── index.html │ └── ok.html │ └── token.txt └── src ├── .htaccess ├── Config ├── Command.php ├── Event.php ├── Manager.php ├── config.ini └── config.json ├── Controller.php ├── Controller └── ControllerTest.php ├── Log └── test_log.txt └── Models ├── FunctionHandler.php ├── Logger.php ├── Utils.php └── VK ├── BotConversation.php ├── BotGet.php ├── BotKeyboard.php ├── BotMessage.php ├── BotOnline.php ├── BotRequest.php ├── BotUploader.php ├── BotWall.php ├── Event.php └── Handler.php /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

MVC BOT

4 |

Содержание

5 |

6 | 0. Быстрый старт
7 | 1. Создание команд
8 | 2. Регистрация Event-ов
9 | 3. Дополнительно
10 | 4. Встроенный Логгер
11 | 5. Клавиатура Ботов
12 | 6. Загрузка изображений
13 | 7. Встроенные классы для работы с VK API
14 |

15 |

16 |
17 | Данная библиотека облегчает создание ботов для VK через CallBack API 18 | в несколько сотен раз
19 | Добавив ее в проект, можно создать Hello World бота за несколько секунд.
20 | Что же она может? 21 |
22 |

Быстрый старт

23 | Для тех, кому лень вписывать токен, и настраивать callback сервер вручную, я создал небольшой скрипт, делающий всю работу за вас.
24 | Переместите папку Install (из папки quick-start) в главную директорию проекта, и следуйте инструкциям на Install/index.php 25 | 26 | 27 | 28 |
29 |

Создание команд

30 | 31 | ```php 32 | Handler::Register('hello-world', function () { 33 | return 'Hello world'; 34 | }, false); 35 | ``` 36 | Как вы можете видеть в коде выше — это делается в пару строк.
37 | Вы вызываете метод Register из класса Handler в файле `/Config/Command.php`
38 |
39 | Первый аргумент — это название функции. Может быть или string, или array.
40 | Второй — это сама функция, которая вызовется в случае набора команды. Это может быть или анонимная функция, или строка
41 | Если это строка, то там указывается имя класса, и метод через @.
42 | Т.е, строка: `Hello@World`
43 | Вызовет из класса ControllerHello (который находится в файле `/Controller/ControllerHello.php` ) метод `ActionWorld`
44 | Третий аргумент — необязательный для указания параметр. Если он установлен на true, то доступ к этой команде будет возможен только через клавиатуру ботов (payload). 45 |
46 | Так-же, можно передавать аргументы:
47 | ```php 48 | Handler::Register('name', function ($name, $age) { 49 | return "Hello, {$name} ({$age} years old)"; 50 | }); 51 | ``` 52 |
53 | 54 |
55 |

Регистрация Event'ов

56 | Допустим, нам надо захватить приходящий от VK тип message_new, как это сделать?
57 | Пишем такие строчки в файле 58 | 59 | `/Config/Event.php` 60 | 61 | ```php 62 | Event::Register('message_new', function () { 63 | Handler::Run(); 64 | Logger::Info("Пришел тип message_new"); 65 | }); 66 | ``` 67 | 68 | Теперь анонимная функция (или строка) которую вы указали во втором аргументе, будет вызываться каждый раз, когда будет приходить этот тип 69 |

Дополнительно

70 |
71 | Конечно-же, это не все возможности библиотеки.
72 |

Обращения к боту


Бота можно заставить игнорировать сообщения, в которых не присутствует обращение к нему. Это делается так:
73 | 74 | ```php 75 | Handler::Appeal(true); 76 | Handler::AddAppeal('Bot'); 77 | ``` 78 | Этот код будет работать только в файле ` /Config/Command.php ` , или ` /Config/Event.php`
79 | Теперь, бот не будет отзываться на такие сообщения:
80 | name Антон 17
81 | Но, будет отзываться на:
82 | Bot name Антон 17
83 | Так-же, в первый аргумент метода AddApeal можно передать не только string, но и array.
84 | ```php 85 | Handler::AddApeal(['Бот', 'Ботец']); 86 | ``` 87 | Теперь, бот будет отзываться и на Бот, и на Ботец. 88 | 89 |

Игнор-режим

90 | Еще, бота можно заставить игнорировать сообщения, которые не начинаются с определенного символа.
91 | 92 | ```php 93 | Handler::StartsWith($bool); 94 | Handler::AddStartsWith($char); 95 | ``` 96 | 97 | $char — символ, с которого должно начинаться сообщение. Это может быть array, или string.
Т.е, такой код: 98 | 99 | ```php 100 | Handler::StartsWith(true); 101 | Handler::AddStartsWith(['/', '$']); 102 | ``` 103 | 104 | Сделает так, что вот такие обращения не будут работать:
105 | name Антон 17
106 | А такие будут:
107 | /name Антон 17
108 | $name Антон 17 109 | 110 |

Таймаут


111 | Если CALLBACK API получает в ответ что-то, помимо "ok", то оно повторит запрос через некоторое время. Обычно, через 3-4 секунды. И, если опять будет получено не "ok", то еще раз повторит.
112 | Чтобы не возникало ситуаций, когда код повторяется, мной была придумана функция SetTimeout. 113 | 114 | ```php 115 | Handler::SetTimeout($second = '*'): void 116 | ``` 117 | 118 | Данная функция устанавливает таймаут (в секундах). Если приходящий ответ пришел $second, и более секунд назад, то этот запрос будет проигнорирован
119 | Если в первый аргумент функции передать *, то это снимает ограничение по времени.
120 | Следует помещать данную функцию в файл Command.php, Manager.php, или Event.php 121 |

Строгая проверка


122 | Можно включить строгую проверку. Она будет сверять регистр функций, и обращений.
123 | 124 | Допустим, у нас есть обращение "Бот", и пользователь пишет:
125 | бот, name Антон 17
126 | При выключенной строгой проверке, это сообщение вызовет функцию name
127 | При включенной — выведет ошибку о том, что такая функция не обнаружена. 128 | 129 | Включить строгую проверку: 130 | ```php 131 | Handler::Strict(true); 132 | ``` 133 | Включение строгой проверки нужно поместить в начало файла Config/Command.php, иначе не будет работать. 134 |

Ошибки


135 | Согласитесь, неудобно писать каждый раз, при ошибке:
136 | 137 | ```php 138 | return "ОШИБКА: Неизвестный символ"; 139 | ``` 140 | 141 |
142 | Именно поэтому, я сделал такую фишку. Если в возвращаемом значении, первый символ это @, то это выведет как ошибку:
143 | 144 | ```php 145 | return "@Неизвестный символ"; 146 | ``` 147 | 148 | 149 |
Код выше, отправит сообщение пользователю такое: "ОШИБКА: Неизвестный символ"
150 | Символ можно сменить с @, на любой другой, в файле `/Config/config.ini` 151 |

Встроенный логгер

152 |
153 | В библиотеку встроен логгер. Методы логгера ниже:
154 | 155 | ```php 156 | // Создает запись в логах, с типом Default 157 | Logger::Info($message): void 158 | 159 | // Создает запись в логах, с типом Error 160 | Logger::Error($message): void 161 | 162 | // Создает запись в логах, с типом Warning 163 | Logger::Warning($message): void 164 | ``` 165 |

Клавиатура ботов

166 |
167 | 168 | Честно говоря, оригинальный синтаксис клавиатуры ботов от VK меня пугает. Он слишком запутанный, если посмотреть на него впервые.
169 | Поэтому, я сделал класс, который может создавать клавиатуру ботов. Все методы данного класса: 170 | 171 | ```php 172 | 173 | class BotKeyboard { 174 | // Данная функция переводит все следующие кнопки на новую линию 175 | public function AddLine(): void 176 | 177 | // Создает новую кнопку. 178 | public function AddButton($text, $color = 'secondary', $payLoad = []): void 179 | 180 | // Создает кнопку, которая отправляет местоположение боту 181 | public function AddLocationButton($payLoad = []): void 182 | 183 | // Создает кнопку, при нажатии на которую, совершается оплата 184 | public function AddPayButton($hash, $payLoad = []): void 185 | 186 | // Создает кнопку, при клике на которую, открывается приложение 187 | public function AddAppButton($text, $app_id, $hash = '', $owner_id = 'callback'): void 188 | 189 | // Скрывать ли клавиатуру после нажатия на кнопку 190 | public function Hide($bool = true): void 191 | 192 | // Возвращает json-клавиатуру для вк 193 | public function Build(): array|bool 194 | } 195 | 196 | ``` 197 | 198 | Давайте разбираться. $payLoad -- это скрытый параметр, который передается при нажатии на кнопку боту. Если он присутствует, библиотека MVC Bot автоматически заменяет сообщение от пользователя на данные из payLoad.
199 | Цветов бывает несколько: secondary, primary, positive, negative.
200 | Максимальный размер клавиатуры -- 4x10
201 | Пример кода:
202 | ```php 203 | 204 | $kb = new BotKeyboard(); 205 | $kb->AddButton('Подключиться к игре', 'positive', ['connect', 'random']); 206 | $kb->AddLine(); 207 | $kb->AddButton('Создать игру', 'positive', ['new', 'game']); 208 | $kb->AddLine(); 209 | $kb->AddButton('Назад', 'secondary', ['back']); 210 | $button = $kb->Build(); 211 | 212 | ``` 213 | 214 |

Загрузка изображений

215 |
216 | Пока, в библиотеке присутствует лишь один метод для загрузки изображений в сообщения на сервера VK. 217 | Как он работает? 218 | Вы, вызываете метод 219 | 220 | ```php 221 | BotUploader::Message($path, $peerID = 'callback') 222 | ``` 223 | 224 | В аргумент $path заносится путь к изображению, а в $peerID ID беседы, или человека. После чего, вам возвращаеться string с attach, которое можно прикрепить к сообщению. 225 | Пример: 226 | ```php 227 | $attach = BotUploader::Message(ROOT . '/File/test.jpg'); // Возратит photo85635407_165186811_69dff3de4372ae9b6e 228 | BotMessage::Send('Картинка', 'callback', $attach); 229 | ``` 230 | 231 |

Встроенные классы для работы с VK API

232 |
233 | В библиотеке встроены классы для работы с VK API. Список методов ниже:
234 | 235 | ```php 236 | class BotMessage { 237 | // Отсылает сообщение пользователю. Если $id равняется callback, то это отправит тому пользователю, от которого пришел callback сайту. 238 | public static function Send($message, $id = 'callback', $attach = [], $keyBoard = []): bool 239 | 240 | // Удаляет сообщение 241 | public static function Delete($messageID): bool 242 | 243 | // Если $text == false, то бот будет записывать голосовое сообщение, если true, то будет печатать сообщение 244 | public static function Activity($text = true, $peerID = 'callback'): bool 245 | 246 | // Редактирует сообщение 247 | public static function Edit($messageID, $text, $attach = [], $peerID = 'callback'): bool 248 | } 249 | 250 | class BotConversation { 251 | 252 | // Вернет true, если бот -- админ 253 | public static function IsAdmin(): bool 254 | 255 | // Возвращает имя беседы 256 | public static function GetName(): string 257 | 258 | // Возвращает ID создателя 259 | public static function GetOwnerID(): int 260 | 261 | // Возвращает ID админов 262 | public static function GetAdminsID(): array|bool 263 | 264 | // Возвращает информацию из метода messages.getConversationsById 265 | public static function GetInfo($peerID = 'callback', $fields = []): array 266 | 267 | // Удаляет пользователя из беседы 268 | public static function DeleteUser($user, $peerID = 'callback'): bool 269 | 270 | // Закрепляет сообщение 271 | public static function Pin($messageID, $peerID = 'callback'): bool 272 | 273 | // Изменяет заголовок беседы 274 | public static function Title($title, $peerID = 'callback'): bool 275 | } 276 | 277 | class BotRequest { 278 | // Вызывает метод $method из VK API и возвращает массив с результатом. 279 | public static function API($method, $data = []): array|bool 280 | 281 | // Отправляет файл на указанный URL. 282 | public static function SendPostFile($url, $data): array|bool 283 | } 284 | 285 | class BotUploader { 286 | // Загружает на сервера VK картинку, и возвращает attach этой картинки (пример -- photo85635407_165186811_69dff3de4372ae9b6e) 287 | // ДАННЫЙ МЕТОД МОЖНО ИСПОЛЬЗОВАТЬ ТОЛЬКО ДЛЯ ЗАГРУЗКИ ИЗОБРАЖЕНИЙ В ЛИЧНЫЕ СООБЩЕНИЯ 288 | public static function Message($path, $peerID = 'callback'): string 289 | } 290 | 291 | class BotGet { 292 | // Возвратит true, если запрос из беседы 293 | public static function IsConversation(): bool 294 | 295 | // Возвращает from_id 296 | public static function From(): int 297 | 298 | // Возвращает peer_id 299 | public static function Peer(): int 300 | 301 | // Возвращает сообщение пользователя 302 | public static function Message(): string 303 | 304 | // Возвращает true, если пользователь отправил PayLoad вместе с сообщением 305 | public static function HasPayLoad(): bool 306 | 307 | // Возвратит 1, если пользователь с таким id мужчина, и 0, если женщина. 308 | public static function Gender($id = 'callback'): int 309 | 310 | // Возвращает имя и фамилию пользователя. Если $lastName = false, то фамилию не будет возвращать 311 | public static function Name($lastName = true, $nameCase = 'nom', $id = 'callback'): string 312 | 313 | // Возвращает информацию о пользователях. $ids может быть массивом, и строкой. 314 | public static function Info($ids = 'callback', $fields = [], $nameCase = 'nom'): array 315 | } 316 | 317 | class BotWall { 318 | // Добавляет комментарий к посту. Если $ownerID указан как callback, то возьметься id группы бота 319 | public static function AddComment($postID, $text, $ownerID = 'callback', $attach = [], $replyTo = 0, $stickerId = 0): void 320 | 321 | // Открывает/Закрывает комментарии к посту. $type может быть только open, или close. 322 | public static function Comment($postID, $type = 'close'): void 323 | } 324 | 325 | class BotOnline { 326 | // Включает онлайн у группы 327 | public static function Online(): bool 328 | 329 | // Отключает онлайн у группы 330 | public static function Offline(): bool 331 | 332 | // Получает информацию о онлайне в группе 333 | public static function Get(): array|bool 334 | } 335 | 336 | ``` -------------------------------------------------------------------------------- /example/Bot Slada/.htaccess: -------------------------------------------------------------------------------- 1 | 2 | RewriteEngine On 3 | 4 | RewriteRule .* Controller.php 5 | -------------------------------------------------------------------------------- /example/Bot Slada/Config/Command.php: -------------------------------------------------------------------------------- 1 | $level]); 43 | return 'окей'; 44 | }); -------------------------------------------------------------------------------- /example/Bot Slada/Config/Event.php: -------------------------------------------------------------------------------- 1 | $bool])->From('conversations')->Exec(); 11 | return $bool ? 'Анти-Выход включен' : 'Анти-Выход выключен'; 12 | } 13 | 14 | function ActionKick() 15 | { 16 | $id = Utils::Join(func_get_args(), ' '); 17 | 18 | if (empty($id) && isset(VK['fwd_messages'][0])) { 19 | $id = VK['fwd_messages'][0]['from_id']; 20 | } elseif (empty($id)) { 21 | return '@Вы не указали id'; 22 | } else { 23 | $id = Account::GetID($id); 24 | if ($id == 0) { 25 | return '@Ой-ой! Я таких не знаю (('; 26 | } 27 | } 28 | 29 | $rank = Account::GetRank(); 30 | $rankKick = Account::GetRank($id); 31 | 32 | if ($rankKick >= $rank) { 33 | $name = BotGet::Name(true, 'gen', $id); 34 | 35 | return "Не удалось кикнуть @id{$id} ($name)"; 36 | } 37 | 38 | $response = BotConversation::DeleteUser($id); 39 | if ($response) { 40 | $name = BotGet::Name(true, 'nom', $id); 41 | 42 | return "Пользователь @id{$id} ($name) кикнут"; 43 | } else { 44 | $name = BotGet::Name(true, 'gen', $id); 45 | 46 | return "Не удалось кикнуть @id{$id} ($name)"; 47 | } 48 | } 49 | 50 | function ActionBan($id = 0) 51 | { 52 | if (isset(VK['fwd_messages'][0]['from_id'])) { 53 | $id = VK['fwd_messages'][0]['from_id']; 54 | $desc = Utils::Join(func_get_args(), ' '); 55 | } elseif (!empty($id)) { 56 | $desc = Utils::Join(array_slice(func_get_args(), 1), ' '); 57 | } else { 58 | return '@Нужно указать ID человека, или его имя!'; 59 | } 60 | 61 | $id = Account::GetID($id); 62 | 63 | if ($id == 0) { 64 | return '@Ой-ой! Я таких не знаю (('; 65 | } 66 | 67 | $rank = Account::GetRank(); 68 | $rankKick = Account::GetRank($id); 69 | 70 | if ($rankKick >= $rank) { 71 | $name = BotGet::Name(true, 'gen', $id); 72 | 73 | return "Не удалось забанить @id{$id} ($name)"; 74 | } 75 | 76 | $response = BotConversation::DeleteUser($id); 77 | 78 | if ($response) { 79 | Account::SetRow($id, ['ban' => 1, 'ban_desc' => $desc, 'ban_by' => BotGet::From()]); 80 | 81 | $name = BotGet::Name(true, 'nom', $id); 82 | 83 | return "Пользователь @id{$id} ($name) забанен"; 84 | } else { 85 | $name = BotGet::Name(true, 'gen', $id); 86 | 87 | return "Не удалось забанить @id{$id} ($name)"; 88 | } 89 | } 90 | 91 | function ActionUnBan() 92 | { 93 | if (isset(VK['fwd_messages'][0]['from_id'])) { 94 | $id = VK['fwd_messages'][0]['from_id']; 95 | } else { 96 | $id = Utils::Join(func_get_args(), ' '); 97 | if (empty($id)) { 98 | return '@Вы не указали ID'; 99 | } 100 | } 101 | 102 | $id = Account::GetID($id); 103 | 104 | $data = Account::GetDataUser($id); 105 | 106 | if ($id == 0 || !$data) { 107 | return '@Ой-ой! Я таких не знаю (('; 108 | } 109 | 110 | Account::SetRow($id, ['ban' => 0, 'ban_desc' => '', 'ban_by' => '']); 111 | 112 | $name = BotGet::Name(true, 'nom', $id); 113 | 114 | return "Пользователь @id{$id} ($name) разбанен"; 115 | } 116 | 117 | function ActionMute() 118 | { 119 | if (isset(VK['fwd_messages'][0]['from_id'])) { 120 | $id = VK['fwd_messages'][0]['from_id']; 121 | } else { 122 | $id = Utils::Join(func_get_args(), ' '); 123 | if (empty($id)) { 124 | return '@Следует указать ID, или имя пользователя'; 125 | } 126 | } 127 | 128 | $id = Account::GetID($id); 129 | 130 | if ($id == 0) { 131 | return '@Ой-ой! Я таких не знаю (('; 132 | } 133 | 134 | $rank = Account::GetRank(); 135 | $rankKick = Account::GetRank($id); 136 | 137 | if ($rankKick >= $rank) { 138 | $name = BotGet::Name(true, 'gen', $id); 139 | 140 | return "Не удалось дать затычку @id{$id} ($name)"; 141 | } 142 | 143 | Account::SetRow($id, ['mute' => 1]); 144 | 145 | $name = BotGet::Name(true, 'nom', $id); 146 | 147 | return "Пользователь @id{$id} ($name) получил затычку"; 148 | } 149 | 150 | function ActionUnMute() 151 | { 152 | if (isset(VK['fwd_messages'][0]['from_id'])) { 153 | $id = VK['fwd_messages'][0]['from_id']; 154 | } else { 155 | $id = Utils::Join(func_get_args(), ' '); 156 | 157 | $id = Account::GetID($id); 158 | 159 | if ($id == 0) { 160 | return '@Ой-ой! Я таких не знаю (('; 161 | } 162 | } 163 | 164 | Account::SetRow($id, ['mute' => 0]); 165 | 166 | $name = BotGet::Name(true, 'nom', $id); 167 | 168 | return "Пользователь @id{$id} ($name) был освобожден от затычки"; 169 | } 170 | 171 | function ActionUnWarn() 172 | { 173 | if (isset(VK['fwd_messages'][0]['from_id'])) { 174 | $id = VK['fwd_messages'][0]['from_id']; 175 | } else { 176 | $id = Utils::Join(func_get_args(), ' '); 177 | 178 | $id = Account::GetID($id); 179 | 180 | if ($id == 0) { 181 | return '@Ой-ой! Я таких не знаю (('; 182 | } 183 | } 184 | 185 | $data = Account::GetDataUser($id); 186 | if ($data && $data['warn'] >= 1) { 187 | 188 | Account::SetRow($id, ['warn' => --$data['warn']]); 189 | 190 | $name = BotGet::Name(true, 'dat', $id); 191 | 192 | return "Пользователю @id{$id} ($name) снято одно предупреждение ({$data['warn']} / 3)"; 193 | } else { 194 | return "У пользователя нет предупреждений"; 195 | } 196 | } 197 | 198 | function ActionWarn() 199 | { 200 | if (isset(VK['fwd_messages'][0]['from_id'])) { 201 | $id = VK['fwd_messages'][0]['from_id']; 202 | } else { 203 | $id = Utils::Join(func_get_args(), ' '); 204 | 205 | $id = Account::GetID($id); 206 | 207 | if ($id == 0) { 208 | return '@Ой-ой! Я таких не знаю (('; 209 | } 210 | } 211 | 212 | $rank = Account::GetRank(); 213 | $rankKick = Account::GetRank($id); 214 | 215 | if ($rankKick >= $rank) { 216 | $name = BotGet::Name(true, 'dat', $id); 217 | 218 | return "Не удалось дать предупреждение @id{$id} ($name)"; 219 | } 220 | 221 | $data = Account::GetDataUser($id); 222 | $data['warn'] = !$data ? 0 : $data['warn']; 223 | 224 | Account::SetRow($id, ['warn' => ++$data['warn']]); 225 | Account::CheckWarn($id); 226 | 227 | $name = BotGet::Name(true, 'nom', $id); 228 | 229 | return "Пользователь @id{$id} ($name) получил предупреждение. ({$data['warn']} / 3)"; 230 | } 231 | 232 | function ActionTitle() 233 | { 234 | $title = Utils::Join(func_get_args(), ' '); 235 | if (empty($title)) { 236 | return '@Вы не указали новое название беседы'; 237 | } 238 | BotConversation::Title($title); 239 | return "Вы изменили имя беседы на \"{$title}\""; 240 | } 241 | } -------------------------------------------------------------------------------- /example/Bot Slada/Controller/ControllerEvent.php: -------------------------------------------------------------------------------- 1 | ActionObject(); 10 | return; 11 | } 12 | $data = Account::GetDataUser(); 13 | if ($data && $data['mute']) { 14 | BotMessage::Send('@id' . BotGet::From() . ', на вас наложили мут. Не пишите ничего в чат, иначе, вам будет выдано еще одно предупреждение.
Сейчас у вас: ' . ++$data['warn'] . ' / 3 предупреждений'); 15 | Account::SetRow(BotGet::From(), ['warn' => $data['warn']]); 16 | Account::CheckWarn(); 17 | return; 18 | } 19 | 20 | Handler::Run(); 21 | } 22 | 23 | function ActionObject() 24 | { 25 | switch (VK['action']['type']) { 26 | case 'chat_invite_user': 27 | $id = VK['action']['member_id']; 28 | if ($id == -GROUP) { 29 | BotMessage::Send('П-приветик, друзяшки! Меня зовут Слада, можете звать меня просто Сладенькая :з
Я могу управлять вашей беседой. Также, в меня встроено немало развлекательных команд (Посмотреть их можно, командой -- Sweety, Помощь 2. Их можно отключить командой Sweety, ОтклРазвлекательные, и включить командой Sweety, ВклРазвлекательные)
Для того, чтобы я смогла вам помогать, дайте мне права администратора, и доступ ко всей переписке, и напишите "Sweety, установить" :-)'); 30 | break; 31 | } else { 32 | $data = Account::GetDataUser($id); 33 | if (!$data) { 34 | break; 35 | } 36 | if ($data['ban']) { 37 | BotConversation::DeleteUser($id); 38 | 39 | $name = BotGet::Name(true, 'nom', $id); 40 | 41 | $who = BotGet::Name(true, 'ins', $data['ban_by']); 42 | 43 | if (!empty($data['ban_desc'])) { 44 | $reason = "по причине {$data['ban_desc']}"; 45 | } else { 46 | $reason = ""; 47 | } 48 | 49 | BotMessage::Send("Пользователь @id{$id} ($name) забанен @id{$data['ban_by']} ({$who}) {$reason}
"); 50 | } 51 | } 52 | break; 53 | case 'chat_kick_user': 54 | $bool = Account::GetData()['antiLeave']; 55 | if ($bool) { 56 | BotConversation::DeleteUser(VK['action']['member_id']); 57 | } 58 | break; 59 | } 60 | return; 61 | } 62 | } -------------------------------------------------------------------------------- /example/Bot Slada/Controller/ControllerGame.php: -------------------------------------------------------------------------------- 1 | '; 13 | } 14 | 15 | $code = 'return API.users.get({"user_ids": API.messages.getConversationMembers({"peer_id":' . BotGet::Peer() . '}).items@.member_id});'; 16 | $api = BotRequest::API('execute', ['code' => $code]); 17 | 18 | $rand = mt_rand(0, count($api) - 1); 19 | 20 | $people = "@id{$api[$rand]['id']} ({$api[$rand]['first_name']} {$api[$rand]['last_name']})"; 21 | return str_replace(['{text}', '{people}'], [$text, $people], $data[mt_rand(0, count($data) - 1)]); 22 | } 23 | } -------------------------------------------------------------------------------- /example/Bot Slada/Controller/ControllerMain.php: -------------------------------------------------------------------------------- 1 | Бот создан на библиотеке MVC PHP Bot: https://github.com/AntonShvets0/MVCBot/'; 9 | } 10 | 11 | function ActionHelp($page = 1) 12 | { 13 | if (!($page == '1' || $page == '2')) { 14 | return '@Неверная страница'; 15 | } 16 | 17 | if ($page == '1') { 18 | $message = Account::Gender() . ', ты видишь перед собой все возможные команды бота!
P.s: Не забывай дописывать перед командой "Sweety ", договорились? :-)
P.s: Все параметры указанные в <вот таких скобках> -- обязательные, а [вот в таких] необязательные!
Список команд:

'; 19 | 20 | $message .= file_get_contents(ROOT . '/Data/Help.txt'); 21 | } else { 22 | $message = Account::OwoGender() . '! Пришло время веселиться, не так ли?
Перед тобой все команды, которыми я могу тебя развлечь. Удачи :-)
P.s: Не забывай дописывать "Sweety ", перед командой
'; 23 | $message .= file_get_contents(ROOT . '/Data/Help2.txt'); 24 | } 25 | 26 | return $message; 27 | } 28 | 29 | function ActionInstall() 30 | { 31 | $owner = BotConversation::GetOwnerID(); 32 | 33 | $registered = false; 34 | if (Account::Registered()) { 35 | $registered = true; 36 | Sql::Delete()->From('conversations')->Where('id', BotGet::Peer())->Exec(); 37 | Sql::Delete()->From('users')->Where('conversation', BotGet::Peer())->Exec(); 38 | Sql::Delete()->From('commands')->Where('conversation', BotGet::Peer())->Exec(); 39 | } 40 | if (!BotConversation::IsAdmin()) { 41 | return '@' . Account::OwoGender() . '! *Гневно топнула ножкой*. Я не администратор!'; 42 | } 43 | 44 | $ranks = ['Пользователь', 'Помощник', 'Администратор', 'Главный Администратор']; 45 | $commands = ['антивыход' => 3, 'кик' => 2, 'бан' => 2, 'разбан' => 1, 'мут' => 1, 'размут' => 1, 'предупреждение' => 2, 'снятьпред' => 1, 'админ' => 3, 'установить' => 3, 'права' => 3, 'рангимя' => 3, 'рангдобавить' => 3, 'рангудалить' => 3, 'название' => 1, 'развлкоманды' => 1]; 46 | 47 | foreach ($commands as $command => $rank) { 48 | Sql::Insert(['rank' => $rank, 'conversation' => BotGet::Peer(), 'command' => $command])->From('commands')->Exec(); 49 | } 50 | 51 | $data = ['id' => BotGet::Peer(), 'name' => BotConversation::GetName(), 'countRanks' => 3, 'ranks' => json_encode($ranks, JSON_UNESCAPED_UNICODE), 'game' => 1]; 52 | $user = ['user' => $owner, 'conversation' => BotGet::Peer(), 'rank' => 3]; 53 | Sql::Insert($data)->From('conversations')->Exec(); 54 | Sql::Insert($user)->From('users')->Exec(); 55 | 56 | return 'Ту-ту-ру~. Команды бота ' . (!$registered ? 'установлены' : 'переустановлены') . '! <3'; 57 | } 58 | } -------------------------------------------------------------------------------- /example/Bot Slada/Controller/ControllerManage.php: -------------------------------------------------------------------------------- 1 | = $rank) { 24 | return '@Нельзя изменить уровень человеку, который выше или равный вам по полномочиям'; 25 | } 26 | 27 | if ($level >= $rank) { 28 | return '@Нельзя изменить уровень на выше, или равный вам'; 29 | } 30 | 31 | if ($id == BotGet::From()) { 32 | return '@Нельзя изменить уровень себе'; 33 | } 34 | 35 | Account::SetRow($id, ['rank' => $level]); 36 | 37 | $name = BotGet::Name(true, 'nom', $id); 38 | $rankName = Account::GetRankName($level); 39 | return "Пользователю @id{$id} ({$name}) установлен ранг {$rankName} ({$level})"; 40 | } 41 | 42 | function ActionAccess($command = "", $level = 0) 43 | { 44 | if (empty($command)) { 45 | return '@Правильный ввод: Sweety, права <Команда> [Ранг]'; 46 | } 47 | 48 | $data = Account::GetData(); 49 | if ($level > $data['countRanks'] || $level < 0) { 50 | return '@Указанный ранг не существует'; 51 | } 52 | $command = mb_strtolower($command); 53 | 54 | if (!isset(Handler::$functionList[$command])) { 55 | return '@Неизвестная команда'; 56 | } 57 | 58 | $data = Sql::Select()->From('commands')->Where('command', $command)->Exec(); 59 | 60 | if (!isset($data[0]['id'])) { 61 | Sql::Insert(['conversation' => BotGet::Peer(), 'command' => $command, 'rank' => $level])->From('commands')->Exec(); 62 | } else { 63 | Sql::Update(['rank' => $level])->From('commands')->Where('conversation', BotGet::Peer())->Where('command', $command)->Exec(); 64 | } 65 | 66 | $name = Account::GetRankName($level); 67 | return "Команда \"{$command}\" теперь доступна только с ранга {$name} ({$level})"; 68 | } 69 | 70 | function ActionRankName($level = 0) 71 | { 72 | if (mb_strlen($level) < 1) { 73 | return '@Ранг не указан'; 74 | } 75 | 76 | $name = Utils::Join(array_slice(func_get_args(), 1), ' '); 77 | 78 | if (empty($name)) { 79 | return '@Имя ранга не указано'; 80 | } 81 | 82 | $data = Account::GetData(); 83 | if ($data['countRanks'] < $level || $level < 0) { 84 | return '@Ранг не существует'; 85 | } 86 | 87 | $rank = json_decode($data['ranks'], true); 88 | 89 | $rank[$level] = $name; 90 | 91 | $rank = json_encode($rank, JSON_UNESCAPED_UNICODE); 92 | 93 | Sql::Update(['ranks' => $rank])->From('conversations')->Where('id', BotGet::Peer())->Exec(); 94 | 95 | return "Имя {$level} ранга установлено на {$name}"; 96 | } 97 | 98 | function ActionRankAdd($count = 0) 99 | { 100 | if (empty($count)) { 101 | return '@Нельзя добавить 0 рангов'; 102 | } 103 | 104 | if ($count > 15) { 105 | return '@Нельзя указать больше 15 рангов за раз'; 106 | } 107 | 108 | $default_names = Utils::Join(array_slice(func_get_args(), 1), ' '); 109 | 110 | $nameRanks = []; 111 | 112 | for ($i = 0; $i < $count; $i++) { 113 | $nameRanks[$i] = "Безымянный"; 114 | } 115 | 116 | if (!empty($default_names)) { 117 | $oldNameRanks = $nameRanks; 118 | $nameRanks = explode(',', $default_names); 119 | if (count($nameRanks) > $count ||count($nameRanks) < $count) { 120 | BotMessage::Send('Вы указали неверное количество имен. Параметр [Имена через запятую] будет опущен'); 121 | $nameRanks = $oldNameRanks; 122 | } 123 | } 124 | 125 | $data = Account::GetData(); 126 | 127 | $ranks = json_encode(array_merge(json_decode($data['ranks'], true), $nameRanks), JSON_UNESCAPED_UNICODE); 128 | $countRanks = $data['countRanks'] + $count; 129 | 130 | Sql::Update(['ranks' => $ranks, 'countRanks' => $countRanks])->From('conversations')->Where('id', BotGet::Peer())->Exec(); 131 | Sql::Update(['rank' => $countRanks])->From('users')->Where('user', BotConversation::GetOwnerID())->Where('conversation', BotGet::Peer())->Exec(); 132 | 133 | return Utils::Num2Str($count, 'Добавлен', ['', 'о', 'о']) . ' ' . $count . ' ' . Utils::Num2Str($count, 'ранг', ['', 'а', 'ов']); 134 | } 135 | 136 | function ActionRankRemove($count = 0) 137 | { 138 | if (empty($count)) { 139 | return '@Количество рангов не указано'; 140 | } 141 | 142 | $data = Account::GetData(); 143 | 144 | if ($count > $data['countRanks']) { 145 | return '@Столько рангов не существует'; 146 | } 147 | 148 | $ranks = json_decode($data['ranks'], true); 149 | 150 | for ($i = 0; $i < $count; $i++) { 151 | unset($ranks[$data['countRanks'] - $i]); 152 | } 153 | 154 | $ranks = json_encode($ranks, JSON_UNESCAPED_UNICODE); 155 | 156 | Sql::Update(['countRanks' => $data['countRanks'] - $count, 'ranks' => $ranks])->From('conversations')->Where('id', BotGet::Peer())->Exec(); 157 | Sql::Update(['rank' => $data['countRanks'] - $count])->From('commands')->Where('conversation', BotGet::Peer())->Where('rank', '>', $data['countRanks'] - $count)->Exec(); 158 | 159 | $rank = $data['countRanks'] - $count - 1 < 0 ? 0 : $data['countRanks'] - $count - 1; 160 | Sql::Update(['rank' => $rank])->From('users')->Where('conversation', BotGet::Peer())->Exec(); 161 | Sql::Update(['rank' => $data['countRanks'] - $count])->From('users')->Where('conversation', BotGet::Peer())->Where('user', BotConversation::GetOwnerID())->Exec(); 162 | return Utils::Num2Str($count, 'Удален', ['', 'о', 'о']) . ' ' . $count . ' ' . Utils::Num2Str($count, 'ранг', ['', 'а', 'ов']); 163 | } 164 | 165 | function ActionListRank() 166 | { 167 | $data = json_decode(Account::GetData()['ranks'], true); 168 | 169 | $msg = "СПИСОК РАНГОВ:
"; 170 | foreach ($data as $key => $val) { 171 | $msg .= "{$key}. {$val}
"; 172 | } 173 | 174 | return $msg; 175 | } 176 | 177 | function ActionListCommand() 178 | { 179 | $data = Sql::Select()->From('commands')->Where('conversation', BotGet::Peer())->Exec(); 180 | 181 | $msg = "СПИСОК КОМАНД:
"; 182 | foreach ($data as $val) { 183 | $rank = Account::GetRankName($val['rank']); 184 | $msg .= "{$val['command']} -- {$rank} ({$val['rank']})
"; 185 | } 186 | 187 | return $msg; 188 | } 189 | 190 | function ActionGame() 191 | { 192 | $data = !Account::GetData()['game']; 193 | Sql::Update(['game' => $data])->From('conversations')->Exec(); 194 | return 'Развлекательные команды ' . ($data ? 'включены' : 'выключены'); 195 | } 196 | } -------------------------------------------------------------------------------- /example/Bot Slada/Data/Help.txt: -------------------------------------------------------------------------------- 1 | Информация -- Информация о боте 2 | Помощь -- Список всех основных команд 3 | Помощь 2 -- Список всех развлекательных команд 4 | 5 | Установить -- Регистрирует беседу в базе данных, позволяя использовать остальные админ-функции 6 | 7 | АДМИНИСТРИРОВАНИЕ 8 | 9 | Кик -- Удаляет пользователя из беседы 10 | Бан [Причина] -- Удаляет пользователя из беседы. При попытке зайти в беседу, этого пользователя будет кикать. 11 | Разбан -- Снимает бан с пользователя 12 | Предупреждение -- Дает предупреждение пользователю. Если будет 3 предупреждения, пользователя удалит из беседы 13 | СнятьПред -- Снимает одно предупреждение 14 | Мут -- За каждое сообщение пользователя, ему будет даваться предупреждение 15 | Размут -- Убирет мут у пользователя 16 | АнтиВыход -- Включает/Отключает функцию антивыхода. При выходе из беседы, пользователя мгновенно кикает, чтобы он не мог зайти обратно. 17 | Название <Название беседы> -- Изменить название беседы 18 | 19 | УПРАВЛЕНИЕ БОТОМ 20 | 21 | Админ <Уровень> -- Изменяет ранг пользователя на нужный 22 | Права <Команда> <Ранг> -- Устанавливает необходимый ранг для данной команды 23 | РангИмя <Ранг> <Имя> -- Изменяет имя ранга 24 | РангДобавить <Количество рангов> [Их имена, через запятую] -- Добавляет новые ранги 25 | РангУдалить <Количество рангов> -- Удаляет ранги 26 | РазвлКоманды -- Включает/Отключает развлекательные команды 27 | СписокРангов -- Показать список всех рангов 28 | СписокКоманд -- Показать список команд -------------------------------------------------------------------------------- /example/Bot Slada/Data/Help2.txt: -------------------------------------------------------------------------------- 1 | swho <Текст> -- выбирает случайного участника из беседы -------------------------------------------------------------------------------- /example/Bot Slada/Data/who.txt: -------------------------------------------------------------------------------- 1 | Темные силы подсказывают мне, что {text} -- {people} 2 | Мои шестеренки шепчут мне, что {text} -- {people} 3 | Мое тотемное животное (синий слон) произнесло: {text} -- {people} 4 | Хм... самая загадочная тайна... Помню, разгадывала на днях тайну. Там ответом было число 42. Так вот. Та тайна, по сравнению с этой -- легкотня!
Ну ладно... Может быть... {text} это {people} -------------------------------------------------------------------------------- /example/Bot Slada/File/blackmale.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntonShvets0/MVCBot/fbc5323bd0acf167e5c70498f0f051d66a29e5f5/example/Bot Slada/File/blackmale.jpg -------------------------------------------------------------------------------- /example/Bot Slada/Models/Account.php: -------------------------------------------------------------------------------- 1 | = 3) { 20 | $response = BotConversation::DeleteUser($id); 21 | 22 | if ($response) { 23 | Account::SetRow($id, ['ban' => 1, 'ban_desc' => '3 предупреждения', 'ban_by' => $id]); 24 | 25 | $name = BotGet::Name(true, 'nom', $id); 26 | 27 | BotMessage::Send("Пользователь @id{$id} ($name) забанен"); 28 | } else { 29 | $name = BotGet::Name(true, 'gen', $id); 30 | 31 | BotMessage::Send("Не удалось забанить @id{$id} ($name)"); 32 | Account::SetRow($id, ['warn' => 0, 'mute' => 0]); 33 | } 34 | } 35 | } 36 | 37 | /** 38 | * @param $id 39 | * @param $row 40 | * Устанавливает значение в бд для пользователя. Если пользователя нет -- создает 41 | */ 42 | public static function SetRow($id, $row) 43 | { 44 | $data = self::GetDataUser($id); 45 | if ($data == false) { 46 | $row['user'] = $id; 47 | $row['conversation'] = BotGet::Peer(); 48 | Sql::Insert($row)->From('users')->Exec(); 49 | } else { 50 | Sql::Update($row)->From('users')->Where('user', $id)->Where('conversation', BotGet::Peer())->Exec(); 51 | } 52 | } 53 | 54 | /** 55 | * @param $name 56 | * @return int 57 | * Пытается получить ID человека 58 | */ 59 | public static function GetID($name) 60 | { 61 | if (is_int($name)) { 62 | $firstAndLastName = BotGet::Name(true, 'nom', $name); 63 | return $firstAndLastName == false ? 0 : $name; 64 | } elseif (mb_substr($name, 0, 2) == 'id') { 65 | $name = mb_substr($name, 2); 66 | $firstAndLastName = BotGet::Name(true, 'nom', $name); 67 | return $firstAndLastName == false ? 0 : $name; 68 | } elseif (mb_substr($name, 0, 3) == '[id') { 69 | $name = mb_substr($name, 3); 70 | list($name) = explode('|', $name); 71 | $firstAndLastName = BotGet::Name(true, 'nom', $name); 72 | return $firstAndLastName == false ? 0 : $name; 73 | } 74 | 75 | $code = 'return API.users.get({"user_ids": API.messages.getConversationMembers({"peer_id":' . BotGet::Peer() . '}).items@.member_id});'; 76 | $api = BotRequest::API('execute', ['code' => $code]); 77 | 78 | foreach ($api as $array) { 79 | $nameArray = $array['first_name'] . ' ' . $array['last_name']; 80 | if (stripos($nameArray, $name) !== false) { 81 | return $array['id']; 82 | } 83 | } 84 | 85 | return 0; 86 | } 87 | 88 | /** 89 | * @param string $user_id 90 | * @return bool 91 | * Возвращает информацию о пользователе 92 | */ 93 | public static function GetDataUser($user_id = 'callback') 94 | { 95 | if ($user_id == 'callback') { 96 | $user_id = BotGet::From(); 97 | } 98 | $data = Sql::Select()->From('users')->Where('conversation', BotGet::Peer())->Where('user', $user_id)->Exec(); 99 | return isset($data[0]) ? $data[0] : false; 100 | } 101 | 102 | /** 103 | * @param string $user_id 104 | * @return int 105 | * Польчает ранг пользователя 106 | */ 107 | public static function GetRank($user_id = 'callback') 108 | { 109 | $data = self::GetDataUser($user_id); 110 | return isset($data['rank']) ? $data['rank'] : 0; 111 | } 112 | 113 | /** 114 | * @param $rank 115 | * @return mixed 116 | * Получает имя ранга 117 | */ 118 | public static function GetRankName($rank) 119 | { 120 | $data = self::GetData(); 121 | return json_decode($data['ranks'], true)[$rank]; 122 | } 123 | 124 | /** 125 | * @return bool|array 126 | * Получает информацию о боте 127 | */ 128 | public static function GetData() 129 | { 130 | $data = Sql::Select()->From('conversations')->Where('id', BotGet::Peer())->Exec(); 131 | 132 | return isset($data[0]) ? $data[0] : false; 133 | } 134 | 135 | /** 136 | * @return string 137 | * Возвращает строку в зависимости от пола 138 | */ 139 | public static function Gender() 140 | { 141 | $gender = BotGet::Gender(); 142 | return $gender == 1 ? 'Братик' : 'Сестренка'; 143 | } 144 | 145 | public static function OwoGender() 146 | { 147 | $gender = BotGet::Gender(); 148 | return $gender == 1 ? 'Б-братик' : 'С-сестренка'; 149 | } 150 | 151 | /** 152 | * @return bool 153 | * Проверяет на наличие в бд беседы 154 | */ 155 | public static function Registered() 156 | { 157 | return self::GetData() != false; 158 | } 159 | 160 | /** 161 | * @return bool 162 | * Проверка. Беседа ли это 163 | */ 164 | public static function IsConversation() 165 | { 166 | return BotGet::Peer() != BotGet::From(); 167 | } 168 | } -------------------------------------------------------------------------------- /example/Bot Slada/Models/FunctionHandler.php: -------------------------------------------------------------------------------- 1 | getMessage()}, {$exception->getTrace()}"); 49 | return ""; 50 | } 51 | } 52 | 53 | return $response; 54 | } 55 | } -------------------------------------------------------------------------------- /example/Bot Slada/Models/Logger.php: -------------------------------------------------------------------------------- 1 | 4 && $mod < 20 ? 2 : $keys[min($mod%10, 5)]; 53 | 54 | return $value . $suffix[$suffix_key]; 55 | } 56 | 57 | public static function GoId($id) 58 | { 59 | return ltrim(ltrim($id, 2), '0'); 60 | } 61 | } -------------------------------------------------------------------------------- /example/Bot Slada/Models/VK/BotConversation.php: -------------------------------------------------------------------------------- 1 | $peerID, 'fields' => Utils::Join($fields)]); 67 | return isset($data['items'][0]) ? $data['items'][0] : false; 68 | } 69 | 70 | /** 71 | * @param string $peerID 72 | * @return bool 73 | * Удаляет из беседы фото 74 | */ 75 | public static function DeletePhoto($peerID = 'callback') 76 | { 77 | if ($peerID == 'callback') { 78 | $peerID = BotGet::Peer(); 79 | } 80 | 81 | $data = self::API('messages.deleteChatPhoto', ['chat_id' => $peerID]); 82 | return !$data ? false : true; 83 | } 84 | 85 | /** 86 | * @param $title 87 | * @param string $peerID 88 | * @return bool 89 | * Редактирует заголовок беседы 90 | */ 91 | public static function Title($title, $peerID = 'callback') 92 | { 93 | if ($peerID == 'callback') { 94 | $peerID = BotGet::Peer(); 95 | } 96 | 97 | $data = self::API('messages.editChat', ['chat_id' => Utils::GoId($peerID), 'title' => $title]); 98 | 99 | return $data; 100 | } 101 | 102 | /** 103 | * @param int $user 104 | * @param string|int $peerID 105 | * @return bool 106 | */ 107 | public static function DeleteUser($user, $peerID = 'callback') 108 | { 109 | if ($peerID == 'callback') { 110 | $peerID = BotGet::Peer(); 111 | } 112 | $peerID = Utils::GoId($peerID); 113 | 114 | return self::API('messages.removeChatUser', ['chat_id' => $peerID, 'member_id' => $user]); 115 | } 116 | 117 | /** 118 | * @param int $messageID 119 | * @param string $peerID 120 | * @return bool 121 | * Закрепляет сообщение 122 | */ 123 | public static function Pin($messageID, $peerID = 'callback') 124 | { 125 | if ($peerID == 'callback') { 126 | $peerID = BotGet::Peer(); 127 | } 128 | return !self::API('messages.pin', ['peer_id' => $peerID, 'message_id' => $messageID]) ? false : true; 129 | } 130 | } -------------------------------------------------------------------------------- /example/Bot Slada/Models/VK/BotGet.php: -------------------------------------------------------------------------------- 1 | $ids, 'fields' => $fields, 'name_case' => $nameCase]); 69 | } 70 | } -------------------------------------------------------------------------------- /example/Bot Slada/Models/VK/BotMessage.php: -------------------------------------------------------------------------------- 1 | $peerID, 'message' => $text, 'message_id' => $messageID, 'attachment' => Utils::Join($attach)]); 29 | } 30 | 31 | /** 32 | * @param bool $bool 33 | * @param string|int $peerID 34 | * @return bool 35 | * Статус набора текста 36 | */ 37 | public static function Activity($bool = true, $peerID = 'callback') 38 | { 39 | if ($peerID == 'callback') { 40 | $peerID = BotGet::GetID(); 41 | } 42 | 43 | $type = $bool ? 'typing' : 'audiomessage'; 44 | $data = self::API('messages.setActivity', ['peer_id' => $peerID, 'type' => $type]); 45 | 46 | return $data; 47 | } 48 | 49 | /** 50 | * @param int|array $messageID 51 | * @return bool 52 | * Удаляет сообщение 53 | */ 54 | public static function Delete($messageID) 55 | { 56 | $messageID = Utils::Join($messageID); 57 | 58 | $data = self::API('messages.delete', ['message_ids' => $messageID, 'delete_for_all' => 1]); 59 | $bool = false; 60 | 61 | foreach ($data as $val) { 62 | if ($val == 0) { 63 | $bool = false; 64 | } else { 65 | $bool = true; 66 | } 67 | } 68 | 69 | return $bool; 70 | } 71 | 72 | /** 73 | * @param string $message 74 | * @param string|int $id 75 | * @param array|string $attach 76 | * @param array $keyBoard 77 | * @return bool 78 | * Отправляет сообщение 79 | */ 80 | public static function Send($message, $id = 'callback', $attach = [], $keyBoard = []) 81 | { 82 | if ($id == 'callback') { 83 | $id = BotGet::GetID(); 84 | } 85 | 86 | $keyBoard = self::CreateKeyBoard($keyBoard); 87 | $message = str_replace(['
', '
'], PHP_EOL, $message); 88 | 89 | $count = (mb_strlen($message / 4000)); // Ограничение в вк по кол-ву символов на сообщение -- 4000 90 | $count = $count > 1 ? $count : 1; 91 | 92 | $data = false; 93 | 94 | for ($i = 0; $i < $count; $i++) { 95 | $msg = mb_substr($message, $i * 4000, 4000); 96 | 97 | $isLastI = $i >= $count - 1; 98 | 99 | $data = [ 100 | 'random_id' => mt_rand(0, 1000), 101 | 'peer_id' => $id, 102 | 'message' => $msg, 103 | ]; 104 | 105 | if ($isLastI) { 106 | $data['attachment'] = Utils::Join($attach); 107 | $data['keyboard'] = $keyBoard; 108 | } 109 | 110 | $data = self::API('messages.send', $data); 111 | } 112 | 113 | Logger::Info("Message \"{$message}\" to {$id}"); 114 | 115 | return $data ? true : false; 116 | } 117 | 118 | /** 119 | * @param array $keyBoard 120 | * @param bool $vkStyle 121 | * @return string 122 | * Создает JSON-клавиатуру для VK 123 | */ 124 | private static function CreateKeyBoard($keyBoard, $vkStyle = false) 125 | { 126 | if ($vkStyle) { 127 | return json_encode($vkStyle, true); 128 | } 129 | 130 | $json = [ 131 | 'one_time' => array_shift($keyBoard), 132 | 'buttons' => [ 133 | 134 | ] 135 | ]; 136 | 137 | foreach ($keyBoard as $item) { 138 | $json['buttons'][] = self::CreateKeyBoardRows($item); 139 | } 140 | 141 | return json_encode($json, JSON_UNESCAPED_UNICODE); 142 | } 143 | 144 | /** 145 | * @param $array 146 | * @return array 147 | */ 148 | private static function CreateKeyBoardRows($array) 149 | { 150 | $result = []; 151 | 152 | foreach ($array as $name => $data) { 153 | $result[] = ['action' => ['label' => $name, 'payload' => json_encode($data[1])], 'color' => $data[0]]; 154 | } 155 | 156 | return $result; 157 | } 158 | } -------------------------------------------------------------------------------- /example/Bot Slada/Models/VK/BotRequest.php: -------------------------------------------------------------------------------- 1 | self::GetFile($path)]); 15 | 16 | $photo = BotRequest::API('photos.saveMessagesPhoto', ['photo' => $data['photo'], 'server' => $data['server'], 'hash' => $data['hash']]); 17 | 18 | return 'photo' . $photo[0]['owner_id'] . '_' . $photo[0]['id'] . '_' . $photo[0]['access_key']; 19 | } 20 | 21 | public static function GetUploadMessageLink($peerID) 22 | { 23 | return BotRequest::API('photos.getMessagesUploadServer', ['peer_id' => $peerID])['upload_url']; 24 | } 25 | 26 | public static function GetFile($path) 27 | { 28 | return new CURLFile($path, mime_content_type($path), $path); 29 | } 30 | } -------------------------------------------------------------------------------- /example/Bot Slada/Models/VK/BotWall.php: -------------------------------------------------------------------------------- 1 | $ownerID, 30 | 'post_id' => $postID, 31 | 'message' => $text, 32 | 'attachments' => Utils::Join($attach) 33 | ]; 34 | 35 | if (!empty($replyTo)) { 36 | $data['reply_to_comment'] = $replyTo; 37 | } 38 | 39 | if (!empty($stickerId)) { 40 | $data['sticker_id'] = $stickerId; 41 | } 42 | 43 | 44 | BotRequest::API('wall.createComment', $data); 45 | } 46 | 47 | /** 48 | * @param int $postID 49 | * @param string $type 50 | * @return void 51 | */ 52 | public static function Comment($postID, $type = 'close') 53 | { 54 | $ownerID = GROUP; 55 | $type = $type == 'close' || $type == 'open' ? $type : 'close'; 56 | 57 | BotRequest::API('wall.' . $type . 'Comments', ['owner_id' => $ownerID, 'post_id' => $postID]); 58 | } 59 | 60 | } -------------------------------------------------------------------------------- /example/Bot Slada/Models/VK/Event.php: -------------------------------------------------------------------------------- 1 | From('commands')->Where('conversation', BotGet::Peer())->Where('command', $command)->Exec(); 210 | if (isset($commands[0]['rank'])) { 211 | $need_rank = $commands[0]['rank']; 212 | $rank = Account::GetRank(); 213 | if ($need_rank > $rank) { 214 | BotMessage::Send('Команда "' . $command . '" доступна только с ранга ' . Account::GetRankName($need_rank) . " ({$need_rank})"); 215 | return; 216 | } 217 | } 218 | } 219 | 220 | $response = FunctionHandler::Call(self::$functionList[$command][0], $message); 221 | 222 | $message = $response; 223 | $attach = []; 224 | $keyBoard = []; 225 | 226 | if (is_array($response)) { 227 | $message = $response[0]; 228 | $attach = $response[1]; 229 | $keyBoard = isset($response[2]) ? $response[2] : []; 230 | } 231 | 232 | if (mb_substr($message, 0, 1) == CONFIG['data']['errorChar']) { 233 | $str = str_replace(['{command}', '{error}'], [$command, mb_substr($message, 1)], CONFIG['data']['error']); 234 | BotMessage::Send($str, 'callback', $attach, $keyBoard); 235 | return; 236 | } 237 | 238 | BotMessage::Send($message, 'callback', $attach, $keyBoard); 239 | } 240 | 241 | /** 242 | * @param $appeal 243 | * @return string 244 | * Форматирует обращение 245 | */ 246 | private static function FormatAppeal($appeal) 247 | { 248 | $lastChar = mb_substr($appeal, mb_strlen($appeal) - 1); 249 | 250 | if ($lastChar == ',') { 251 | $appeal = mb_substr($appeal, 0, -1); 252 | } 253 | 254 | return mb_strtolower($appeal); 255 | } 256 | } -------------------------------------------------------------------------------- /example/Config/Command.php: -------------------------------------------------------------------------------- 1 | [ 23 | "positive", // зеленая кнопка 24 | ['about', 'us'] // при нажатии на эту кнопку, боту отправит команду "about us" 25 | ] 26 | ] 27 | ]; 28 | return ['Проверка клавиатуры', ['photo433245412_457246880', 'photo306334670_457253681'], $keyboard]; 29 | }); 30 | 31 | Handler::Register('about', function () { 32 | return 'MVC BOT -- это удобная библиотека для создания CALLBACK-ботов в вк. В ней встроена библиотека для работы с VK API, а создание команд делается в пару строк кода
Автор: https://vk.com/lordoverlord0'; 33 | }, true); // делаем команду доступной только через кнопку 34 | 35 | Handler::Register(['рандом', 'ранд', 'random', 'rand'], 'main@random'); // Регистрируем команды (рандом/ранд/random/rand) которые ссылаются на класс ControllerMain и метод ActionRandom 36 | 37 | Handler::Register(['управл-беседа'], function ($type) { // управляем беседой 38 | $data = Utils::Join(array_slice(func_get_args(), 1), ' '); // Получаем всю информацию после $type 39 | 40 | switch ($type) { 41 | case 'удалить': 42 | BotConversation::DeleteUser($data); // Удаляем пользователя из беседы 43 | return 'Пользователь @id' . $data . ' удален'; 44 | case 'изменить_имя': 45 | BotConversation::Title($data); // Изменяем имя беседы 46 | return 'Успешно'; 47 | case 'удалить_фото': 48 | BotConversation::DeletePhoto(); // Удаляем фото беседы 49 | return 'Успешно'; 50 | default: 51 | return '@Неизвестный тип: ' . $type; 52 | } 53 | }); 54 | 55 | Handler::Register('эмуляция', function ($type) { // эмулируем набор текста, или запись голосового сообщения 56 | $type = $type == 'голосовуха' ? false : true; 57 | BotMessage::Activity($type); 58 | }); -------------------------------------------------------------------------------- /example/Controller/ControllerMain.php: -------------------------------------------------------------------------------- 1 | GetArrayRand($min, $max); 9 | return "ВАШЕ СЛУЧАЙНОЕ ЧИСЛО: {$this->Mean($random)}"; 10 | } 11 | 12 | /** 13 | * @param int $min 14 | * @param int $max 15 | * @return array 16 | */ 17 | function GetArrayRand($min, $max) 18 | { 19 | $array = []; 20 | for ($i = 0; $i < 250; $i++) { 21 | $array[] = mt_rand($min, $max); 22 | } 23 | return $array; 24 | } 25 | 26 | /** 27 | * @param array $array 28 | * @return float|int 29 | * Среднее арифметическое 30 | */ 31 | function Mean($array) 32 | { 33 | return array_sum($array) / count($array); 34 | } 35 | } -------------------------------------------------------------------------------- /img/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntonShvets0/MVCBot/fbc5323bd0acf167e5c70498f0f051d66a29e5f5/img/1.jpg -------------------------------------------------------------------------------- /img/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntonShvets0/MVCBot/fbc5323bd0acf167e5c70498f0f051d66a29e5f5/img/2.jpg -------------------------------------------------------------------------------- /img/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntonShvets0/MVCBot/fbc5323bd0acf167e5c70498f0f051d66a29e5f5/img/3.jpg -------------------------------------------------------------------------------- /img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntonShvets0/MVCBot/fbc5323bd0acf167e5c70498f0f051d66a29e5f5/img/logo.png -------------------------------------------------------------------------------- /img/nameanton17.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntonShvets0/MVCBot/fbc5323bd0acf167e5c70498f0f051d66a29e5f5/img/nameanton17.jpg -------------------------------------------------------------------------------- /quick-start/Install/Zip.php: -------------------------------------------------------------------------------- 1 | numFiles; $i++) { 21 | $filename = $this->getNameIndex($i); 22 | 23 | if (substr($filename, 0, mb_strlen($subdir, "UTF-8")) == $subdir) { 24 | $relativePath = substr($filename, mb_strlen($subdir, "UTF-8")); 25 | $relativePath = str_replace(array("/", "\\"), DIRECTORY_SEPARATOR, $relativePath); 26 | 27 | if (mb_strlen($relativePath, "UTF-8") > 0) { 28 | if (substr($filename, -1) == "/") // Directory 29 | { 30 | // New dir 31 | if (!is_dir($destination . $relativePath)) 32 | if (!@mkdir($destination . $relativePath, 0755, true)) 33 | $errors[$i] = $filename; 34 | } else { 35 | if (dirname($relativePath) != ".") { 36 | if (!is_dir($destination . dirname($relativePath))) { 37 | // New dir (for file) 38 | @mkdir($destination . dirname($relativePath), 0755, true); 39 | } 40 | } 41 | 42 | // New file 43 | if (@file_put_contents($destination . $relativePath, $this->getFromIndex($i)) === false) 44 | $errors[$i] = $filename; 45 | } 46 | } 47 | } 48 | } 49 | 50 | return $errors; 51 | } 52 | } -------------------------------------------------------------------------------- /quick-start/Install/act.php: -------------------------------------------------------------------------------- 1 | $token, 'v' => 5.81])); 10 | 11 | $response = file_get_contents('https://api.vk.com/method/' . $method . '?' . $data); 12 | 13 | return json_decode($response, true); 14 | } 15 | 16 | function rm($path) 17 | { 18 | if (is_file($path)) return unlink($path); 19 | if (is_dir($path)) { 20 | foreach (scandir($path) as $p) if (($p != '.') && ($p != '..')) 21 | rm($path . DIRECTORY_SEPARATOR . $p); 22 | return rmdir($path); 23 | } 24 | return false; 25 | } 26 | 27 | $act = isset($_GET['do']) ? $_GET['do'] : ''; 28 | 29 | switch ($act) { 30 | case 'access': 31 | $token = isset($_POST['token']) ? $_POST['token'] : ''; 32 | 33 | $response = Api('groups.getTokenPermissions', [], $token); 34 | 35 | if (isset($response['error'])) { 36 | header('Location: index.php?error=Неверный%20токен&path=index'); 37 | exit(); 38 | } 39 | 40 | if ($response['response']['mask'] < 405508) { 41 | header('Location: index.php?error=Токену%20разрешено%20не%20все&path=index'); 42 | exit(); 43 | } 44 | 45 | $id = Api('groups.getById', [], $token)['response'][0]['id']; 46 | 47 | file_put_contents('token.txt', $token); 48 | file_put_contents('id.txt', $id); 49 | file_put_contents('secret.txt', $_POST['secret']); 50 | 51 | header('Location: act.php?do=callback'); 52 | break; 53 | case 'callback': 54 | $token = file_get_contents('token.txt'); 55 | $id = file_get_contents('id.txt'); 56 | 57 | $api = Api('groups.getCallbackConfirmationCode', ['group_id' => $id], $token); 58 | 59 | $confirm_code = $api['response']['code']; 60 | 61 | file_put_contents('confirm.txt', $confirm_code); 62 | 63 | header('Location: act.php?do=download'); 64 | break; 65 | case 'download': 66 | require_once 'Zip.php'; 67 | $github = file_get_contents('https://github.com/AntonShvets0/MVCBot/archive/master.zip'); 68 | file_put_contents('bot.zip', $github); 69 | $zip = new Zip(); 70 | $res = $zip->open('bot.zip'); 71 | $zip->extractSubdirTo(ROOT, 'MVCBot-master/src'); 72 | $zip->close(); 73 | unlink(ROOT . '/.htaccess'); 74 | unlink('bot.zip'); 75 | $array = [ 76 | 'vkCallbackData' => ['secret' => file_get_contents('secret.txt'), 'confirm' => file_get_contents('confirm.txt')], 77 | 'vkSendData' => ['v' => 5.81, 'access_token' => file_get_contents('token.txt')], 78 | 'data' => ['errorChar' => '@', 'unknownCommand' => 'ОШИБКА: Неизвестная команда "{command}"', 'error' => 'ОШИБКА: {error}'] 79 | ]; 80 | $json = json_encode($array, JSON_UNESCAPED_UNICODE); 81 | $code = << $group, 'url' => 'http://' . $_SERVER['HTTP_HOST'] . '/' . explode('?', $_SERVER['REQUEST_URI'])[0], 'title' => 'MVCBot', 'secret_key' => $secret], $token)['response']['server_id']; 108 | 109 | Api('groups.setCallbackSettings', ['group_id' => $group, 'server_id' => $server, 'api_version' => '5.80', 'message_new' => 1], $token); 110 | 111 | echo 'Все прошло успешно. Если папка Install не удалилась -- удалите ее. Для проверки бота, напишите ему mvc-php'; 112 | 113 | break; 114 | default: 115 | header('location: index.php'); 116 | } -------------------------------------------------------------------------------- /quick-start/Install/image/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntonShvets0/MVCBot/fbc5323bd0acf167e5c70498f0f051d66a29e5f5/quick-start/Install/image/1.jpg -------------------------------------------------------------------------------- /quick-start/Install/image/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntonShvets0/MVCBot/fbc5323bd0acf167e5c70498f0f051d66a29e5f5/quick-start/Install/image/2.jpg -------------------------------------------------------------------------------- /quick-start/Install/image/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntonShvets0/MVCBot/fbc5323bd0acf167e5c70498f0f051d66a29e5f5/quick-start/Install/image/3.jpg -------------------------------------------------------------------------------- /quick-start/Install/image/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntonShvets0/MVCBot/fbc5323bd0acf167e5c70498f0f051d66a29e5f5/quick-start/Install/image/4.jpg -------------------------------------------------------------------------------- /quick-start/Install/image/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntonShvets0/MVCBot/fbc5323bd0acf167e5c70498f0f051d66a29e5f5/quick-start/Install/image/5.jpg -------------------------------------------------------------------------------- /quick-start/Install/image/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntonShvets0/MVCBot/fbc5323bd0acf167e5c70498f0f051d66a29e5f5/quick-start/Install/image/6.jpg -------------------------------------------------------------------------------- /quick-start/Install/index.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | MVC PHP BOT | Установка 5 | 6 | 7 | 8 | 9 | 19 |
20 |
21 |
{$_GET['error']}
22 |
23 |
24 | 25 | HTML; 26 | 27 | } 28 | 29 | echo file_get_contents('page/' . $path . '.html'); 30 | ?> 31 | 34 | 37 | 40 | 41 | -------------------------------------------------------------------------------- /quick-start/Install/page/index.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

Установка MVC PHP Bot

5 |

Шаг 1. ACCESS TOKEN и секретный ключ

6 |
7 |
8 | 9 | 10 | 11 | 12 |
13 |
14 | Токен -- это вещь, которая позволяет отсылать сообщения, кикать людей, и т.д от имени вашей группы.
15 | Как его получить?
16 |
    17 |
  • Зайдите в Настройки Группы
    token1
  • 18 |
  • Перейдите во вкладку "Работа с API"
    token2
  • 19 |
  • Нажмите "Создать ключ"
    token3
  • 20 |
  • Выберите все галки, чтобы бот мог работать корректно
    token4
  • 21 |
  • Подтвердите операцию
    token5
  • 22 |
  • Скопируйте токен из поля
    token6
  • 23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
-------------------------------------------------------------------------------- /quick-start/Install/page/ok.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

Установка MVC PHP Bot

5 |

Шаг 2. Настройка CALLBACK сервера

6 |

Все окей! Архив с актуальной версией бота скачан в главную директорию сайта. Нажмите "Продолжить", чтобы скрипт настроил callback сервер

7 | Продолжить 8 |
9 |
10 |
-------------------------------------------------------------------------------- /quick-start/Install/token.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AntonShvets0/MVCBot/fbc5323bd0acf167e5c70498f0f051d66a29e5f5/quick-start/Install/token.txt -------------------------------------------------------------------------------- /src/.htaccess: -------------------------------------------------------------------------------- 1 | 2 | RewriteEngine On 3 | 4 | RewriteRule .* Controller.php 5 | -------------------------------------------------------------------------------- /src/Config/Command.php: -------------------------------------------------------------------------------- 1 | = Handler::GetTimeout()) { 19 | exit('ok'); 20 | } 21 | } 22 | 23 | define('GROUP', $data['group_id']); 24 | Logger::Info("Request CALLBACK data: {$callback}", 3); 25 | 26 | if (isset(Event::$event[$data['type']])) { 27 | FunctionHandler::Call(Event::$event[$data['type']]); 28 | } 29 | 30 | echo 'ok'; -------------------------------------------------------------------------------- /src/Config/config.ini: -------------------------------------------------------------------------------- 1 | [vkCallbackData] 2 | secret = Секретный ключ 3 | confirm = Код подтверждения 4 | 5 | [vkSendData] 6 | v = 5.81 7 | access_token = Токен группы 8 | 9 | [data] 10 | errorChar = @ 11 | unknownCommand = ОШИБКА: Неизвестная команда '{command}' 12 | error = ОШИБКА: {error} -------------------------------------------------------------------------------- /src/Config/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "vkCallbackData": { 3 | "secret": "Секретный ключ", 4 | "confirm": "Код подтверждения" 5 | }, 6 | "vkSendData": { 7 | "v": 5.81, 8 | "access_token": "Токен группы" 9 | }, 10 | "data": { 11 | "errorChar": "@", 12 | "unknownCommand": "ОШИБКА: Неизвестная команда '{command}'", 13 | "error": "ОШИБКА: {error}" 14 | } 15 | } -------------------------------------------------------------------------------- /src/Controller.php: -------------------------------------------------------------------------------- 1 | = 4) { 51 | ini_set('display_errors', 1); 52 | error_reporting(E_ALL); 53 | if (LOGGER_LEVEL >= 5) { 54 | set_error_handler(function () { 55 | $args = array_slice(func_get_args(), 1); 56 | Logger::Warning("Warning: {$args[0]}, file {$args[1]}, line {$args[2]}", 5, true); 57 | }); 58 | } 59 | if (LOGGER_LEVEL >= 4) { 60 | set_exception_handler(function (Throwable $exception) { 61 | echo 'ok'; // Выводим ok, чтобы CALLBACK API не ругался 62 | $message = $exception->getMessage(); 63 | $line = $exception->getLine(); 64 | $file = $exception->getFile(); 65 | Logger::Error("Error: {$message}, file {$file}, line {$line}", 4, true); 66 | }); 67 | } 68 | } 69 | /* ВКЛЮЧАЕМ ПОКАЗ ОШИБОК */ 70 | 71 | /* ИНКЛУДИМ ГЛАВНЫЕ ФАЙЛЫ */ 72 | 73 | require_once ROOT . '/Config/Event.php'; 74 | require_once ROOT . '/Config/Command.php'; 75 | 76 | require_once ROOT . '/Config/Manager.php'; 77 | 78 | /* ИНКЛУДИМ ГЛАВНЫЕ ФАЙЛЫ */ 79 | 80 | function GetFile($path) // Получаем все файлы в папке 81 | { 82 | $files = scandir($path, true); 83 | $pathList = []; 84 | 85 | foreach ($files as $file) { 86 | if ($file == '.' || $file == '..') { 87 | continue; 88 | } elseif (is_dir(ROOT . DIRECTORY_SEPARATOR . $path . DIRECTORY_SEPARATOR . $file)) { 89 | $pathList = array_merge($pathList, GetFile($path . DIRECTORY_SEPARATOR . $file)); 90 | } else { 91 | $pathList[] = ROOT . DIRECTORY_SEPARATOR . $path . DIRECTORY_SEPARATOR . $file; 92 | } 93 | } 94 | 95 | return $pathList; 96 | } 97 | -------------------------------------------------------------------------------- /src/Controller/ControllerTest.php: -------------------------------------------------------------------------------- 1 | getMessage()}, {$exception->getTrace()}"); 49 | return ""; 50 | } 51 | } 52 | 53 | return $response; 54 | } 55 | } -------------------------------------------------------------------------------- /src/Models/Logger.php: -------------------------------------------------------------------------------- 1 | = $level) { 50 | $data = date('H:i:s'); 51 | $file = fopen(self::GetFile($error), 'a+'); 52 | fwrite($file, "[{$data}] [{$type}]: {$message}" . PHP_EOL); 53 | fclose($file); 54 | } 55 | } 56 | 57 | /** 58 | * @param bool $error 59 | * @return string 60 | * Определяет файл для записи 61 | */ 62 | private static function GetFile($error = false) 63 | { 64 | return !$error ? ROOT . '/Log/' . date('d_m_y') . '.txt' : ROOT . '/Log/' . date('d_m_y') . '_err.txt'; 65 | } 66 | } -------------------------------------------------------------------------------- /src/Models/Utils.php: -------------------------------------------------------------------------------- 1 | 4 && $mod < 20 ? 2 : $keys[min($mod%10, 5)]; 50 | 51 | return $value . $suffix[$suffix_key]; 52 | } 53 | 54 | public static function GoId($id) 55 | { 56 | return ltrim(ltrim($id, 2), '0'); 57 | } 58 | } -------------------------------------------------------------------------------- /src/Models/VK/BotConversation.php: -------------------------------------------------------------------------------- 1 | $peerID, 'fields' => Utils::Join($fields)]); 67 | return $data['items'][0] ?? false; 68 | } 69 | 70 | /** 71 | * @param string $peerID 72 | * @return bool 73 | * Удаляет из беседы фото 74 | */ 75 | public static function DeletePhoto($peerID = 'callback') 76 | { 77 | if ($peerID == 'callback') { 78 | $peerID = BotGet::Peer(); 79 | } 80 | 81 | $data = BotRequest::API('messages.deleteChatPhoto', ['chat_id' => $peerID]); 82 | return !$data ? false : true; 83 | } 84 | 85 | /** 86 | * @param $title 87 | * @param string $peerID 88 | * @return bool 89 | * Редактирует заголовок беседы 90 | */ 91 | public static function Title($title, $peerID = 'callback') 92 | { 93 | if ($peerID == 'callback') { 94 | $peerID = BotGet::Peer(); 95 | } 96 | 97 | $data = BotRequest::API('messages.editChat', ['chat_id' => Utils::GoId($peerID), 'title' => $title]); 98 | 99 | return $data; 100 | } 101 | 102 | /** 103 | * @param int $user 104 | * @param string|int $peerID 105 | * @return bool 106 | */ 107 | public static function DeleteUser($user, $peerID = 'callback') 108 | { 109 | if ($peerID == 'callback') { 110 | $peerID = BotGet::Peer(); 111 | } 112 | $peerID = Utils::GoId($peerID); 113 | 114 | return BotRequest::API('messages.removeChatUser', ['chat_id' => $peerID, 'member_id' => $user]); 115 | } 116 | 117 | /** 118 | * @param int $messageID 119 | * @param string $peerID 120 | * @return bool 121 | * Закрепляет сообщение 122 | */ 123 | public static function Pin($messageID, $peerID = 'callback') 124 | { 125 | if ($peerID == 'callback') { 126 | $peerID = BotGet::Peer(); 127 | } 128 | return !BotRequest::API('messages.pin', ['peer_id' => $peerID, 'message_id' => $messageID]) ? false : true; 129 | } 130 | } -------------------------------------------------------------------------------- /src/Models/VK/BotGet.php: -------------------------------------------------------------------------------- 1 | $ids, 'fields' => $fields, 'name_case' => $nameCase]); 121 | } 122 | } -------------------------------------------------------------------------------- /src/Models/VK/BotKeyboard.php: -------------------------------------------------------------------------------- 1 | line >= 10) { 19 | throw new Error('Max size keyboard 4x10'); 20 | } 21 | $this->line++; 22 | $this->button = 0; 23 | return $this; 24 | } 25 | 26 | /** 27 | * @param $text 28 | * @param string $color 29 | * @param array $payLoad 30 | * Добавляет кнопку 31 | */ 32 | public function AddButton($text, $color = 'secondary', $payLoad = []) 33 | { 34 | if (isset($this->result[$this->line]) && count($this->result[$this->line]) >= 4) { 35 | throw new Error('Max size keyboard 4x10'); 36 | } 37 | 38 | $this->result[$this->line][$this->button] = ['color' => $color, 'action' => ['type' => 'text', 'label' => $text, 'payload' => json_encode($payLoad, JSON_UNESCAPED_UNICODE)]]; 39 | $this->button++; 40 | } 41 | 42 | /** 43 | * @param array $payLoad 44 | * Добавляет кнопку, которая отправляет местоположение 45 | */ 46 | public function AddLocationButton($payLoad = []) 47 | { 48 | $this->AddLine(); 49 | $this->result[$this->line][] = ['action' => ['type' => 'location', 'payload' => json_encode($payLoad, JSON_UNESCAPED_UNICODE)]]; 50 | } 51 | 52 | /** 53 | * @param string $hash 54 | * @param array $payLoad 55 | * Добавляет кнопку оплаты 56 | */ 57 | public function AddPayButton($hash, $payLoad = []) 58 | { 59 | $this->AddLine(); 60 | $this->result[$this->line][] = ['action' => ['type' => 'vkpay', 'hash' => $hash, 'payload' => json_encode($payLoad, JSON_UNESCAPED_UNICODE)]]; 61 | } 62 | 63 | /** 64 | * @param string $text 65 | * @param int $app_id 66 | * @param string $hash 67 | * @param string|int $owner_id 68 | * Добавляет кнопку открытия приложения 69 | */ 70 | public function AddAppButton($text, $app_id, $hash = '', $owner_id = 'callback') 71 | { 72 | $this->AddLine(); 73 | 74 | if ($owner_id == 'callback') { 75 | $owner_id = -GROUP; 76 | } 77 | 78 | $this->result[$this->line][] = ['action' => ['type' => 'open_app', 'app_id' => $app_id, 'owner_id' => $owner_id, 'hash' => $hash, 'label' => $text]]; 79 | } 80 | 81 | /** 82 | * @param bool $bool 83 | * Скрывать ли клавиатуру после нажатия на кнопку 84 | */ 85 | public function Hide($bool = true) 86 | { 87 | $this->oneTime = $bool; 88 | } 89 | 90 | /** 91 | * @return false|string 92 | */ 93 | public function Build() 94 | { 95 | $result = ['one_time' => $this->oneTime, 'buttons' => $this->result]; 96 | return json_encode($result, JSON_UNESCAPED_UNICODE); 97 | } 98 | } -------------------------------------------------------------------------------- /src/Models/VK/BotMessage.php: -------------------------------------------------------------------------------- 1 | $peerID, 'message' => $text, 'message_id' => $messageID, 'attachment' => Utils::Join($attach)]); 29 | } 30 | 31 | /** 32 | * @param bool $bool 33 | * @param string|int $peerID 34 | * @return bool 35 | * Статус набора текста 36 | */ 37 | public static function Activity($bool = true, $peerID = 'callback') 38 | { 39 | if ($peerID == 'callback') { 40 | $peerID = BotGet::GetID(); 41 | } 42 | 43 | $type = $bool ? 'typing' : 'audiomessage'; 44 | $data = BotRequest::API('messages.setActivity', ['peer_id' => $peerID, 'type' => $type]); 45 | 46 | return $data; 47 | } 48 | 49 | /** 50 | * @param int|array $messageID 51 | * @return bool 52 | * Удаляет сообщение 53 | */ 54 | public static function Delete($messageID) 55 | { 56 | $messageID = Utils::Join($messageID); 57 | 58 | $data = BotRequest::API('messages.delete', ['message_ids' => $messageID, 'delete_for_all' => 1]); 59 | $bool = false; 60 | 61 | foreach ($data as $val) { 62 | if ($val == 0) { 63 | $bool = false; 64 | } else { 65 | $bool = true; 66 | } 67 | } 68 | 69 | return $bool; 70 | } 71 | 72 | /** 73 | * @param string $message 74 | * @param string|int $id 75 | * @param array|string $attach 76 | * @param string $keyBoard 77 | * @return bool 78 | * Отправляет сообщение 79 | */ 80 | public static function Send($message, $id = 'callback', $attach = [], $keyBoard = "") 81 | { 82 | if ($id == 'callback') { 83 | $id = BotGet::GetID(); 84 | } 85 | 86 | $message = str_replace(['
', '
'], PHP_EOL, $message); 87 | 88 | $count = mb_strlen($message) / 4000; // Ограничение в вк по кол-ву символов на сообщение -- 4000 89 | $count = $count > 1 ? $count : 1; 90 | 91 | $data = false; 92 | 93 | for ($i = 0; $i < $count; $i++) { 94 | $msg = mb_substr($message, $i * 4000, 4000); 95 | 96 | $isLastI = $i >= $count - 1; 97 | 98 | $data = [ 99 | 'random_id' => mt_rand(0, 1000), 100 | 'peer_id' => $id, 101 | 'message' => $msg, 102 | ]; 103 | 104 | if ($isLastI) { 105 | $data['attachment'] = Utils::Join($attach); 106 | $data['keyboard'] = $keyBoard; 107 | } 108 | 109 | $data = BotRequest::API('messages.send', $data); 110 | } 111 | 112 | Logger::Info("Message \"{$message}\" to {$id}", 2); 113 | 114 | return $data ? true : false; 115 | } 116 | } -------------------------------------------------------------------------------- /src/Models/VK/BotOnline.php: -------------------------------------------------------------------------------- 1 | GROUP]); 18 | } 19 | 20 | /** 21 | * @return bool 22 | * Убирает онлайн у группы 23 | */ 24 | public static function Offline() 25 | { 26 | return BotRequest::API('groups.disableOnline', ['group_id' => GROUP]); 27 | } 28 | 29 | /** 30 | * @return array|false 31 | * Возвращает статистику о онлайне 32 | */ 33 | public static function Get() 34 | { 35 | return BotRequest::API('groups.getOnlineStatus', ['group_id' => GROUP]); 36 | } 37 | } -------------------------------------------------------------------------------- /src/Models/VK/BotRequest.php: -------------------------------------------------------------------------------- 1 | self::GetFile($path)]); 20 | 21 | $photo = BotRequest::API('photos.saveMessagesPhoto', ['photo' => $data['photo'], 'server' => $data['server'], 'hash' => $data['hash']]); 22 | 23 | return 'photo' . $photo[0]['owner_id'] . '_' . $photo[0]['id'] . '_' . $photo[0]['access_key']; 24 | } 25 | 26 | private static function GetFile($path) 27 | { 28 | return new CURLFile($path, mime_content_type($path), $path); 29 | } 30 | 31 | private static function GetUploadMessageLink($peerID) 32 | { 33 | return BotRequest::API('photos.getMessagesUploadServer', ['peer_id' => $peerID])['upload_url']; 34 | } 35 | } -------------------------------------------------------------------------------- /src/Models/VK/BotWall.php: -------------------------------------------------------------------------------- 1 | $ownerID, 30 | 'post_id' => $postID, 31 | 'message' => $text, 32 | 'attachments' => Utils::Join($attach) 33 | ]; 34 | 35 | if (!empty($replyTo)) { 36 | $data['reply_to_comment'] = $replyTo; 37 | } 38 | 39 | if (!empty($stickerId)) { 40 | $data['sticker_id'] = $stickerId; 41 | } 42 | 43 | 44 | BotRequest::API('wall.createComment', $data); 45 | } 46 | 47 | /** 48 | * @param int $postID 49 | * @param string $type 50 | * @return void 51 | */ 52 | public static function Comment($postID, $type = 'close') 53 | { 54 | $ownerID = GROUP; 55 | $type = $type == 'close' || $type == 'open' ? $type : 'close'; 56 | 57 | BotRequest::API('wall.' . $type . 'Comments', ['owner_id' => $ownerID, 'post_id' => $postID]); 58 | } 59 | 60 | } -------------------------------------------------------------------------------- /src/Models/VK/Event.php: -------------------------------------------------------------------------------- 1 |