├── data ├── cookies.txt └── logfile.txt ├── config.php ├── README.md ├── example.php └── classes ├── minicurl.class.php └── vk_poster.class.php /data/cookies.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /data/logfile.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /config.php: -------------------------------------------------------------------------------- 1 | 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### Требования 2 | 1. PHP 4/5 3 | 2. [cURL](http://ru.php.net/manual/en/book.curl.php) 4 | 5 | ### Установка и настройка 6 | 1. Склонируйте репозиторий. 7 | 2. Задайте права на запись для файлов из папки /data 8 | 3. Введите свои данные для конфигурации в файл /config.php 9 | 4. По примеру из /example.php сделайте постинг своих сообщений на нужные страницы. 10 | 11 | ### [Использование](https://github.com/saippuakauppias/vk-wallposter/wiki) 12 | 13 | ### ToDo 14 | 1. Прикрепление файлов к сообщениям. 15 | 16 | [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/saippuakauppias/vk-wallposter/trend.png)](https://bitdeli.com/free "Bitdeli Badge") 17 | 18 | -------------------------------------------------------------------------------- /example.php: -------------------------------------------------------------------------------- 1 | check_auth()) 23 | { 24 | echo 'Authorised in vk!
'; 25 | } 26 | else 27 | { 28 | echo $vk->print_last_error(); 29 | exit(); 30 | } 31 | 32 | // сообщение для публикации (обязательно в UTF-8) 33 | $message = 'http://blog.lalf.ru/'; 34 | 35 | // впишите тут идентификатор пользователя 36 | $uid = rand(1000000, 90000000); 37 | 38 | // публикация сообщения на странице юзера контакта 39 | if ($vk->post_to_user($uid, $message)) 40 | { 41 | echo 'Posted in user page!'; 42 | } 43 | else 44 | { 45 | echo $vk->print_last_error(); 46 | exit(); 47 | } 48 | 49 | // впишите тут идентификатор группы 50 | $gid = rand(1000000, 90000000); 51 | 52 | // публикация сообщения в группе 53 | if ($vk->post_to_group($gid, $message)) 54 | { 55 | echo 'Posted in group!'; 56 | } 57 | else 58 | { 59 | echo $vk->print_last_error(); 60 | exit(); 61 | } 62 | 63 | // впишите тут идентификатор паблика 64 | $pid = rand(1000000, 90000000); 65 | 66 | // публикация сообщения на публичной странице 67 | if ($vk->post_to_public_page($pid, $message)) 68 | { 69 | echo 'Posted in public page!'; 70 | } 71 | else 72 | { 73 | echo $vk->print_last_error(); 74 | exit(); 75 | } 76 | 77 | ?> 78 | -------------------------------------------------------------------------------- /classes/minicurl.class.php: -------------------------------------------------------------------------------- 1 | headers = $headers; 22 | $this->cookies_file = $cookies_file; 23 | $this->proxy = $proxy; 24 | $this->proxy_port = $proxy_port; 25 | $this->proxy_type = $proxy_type; 26 | $this->user_agent = $user_agent; 27 | } 28 | 29 | public function set_cookies($cookies) 30 | { 31 | // TODO: скорее всего не будет работать с несколькими куками сразу... 32 | if (strpos($this->cookies, $cookies) === FALSE) 33 | { 34 | $this->cookies .= $cookies; 35 | } 36 | } 37 | 38 | public function get_file($url, $postfields=FALSE, $referer=FALSE) 39 | { 40 | $this->referer = $referer; 41 | $this->postfields = (is_array($postfields) ? http_build_query($postfields) : $postfields); 42 | 43 | return $this->cURL_get_file($url); 44 | } 45 | 46 | public function clear_cookies() 47 | { 48 | if(!empty($this->cookies_file)) 49 | { 50 | @chmod($this->cookies_file, 0777); 51 | $fp = fopen($this->cookies_file, 'w'); 52 | fclose($fp); 53 | @chmod($this->cookies_file, 0777); 54 | } 55 | 56 | $this->cookies = ''; 57 | } 58 | 59 | public function debug_pages() 60 | { 61 | return $self->debug_pages; 62 | } 63 | 64 | private function cURL_get_file($url) 65 | { 66 | $url = (strpos($url, '#') ? current(explode('#', $url)) : $url); 67 | 68 | $ch = curl_init($url); 69 | curl_setopt($ch, CURLOPT_HEADER, $this->headers); 70 | curl_setopt($ch, CURLOPT_NOBODY, FALSE); 71 | // safe_mode || open_basedir 72 | curl_setopt($ch, CURLOPT_FOLLOWLOCATION, FALSE); 73 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); 74 | curl_setopt($ch, CURLOPT_USERAGENT, $this->user_agent); 75 | 76 | if (empty($this->cookies)) 77 | { 78 | curl_setopt($ch, CURLOPT_COOKIEJAR, $this->cookies_file); 79 | curl_setopt($ch, CURLOPT_COOKIEFILE, $this->cookies_file); 80 | } 81 | else 82 | { 83 | curl_setopt($ch, CURLOPT_COOKIE, $this->cookies); 84 | } 85 | 86 | if ($this->postfields) 87 | { 88 | curl_setopt($ch, CURLOPT_POST, TRUE); 89 | curl_setopt($ch, CURLOPT_POSTFIELDS, $this->postfields); 90 | } 91 | 92 | if($this->proxy) 93 | { 94 | curl_setopt($ch, CURLOPT_PROXY, $this->proxy); 95 | curl_setopt($ch, CURLOPT_PROXYPORT, $this->proxy_port); 96 | 97 | if ($this->proxy_type == 1) 98 | { 99 | curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4); 100 | } 101 | elseif ($this->proxy_type == 2) 102 | { 103 | curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5); 104 | } 105 | } 106 | 107 | if ($this->referer) 108 | { 109 | curl_setopt($ch, CURLOPT_REFERER, $this->referer); 110 | } 111 | 112 | $result = curl_exec($ch); 113 | $error = curl_errno($ch); 114 | 115 | if (defined('DEBUG') AND (DEBUG == TRUE)) 116 | { 117 | $self->debug_pages[$url] = $result; 118 | } 119 | 120 | if ($error != '0') { 121 | // TODO: add exceptions 122 | echo '
cURL error (' , $error , '): ' , curl_error($ch) , '
'; 123 | @ob_flush(); @flush(); 124 | 125 | curl_close($ch); 126 | 127 | return FALSE; 128 | } else { 129 | curl_close($ch); 130 | 131 | return $result; 132 | } 133 | } 134 | } 135 | 136 | ?> 137 | -------------------------------------------------------------------------------- /classes/vk_poster.class.php: -------------------------------------------------------------------------------- 1 | email = VKEMAIL; 16 | $this->pwd = VKPWD; 17 | $this->phone = VKPHONE; 18 | $this->sleeptime = SLEEPTIME; 19 | $this->minicurl = new minicurl(TRUE, COOKIES_FILE, 'Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1'); 20 | } 21 | 22 | /* 23 | * public auth functions 24 | */ 25 | 26 | public function check_auth() 27 | { 28 | if (strlen($this->phone) != 4) 29 | { 30 | $this->put_error_in_logfile('4 LAST DIGITS from phone!!!'); 31 | exit(); 32 | } 33 | 34 | if($this->need_auth()) 35 | { 36 | if(!$this->auth()) 37 | { 38 | $this->put_error_in_logfile('Not authorised!'); 39 | return FALSE; 40 | } 41 | } 42 | 43 | return TRUE; 44 | } 45 | 46 | /* 47 | * public posting functions 48 | */ 49 | 50 | public function post_to_user($user_id, $message, $friends_only=FALSE) 51 | { 52 | // check_auth() - так ли тут нужно? по-моему, нет 53 | 54 | if (!is_numeric($user_id)) 55 | { 56 | $this->put_error_in_logfile('$user_id - only numbers!'); 57 | return FALSE; 58 | } 59 | 60 | $hash = $this->get_hash('id' . $user_id); 61 | if (empty($hash)) 62 | { 63 | $this->put_error_in_logfile('JS-Field "post_hash" not found!'); 64 | return FALSE; 65 | } 66 | 67 | if(!$this->post_to_wall_query($hash, $user_id, $message, FALSE, $friends_only, 'feed')) 68 | { 69 | $this->put_error_in_logfile('Message not posted!'); 70 | return FALSE; 71 | } 72 | 73 | return TRUE; 74 | } 75 | 76 | public function post_to_group($group_id, $message, $official=FALSE) 77 | { 78 | if (!is_numeric($group_id)) 79 | { 80 | $this->put_error_in_logfile('$group_id - only numbers!'); 81 | return FALSE; 82 | } 83 | 84 | $hash = $this->get_hash('club' . $group_id); 85 | if (empty($hash)) 86 | { 87 | $this->put_error_in_logfile('JS-Field "post_hash" not found!'); 88 | return FALSE; 89 | } 90 | 91 | $group_id = '-' . $group_id; 92 | 93 | if(!$this->post_to_wall_query($hash, $group_id, $message, $official, FALSE)) 94 | { 95 | $this->put_error_in_logfile('Message not posted!'); 96 | return FALSE; 97 | } 98 | 99 | return TRUE; 100 | } 101 | 102 | public function post_to_public_page($page_id, $message) 103 | { 104 | if (!is_numeric($page_id)) 105 | { 106 | $this->put_error_in_logfile('$page_id - only numbers!'); 107 | return FALSE; 108 | } 109 | 110 | $hash = $this->get_hash('public' . $page_id); 111 | if (empty($hash)) 112 | { 113 | $this->put_error_in_logfile('JS-Field "post_hash" not found!'); 114 | return FALSE; 115 | } 116 | 117 | $page_id = '-' . $page_id; 118 | 119 | if(!$this->post_to_wall_query($hash, $page_id, $message)) 120 | { 121 | $this->put_error_in_logfile('Message not posted!'); 122 | return FALSE; 123 | } 124 | 125 | return TRUE; 126 | } 127 | 128 | /* 129 | * public other functions 130 | */ 131 | 132 | public function print_last_error() 133 | { 134 | if (defined('DEBUG') AND (DEBUG == TRUE)) 135 | { 136 | var_dump($self->minicurl->debug_pages()); 137 | } 138 | 139 | $errors = array_reverse(file(LOG_FILE)); 140 | return 'Error!
' . $errors[0]; 141 | } 142 | 143 | /* 144 | * private auth functions 145 | */ 146 | 147 | private function need_auth() 148 | { 149 | $result = $this->minicurl->get_file('http://vk.com/settings'); 150 | $this->sleep(); 151 | return strpos($result, 'HTTP/1.1 302 Found') !== FALSE; 152 | } 153 | 154 | private function auth() 155 | { 156 | $this->minicurl->clear_cookies(); 157 | 158 | $location = $this->get_auth_location(); 159 | if($location === FALSE){ 160 | $this->put_error_in_logfile('Not recieved Location!'); 161 | return FALSE; 162 | } 163 | 164 | $sid = $this->get_auth_cookies($location); 165 | if(!$sid){ 166 | $this->put_error_in_logfile('Not received cookies!'); 167 | return FALSE; 168 | } 169 | 170 | $this->minicurl->set_cookies('remixsid=' . $sid . '; path=/; domain=.vk.com'); 171 | 172 | return TRUE; 173 | } 174 | 175 | private function get_auth_location() 176 | { 177 | $html = $this->minicurl->get_file('http://vk.com/'); 178 | preg_match('##isU', $html, $matches); 179 | 180 | $post = array( 181 | 'act' => 'login', 182 | 'al_frame' => '1', 183 | 'captcha_key' => '', 184 | 'captcha_sid' => '', 185 | 'email' => $this->email, 186 | 'expire' => '', 187 | 'from_host' => 'vk.com', 188 | 'ip_h' => (isset($matches[1]) ? $matches[1]: ''), 189 | 'pass' => $this->pwd, 190 | 'q' => '1', 191 | ); 192 | 193 | $auth = $this->minicurl->get_file('http://login.vk.com/?act=login', $post, 'http://vk.com/'); 194 | preg_match('#Location\: ([^\r\n]+)#is', $auth, $match); 195 | 196 | $this->sleep(); 197 | return ((isset($match[1])) ? $match[1] : FALSE); 198 | } 199 | 200 | private function get_auth_cookies($location) 201 | { 202 | $result = $this->minicurl->get_file($location); 203 | 204 | $this->sleep(); 205 | return ((strpos($result, "setCookieEx('sid', ") === FALSE) ? FALSE : 206 | substr($result, strpos($result, "setCookieEx('sid', '") + 20, 60)); 207 | } 208 | 209 | /* 210 | * private posting functions 211 | */ 212 | 213 | private function post_to_wall_query($hash, $to_id, $message, $official=FALSE, $friends_only=FALSE, $type='all') 214 | { 215 | $official = $official ? '1' : ''; 216 | $friends_only = $friends_only ? '1' : ''; 217 | 218 | $post = array( 219 | 'act' => 'post', 220 | 'al' => '1', 221 | 'facebook_export' => '', 222 | 'friends_only' => $friends_only, 223 | 'hash' => $hash, 224 | 'message' => $message, 225 | 'note_title' => '', 226 | 'official' => $official, 227 | 'status_export' => '', 228 | 'to_id' => $to_id, 229 | 'type' => $type, 230 | ); 231 | 232 | $result = $this->minicurl->get_file('http://vk.com/al_wall.php', $post); 233 | 234 | $this->sleep(); 235 | preg_match('#>\d\d+([\d]+)#isU', $result, $match); 236 | 237 | return (isset($match[1]) AND ($match[1] == '0')); 238 | } 239 | 240 | private function get_hash($page_id) 241 | { 242 | $result = $this->minicurl->get_file('http://vk.com/' . $page_id); 243 | $this->sleep(); 244 | 245 | preg_match('#Location\: ([^\r\n]+)#is', $result, $match); 246 | if (isset($match[1]) AND !empty($match[1])) 247 | { 248 | $result = $this->minicurl->get_file('http://vk.com' . $match[1]); 249 | $this->sleep(); 250 | unset($match); 251 | 252 | preg_match("#act: '([^']+)', code: ge\('code'\)\.value, to: '([^']+)', al_page: '([^']*)', hash: '([^']+)'#i", $result, $match); 253 | 254 | $post = array( 255 | 'act' => $match[1], 256 | 'al' => '1', // хз что это 257 | 'al_page' => $match[3], 258 | 'code' => $this->phone, 259 | 'hash' => $match[4], 260 | 'to' => $match[2] 261 | ); 262 | 263 | $result = $this->minicurl->get_file('http://vk.com/login.php', $post); 264 | $this->sleep(); 265 | unset($match); 266 | 267 | preg_match('#>/([a-z0-9\.\-_]+)<#is', $result, $match); 268 | 269 | if (isset($match[1]) AND !empty($match[1])) 270 | { 271 | $result = $this->minicurl->get_file('http://vk.com/' . $match[1]); 272 | $this->sleep(); 273 | unset($match); 274 | } 275 | } 276 | preg_match('#"post_hash":"([^"]+)"#isU', $result, $match); 277 | 278 | if (strpos($result, 'action="https://login.vk.com/?act=login')) 279 | { 280 | unset($match[1]); 281 | } 282 | 283 | return (isset($match[1]) ? $match[1] : ''); 284 | } 285 | 286 | /* 287 | * private other functions 288 | */ 289 | 290 | private function sleep() 291 | { 292 | if ($this->sleeptime) 293 | { 294 | sleep($this->sleeptime + rand(1, 4)); 295 | } 296 | } 297 | 298 | private function put_error_in_logfile($msg) 299 | { 300 | $msg = '[' . date('Y.m.d H:i:s') . ']: ' . $msg . "\n"; 301 | $fp = fopen(LOG_FILE, 'a'); 302 | fwrite($fp, $msg); 303 | fclose($fp); 304 | } 305 | } 306 | 307 | ?> 308 | --------------------------------------------------------------------------------