/** * Do a tracker_log incase anything went wrong with a query. */ function checkDatabaseInsert($query) { global $DBH; if (!$query) { $e_code = $DBH->errorInfo()[1]; $e_msg = $DBH->errorInfo()[2]; // Database constraint if ($e_code != 7) { tracker_log('[error] Database exception: code: ' . $e_code . ', message: ' . $e_msg); } else { tracker_debug('[assumed safe error] Database exception: code: ' . $e_code . ', message: ' . $e_msg); } } return $query; }
/** * CONTINIOUS TRACKING * Tracking: * - User status changes to track if a user is online/offline * - User lastseen (privacy options) (attached to online/offline status) * - User profile pictures (and changes) * - User status message (and changes) */ function track() { global $DBH, $wa, $tracking_ticks, $tracking_numbers, $whatsspyNotificatons, $crawl_time, $whatsappAuth, $pollCount, $lastseenCount, $statusMsgCount, $picCount, $request_error_queue, $continue_tracker_session, $whatsspyPerformanceMode; $crawl_time = time(); setupWhatsappHandler(); retrieveTrackingUsers(); tracker_log('[init] Started tracking with phonenumber ' . $whatsappAuth['number']); if ($continue_tracker_session == false) { startTrackerHistory(); sendNotification($DBH, null, $whatsspyNotificatons, 'tracker', ['title' => 'WhatsSpy Public has started tracking!', 'description' => 'tracker has started tracking ' . count($tracking_numbers) . ' users.', 'event-type' => 'start']); } else { $continue_tracker_session = false; } while (true) { $crawl_time = time(); // Socket read $tick_start = microtime(true); if ($whatsspyPerformanceMode === true) { while (microtime(true) - $tick_start < 1.0 && $wa->pollMessage() === true) { echo microtime(true) - $tick_start . "\r\n"; tracker_debug('Socket read called with poll time: ' . microtime(true) - $tick_start); } } else { $wa->pollMessage(); } $tick_end = microtime(true); $poll_took = number_format($tick_end - $tick_start, 4); // Check if database set is up to date if (count($tracking_numbers) > base64_decode('NzAw')) { tracker_log(base64_decode("UEiQOiBGYXRhbCBFcnJvcjogVHJhY2tpbmcgdG9vIG1hbnkgY29udGFjdHMsIGFib3J0aW5nIHRyYWNraW5nLg=="), true, true); exit; } list($usec, $sec) = explode(' ', microtime()); // split the microtime on space with two tokens $usec and $sec. $usec = str_replace("0.", ".", number_format($usec, 4)); // remove the leading '0.' from usec tracker_log("[poll #{$pollCount}] Tracking " . count($tracking_numbers) . " users (poll took {$poll_took})", true, false); // 1) STATUS MESSAGE (and privacy) // // Check status message if ($pollCount % calculateTick($tracking_ticks['statusmsg']) == 0) { tracker_log('[status-msg #' . $statusMsgCount . '] Checking ' . count($tracking_numbers) . ' users.'); if (count($tracking_numbers) > 0) { $wa->sendGetStatuses($tracking_numbers); } $statusMsgCount++; } // 2) PROFILE PICTURE (and privacy) // // Check profile picture if ($pollCount % calculateTick($tracking_ticks['profile-pic']) == 0) { tracker_log('[profile-pic #' . $picCount . '] Checking ' . count($tracking_numbers) . ' users.'); foreach ($tracking_numbers as $number) { $wa->sendGetProfilePicture($number, true); } $picCount++; } // 3) DATABASE ACCOUNT REFRESH // // Check user database and refresh user set every hour but with a offset of 80 seconds. if ($pollCount % calculateTick($tracking_ticks['refresh-db']) == calculateTick($tracking_ticks['refresh-db'] - 80)) { retrieveTrackingUsers(true); } // 4) SOCKET RESET AND LOGIN // // Disconnect and reconnect with whatsapp to prevent dead tracker if ($pollCount % calculateTick($tracking_ticks['reset-socket']) == calculateTick($tracking_ticks['reset-socket'] - 40)) { resetSocket(); retrieveTrackingUsers(false); } // 5) DATABASE ACCOUNT VERIFY CHECK // // Verify any freshly inserted accounts and check if there really whatsapp users. // Check everey 5 minutes. // When the user is verified the number is automaticly added to the tracker running DB. if ($pollCount % calculateTick($tracking_ticks['verify-check']) == 0) { verifyTrackingUsers(); } // 6) WHATSAPP PING // // Keep connection alive (<300s) if ($pollCount % calculateTick($tracking_ticks['keep-alive']) == 0) { tracker_log('[keep-alive] Ping sent.', true, false); $wa->sendPing(); } // usage of 39512f5ea29c597f25483697471ac0b00cbb8088359c219e98fa8bdaf7e079fa $pollCount++; // Sleep if no more messages could be processed. if ($poll_took < 1.0) { $sleeping = 1.0 - $poll_took; usleep($sleeping * 1000000); } } }
/** * CONTINIOUS TRACKING * Tracking: * - User status changes to track if a user is online/offline * - User lastseen (privacy options) * - User profile pictures (and changes) * - User status message (and changes) */ function track() { global $DBH, $wa, $tracking_ticks, $tracking_numbers, $whatsspyNotificatons, $crawl_time, $whatsappAuth, $pollCount, $lastseenCount, $statusMsgCount, $picCount, $request_error_queue, $continue_tracker_session; $crawl_time = time(); setupWhatsappHandler(); retrieveTrackingUsers(); tracker_log('[init] Started tracking with phonenumber ' . $whatsappAuth['number']); if ($continue_tracker_session == false) { startTrackerHistory(); sendNotification($DBH, null, $whatsspyNotificatons, 'tracker', ['title' => 'WhatsSpy Public has started tracking!', 'description' => 'tracker has started tracking ' . count($tracking_numbers) . ' users.', 'event-type' => 'start']); } else { $continue_tracker_session = false; } while (true) { $crawl_time = time(); // Socket read $tick_start = microtime(true); $wa->pollMessage(); $tick_end = microtime(true); tracker_log('[poll #' . $pollCount . '] Tracking ' . count($tracking_numbers) . ' users. ' . "\r", true, false); // 1) LAST SEEN PRIVACY // // Check lastseen if ($pollCount % calculateTick($tracking_ticks['lastseen']) == 0) { tracker_log('[lastseen #' . $lastseenCount . '] Checking ' . count($tracking_numbers) . ' users. '); foreach ($tracking_numbers as $number) { $wa->sendGetRequestLastSeen($number); } $lastseenCount++; } // 2) STATUS MESSAGE (and privacy) // // Check status message if ($pollCount % calculateTick($tracking_ticks['statusmsg']) == 0) { tracker_log('[status-msg #' . $statusMsgCount . '] Checking ' . count($tracking_numbers) . ' users.'); if (count($tracking_numbers) > 0) { $wa->sendGetStatuses($tracking_numbers); } $statusMsgCount++; } // 3) PROFILE PICTURE (and privacy) // // Check profile picture if ($pollCount % calculateTick($tracking_ticks['profile-pic']) == 0) { tracker_log('[profile-pic #' . $picCount . '] Checking ' . count($tracking_numbers) . ' users.'); foreach ($tracking_numbers as $number) { $wa->sendGetProfilePicture($number, true); } $picCount++; } // 4) DATABASE ACCOUNT REFRESH // // Check user database and refresh user set every hour but with a offset of 80 seconds. if ($pollCount % calculateTick($tracking_ticks['refresh-db']) == calculateTick($tracking_ticks['refresh-db'] - 80)) { retrieveTrackingUsers(true); } // 5) SOCKET RESET AND LOGIN // // Disconnect and reconnect with whatsapp to prevent dead tracker if ($pollCount % calculateTick($tracking_ticks['reset-socket']) == calculateTick($tracking_ticks['reset-socket'] - 40)) { resetSocket(); retrieveTrackingUsers(false); } // 6) DATABASE ACCOUNT VERIFY CHECK // // Verify any freshly inserted accounts and check if there really whatsapp users. // Check everey 5 minutes. // When the user is verified the number is automaticly added to the tracker running DB. if ($pollCount % calculateTick($tracking_ticks['verify-check']) == 0) { verifyTrackingUsers(); } // 7) WHATSAPP PING // // Keep connection alive (<300s) if ($pollCount % calculateTick($tracking_ticks['keep-alive']) == 0) { tracker_log('[keep-alive] Ping sent.' . "\r", true, false); $wa->sendPing(); } // usage of 39512f5ea29c597f25483697471ac0b00cbb8088359c219e98fa8bdaf7e079fa $pollCount++; // Draw the socket read a draw if ($tick_end - $tick_start < 1.0) { sleep(1); } } }
/** * Check if the user's config is up to standards and attempt to (temp) fix this. */ function checkConfig() { global $whatsappAuth, $whatsspyNotificatons, $whatsspyAdvControls, $whatsspyErrorHandling, $whatsspyHeuristicOptions, $whatsspyPerformanceMode; $notice = false; // Check if config is filled in. if ($whatsappAuth['secret'] === '') { tracker_log('[config] number and secret fields are required for the tracker to operate.'); exit; } // Check if debug is set if ($whatsappAuth['debug'] !== false && $whatsappAuth['debug'] !== true) { tracker_log('[config] $whatsappAuth[\'debug\'] missing (assuming false).'); $notice = true; $whatsappAuth['debug'] = false; } // Check if new notification structure is used. if ($whatsspyNotificatons === null) { tracker_log('[config] $whatsspyNotificatons missing (notifications disabled).'); $notice = true; $whatsspyNotificatons = []; } if ($whatsspyAdvControls === null) { $whatsspyAdvControls = ['enabled' => false]; } if ($whatsspyErrorHandling === null) { tracker_log('[config] $whatsspyErrorHandling missing (using default options).'); $notice = true; $whatsspyErrorHandling = ['ignoreConnectionClosed' => false]; } if ($whatsspyHeuristicOptions === null) { tracker_log('[config] $whatsspyHeuristicOptions missing (using default options).'); $notice = true; $whatsspyHeuristicOptions = ['onPresenceAvailableLag' => -2, 'onPresenceUnavailableLagFase1' => -12, 'onPresenceUnavailableLagFase2' => -8, 'onPresenceUnavailableLagFase3' => -5]; } if ($whatsspyPerformanceMode === null) { $whatsspyPerformanceMode = false; } if ($notice) { tracker_log('[config] Please copy over the missing variables from config.example.php (starting in 2s).'); sleep(2); } }