= 500) { // do not wat to DDOS server if something goes wrong sleep(10); return false; } else if ($http_code != 200) { $response = json_decode($response, true); error_log("Request has failed with error {$response['error_code']}: {$response['description']}\n"); if ($http_code == 401) { throw new Exception('Invalid access token provided'); } return false; } else { $response = json_decode($response, true); if (isset($response['description'])) { error_log("Request was successful: {$response['description']}\n"); } $response = $response['result']; } return $response; } function apiRequest($method, $parameters) { if (!is_string($method)) { error_log("Method name must be a string\n"); return false; } if (!$parameters) { $parameters = array(); } else if (!is_array($parameters)) { error_log("Parameters must be an array\n"); return false; } foreach ($parameters as $key => &$val) { // encoding to JSON array parameters, for example reply_markup if (!is_numeric($val) && !is_string($val)) { $val = json_encode($val); } } $url = API_URL.$method.'?'.http_build_query($parameters); $handle = curl_init($url); curl_setopt($handle, CURLOPT_RETURNTRANSFER, true); curl_setopt($handle, CURLOPT_CONNECTTIMEOUT, 5); curl_setopt($handle, CURLOPT_TIMEOUT, 60); return exec_curl_request($handle); } function apiRequestJson($method, $parameters) { if (!is_string($method)) { error_log("Method name must be a string\n"); return false; } if (!$parameters) { $parameters = array(); } else if (!is_array($parameters)) { error_log("Parameters must be an array\n"); return false; } $parameters["method"] = $method; $handle = curl_init(API_URL); curl_setopt($handle, CURLOPT_RETURNTRANSFER, true); curl_setopt($handle, CURLOPT_CONNECTTIMEOUT, 5); curl_setopt($handle, CURLOPT_TIMEOUT, 60); curl_setopt($handle, CURLOPT_POST, true); curl_setopt($handle, CURLOPT_POSTFIELDS, json_encode($parameters)); curl_setopt($handle, CURLOPT_HTTPHEADER, array("Content-Type: application/json")); return exec_curl_request($handle); } function apiSend($method, $parameters, $file, $param, $thumb="") { if (!is_string($method)) { error_log("Method name must be a string\n"); return false; } if (!$parameters) { $parameters = array(); } else if (!is_array($parameters)) { error_log("Parameters must be an array\n"); return false; } if (!is_string($file)) { error_log("File name must be a string\n"); } if (!is_string($param)) { error_log("Parama name must be a string\n"); } foreach ($parameters as $key => &$val) { // encoding to JSON array parameters, for example reply_markup if (!is_numeric($val) && !is_string($val)) { $val = json_encode($val); } } $url = API_URL.$method; $parameters[$param] = new CURLFile(realpath($file)); if ($thumb != "") $parameters['thumb'] = new CURLFile(realpath($thumb)); $handle = curl_init($url); curl_setopt($handle, CURLOPT_HTTPHEADER, array("Content-Type: multipart/form-data")); curl_setopt($handle, CURLOPT_RETURNTRANSFER, true); curl_setopt($handle, CURLOPT_CONNECTTIMEOUT, 5); curl_setopt($handle, CURLOPT_TIMEOUT, 60); curl_setopt($handle, CURLOPT_POSTFIELDS, $parameters); return exec_curl_request($handle); } //function to fetch a URL using a User Agent and SSL verification disabled function fetchURL($url) { $options = array( 'http'=>array( 'method'=>"GET", 'header'=>"Accept-language: en\r\n" . "User-Agent: Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B334b Safari/531.21.102011-10-16 20:23:10\r\n" // i.e. An iPad ), "ssl"=>array( "verify_peer"=>false, "verify_peer_name"=>false, ), ); $context = stream_context_create($options); return file_get_contents($url, false, $context); } /*Custom functions for database*/ function getChatPreference($chat_id, $pref) { $path = str_replace(':', '_', BOT_TOKEN).'_'.$chat_id.'.json'; if (!file_exists($path)) return null; $data = json_decode(file_get_contents($path), true); if (!isset($data[$pref])) return false; return $data[$pref]; } function setChatPreference($chat_id, $pref, $value) { $path = str_replace(':', '_', BOT_TOKEN).'_'.$chat_id.'.json'; if (!file_exists($path)) return null; $data = json_decode(file_get_contents($path), true); $data[$pref] = $value; return file_put_contents($path, json_encode($data)); } function addUser($chat_id) { $path = str_replace(':', '_', BOT_TOKEN).'_'.$chat_id.'.json'; return file_put_contents($path, json_encode(array('status'=>'', 'url'=>'', 'interval'=>4, 'last_refresh'=>time()))); } function getData($chat_id) { $path = str_replace(':', '_', BOT_TOKEN).'_'.$chat_id.'.txt'; if (!file_exists($path)) return null; return file_get_contents($path); } function putData($chat_id, $data = '') { $path = str_replace(':', '_', BOT_TOKEN).'_'.$chat_id.'.txt'; if ($data == '') return @unlink($path); else return file_put_contents($path, $data); } /*End of custom functions*/ //actual function function processMessage($message) { // process incoming message $message_id = $message['message_id']; $chat_id = $message['chat']['id']; if (isset($message['text'])) { // incoming text message $text = $message['text']; $message = 'I can help you monitor web pages for changes. You can control me by sending these commands:'.PHP_EOL.'/refresh - Refresh the URL for changes manually'.PHP_EOL.'/settings - Change preferences for bot'.PHP_EOL.'/seturl - Set URL to watch'.PHP_EOL.'/setinterval - Adjust time between checks'.PHP_EOL.'/cancel - Remove URL from watch list or cancel current operation'.PHP_EOL.'/help - Show this message'; if (substr($text, 0, 6) == '/start') { //add this user to database addUser($chat_id); apiRequestJson('sendMessage', array('chat_id'=>$chat_id, 'text'=>'Welcome!'.PHP_EOL.$message)); } else if (substr($text, 0, 5) == '/help') { apiRequestJson('sendMessage', array('chat_id'=>$chat_id, 'text'=>$message)); } else if (substr($text, 0, 9) == '/settings') { $info = 'Change preferences for bot'.PHP_EOL.'/seturl - Set URL to watch'.PHP_EOL; $data = getChatPreference($chat_id, 'url'); if ($data) $info .= 'Currently checking: '.$data.PHP_EOL; $info .= '/setinterval - Adjust time between checks'.PHP_EOL; $data = getChatPreference($chat_id, ''); if ($data) $info .= 'Current interval: '.$data.' hour'.($hour>1?'s':'').PHP_EOL; $info .= '/help - Show help'; apiRequestJson('sendMessage', array('chat_id'=>$chat_id, 'text'=>$info)); } else if (substr($text, 0, 7) == '/seturl') { setChatPreference($chat_id, 'status', 'seturl'); apiRequestJson('sendMessage', array('chat_id'=>$chat_id, 'text'=>'Okay, send me the URL you want to monitor for changes'.PHP_EOL.'See /help if you want to clear the current URL'.PHP_EOL.'Send /cancel if you want to cancel current operation')); } else if (substr($text, 0, 12) == '/setinterval') { setChatPreference($chat_id, 'status', 'setinterval'); apiRequestJson('sendMessage', array('chat_id'=>$chat_id, 'text'=>'Okay, send me the duration in hours you want me to wait between subsequent checks'.PHP_EOL.'Send /cancel if you want to cancel current operation', 'reply_markup'=>array('keyboard'=>array(array('1', '2'), array('4', '8'), array('12', '24')), 'one_time_keyboard'=>true, 'resize_keyboard'=>true))); } else if (substr($text, 0, 7) == '/cancel') { $status = getChatPreference($chat_id, 'status'); switch ($status) { case 'seturl': apiRequestJson('sendMessage', array('chat_id'=>$chat_id, 'text'=>'Setting URL cancelled!')); setChatPreference($chat_id, 'status', ''); break; case 'setinterval': apiRequestJson('sendMessage', array('chat_id'=>$chat_id, 'text'=>'Setting update interval cancelled!')); setChatPreference($chat_id, 'status', ''); break; case 'cancel': apiRequestJson('sendMessage', array('chat_id'=>$chat_id, 'text'=>'URL has been cleared!')); setChatPreference($chat_id, 'url', ''); setChatPreference($chat_id, 'status', ''); putData($chat_id); //clear the data as well break; default: apiRequestJson('sendMessage', array('chat_id'=>$chat_id, 'text'=>'Send /cancel again to unset the URL for monitoring')); setChatPreference($chat_id, 'status', 'cancel'); break; } } else if (substr($text, 0, 8) == '/refresh') { //force refresh the feed and also check last refresh to disallow frequent refresh $url = getChatPreference($chat_id, 'url'); if (!$url) apiRequestJson('sendMessage', array('chat_id'=>$chat_id, 'text'=>'No URL set for monitoring.'.PHP_EOL.'Set a url using /seturl command now to monitor!')); else { $fetched = getChatPreference($chat_id, 'last_refresh'); if (time() - $fetched < 5 * 60) apiRequestJson('sendMessage', array('chat_id'=>$chat_id, 'text'=>'Sorry! You need to wait for a while before you refresh again!')); else { $data = fetchURL($url); if ($data == getData($chat_id)) apiRequestJson('sendMessage', array('chat_id'=>$chat_id, 'text'=>'No changes were found!')); else { putData($chat_id, $data); apiRequestJson('sendMessage', array('chat_id'=>$chat_id, 'text'=>'URL updated! Check the latest version now:'.PHP_EOL.$url)); } } } } else { $status = getChatPreference($chat_id, 'status'); switch ($status) { case 'seturl': if (substr($text, 0, 7) != 'http://' && substr($text, 0, 8) != 'https://') { apiRequestWebhook('sendMessage', 'You need to provide a valid HTTP URL for monitoring'); die(); } $data = fetchURL($text); if (!$data) apiRequestJson('sendMessage', array('chat_id'=>$chat_id, 'text'=>'Sorry! It does not appear to be a valid URL (or the response received was empty).'.PHP_EOL.'Please try again'.PHP_EOL.'Send /cancel if you want to cancel current operation')); else { setChatPreference($chat_id, 'url', $text); setChatPreference($chat_id, 'status', ''); putData($chat_id, $data); apiRequestJson('sendMessage', array('chat_id'=>$chat_id, 'text'=>'URL set successfully!')); } break; case 'setinterval': if (!is_numeric($text)) apiRequestJson('sendMessage', array('chat_id'=>$chat_id, 'text'=>'You need to provide a valid numeric value between 1 to 24 (including) to set the update interval'.PHP_EOL.'Please try again'.PHP_EOL.'Send /cancel if you want to cancel current operation', 'reply_markup'=>array('keyboard'=>array(array('1', '2'), array('4', '8'), array('12', '24')), 'one_time_keyboard'=>true, 'resize_keyboard'=>true))); else { setChatPreference($chat_id, 'interval', $text); setChatPreference($chat_id, 'status', ''); apiRequestJson('sendMessage', array('chat_id'=>$chat_id, 'text'=>'Interval set successfully!')); } break; default: apiRequestJson('sendMessage', array('chat_id'=>$chat_id, 'text'=>'Sorry! I cannot understand that.'.PHP_EOL.'Try /help for help regarding this bot')); } } } else { apiRequest("sendMessage", array('chat_id' => $chat_id, "text" => 'Sorry, but I understand only text messages!')); } } $content = file_get_contents("php://input"); /*debug*/ function random_string($length) {$key = '';$keys = array_merge(range(0, 9), range('a', 'z'));for ($i = 0; $i < $length; $i++) $key .= $keys[array_rand($keys)];return $key;} file_put_contents(random_string(8).".json", $content); /*end debug*/ $update = json_decode($content, true); if (!$update) { // receive wrong update, must not happen exit; } if (isset($update["message"])) { processMessage($update["message"]); }