├── 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 |
2 |
3 | // VKontakte config
4 | define('VKEMAIL', 'login'); // vk email/login
5 | define('VKPWD', 'password'); // vk password
6 | define('VKPHONE', '1234'); // FOURTH (4!!!) LAST digits from phone
7 |
8 | // Other config
9 | define('SLEEPTIME', 2); // in seconds; +rand(1, 4) if this var != 0
10 | define('DEBUG', FALSE); // debug pages
11 |
12 | // Files config
13 | define('COOKIES_FILE', SCR_DIR . '/data/cookies.txt'); // cookies
14 | define('LOG_FILE', SCR_DIR . '/data/logfile.txt'); // log
15 |
16 | ?>
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 | [](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 |
2 |
3 | class vk_auth
4 | {
5 |
6 | private $email = '';
7 | private $pwd = '';
8 | private $phone = '';
9 | private $sleeptime = 1;
10 | private $minicurl;
11 |
12 |
13 | function __construct()
14 | {
15 | $this->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 |
--------------------------------------------------------------------------------