require __DIR__ . '/vendor/autoload.php'; // Google Drive API
// HTTPS Authentication
$masterToken = getMasterTokenForAccount("your_username@gmail.com", "your_password");
$appSignature = '38a0f7d505fe18fec64fbf343ecaaaf310dbd799';
$appID = 'com.whatsapp';
$accessToken = getGoogleDriveAccessToken($masterToken, $appID, $appSignature);
if ($accessToken === false) return;
// Initializing the Google Drive Client
$client = new Google_Client();
$client->setAccessToken($accessToken);
$client->addScope(Google_Service_Drive::DRIVE_APPDATA);
$client->addScope(Google_Service_Drive::DRIVE_FILE);
$client->setClientId(""); // client id and client secret can be left blank
$client->setClientSecret(""); // because we're faking an android client
$service = new Google_Service_Drive($client);
// Print the names and IDs for up to 10 files.
'spaces' => 'appDataFolder',
'fields' => 'nextPageToken, files(id, name)',
'pageSize' => 10
);
$results = $service->files->listFiles($optParams);
if (count($results->getFiles()) == 0) {
print "No files found.\n";
}
else
{
print "Files:\n";
foreach ($results->getFiles() as $file)
{
print $file->getName() . " (" . $file->getId() . ")\n";
}
}
/*
$fileId = '1kTFG5TmgIGTPJuVynWfhkXxLPgz32QnPJCe5jxL8dTn0';
$content = $service->files->get($fileId, array('alt' => 'media' ));
echo var_dump($content);
*/
function getGoogleDriveAccessToken($masterToken, $appIdentifier, $appSignature)
{
if ($masterToken === false) return false;
$url = 'https://android.clients.google.com/auth';
$deviceID = '0000000000000000';
$requestedService = 'oauth2:https://w...content-available-to-author-only...s.com/auth/drive.appdata https://w...content-available-to-author-only...s.com/auth/drive.file';
$data = array('Token' => $masterToken, 'app' => $appIdentifier, 'client_sig' => $appSignature, 'device' => $deviceID, 'google_play_services_version' => '8703000', 'service' => $requestedService, 'has_permission' => '1');
'header' => "Content-type: application/x-www-form-urlencoded\r\nConnection: close",
'method' => 'POST',
'ignore_errors' => TRUE,
'protocol_version'=>'1.1',
//'proxy' => 'tcp://127.0.0.1:8080', // optional proxy for debugging
//'request_fulluri' => true
)
);
if (strpos($http_response_header[0], '200 OK') === false) {
/* Handle error */
print 'An error occured while requesting an access token: ' . $result . "\r\n";
return false;
}
$endsAt = strpos($result, "\n", $startsAt); $accessToken = substr($result, $startsAt, $endsAt - $startsAt);
return "{\"access_token\":\"" . $accessToken . "\", \"refresh_token\":\"TOKEN\", \"token_type\":\"Bearer\", \"expires_in\":360000, \"id_token\":\"TOKEN\", \"created\":" . time() . "}"; }
function getMasterTokenForAccount($email, $password)
{
$url = 'https://android.clients.google.com/auth';
$deviceID = '0000000000000000';
$data = array('Email' => $email, 'Passwd' => $password, 'app' => 'com.google.android.gms', 'client_sig' => '38918a453d07199354f8b19af05ec6562ced5788', 'parentAndroidId' => $deviceID);
'header' => "Content-type: application/x-www-form-urlencoded\r\nConnection: close",
'method' => 'POST',
'ignore_errors' => TRUE,
'protocol_version'=>'1.1',
//'proxy' => 'tcp://127.0.0.1:8080', // optional proxy for debugging
//'request_fulluri' => true
)
);
if (strpos($http_response_header[0], '200 OK') === false) {
/* Handle error */
print 'An error occured while trying to log in: ' . $result . "\r\n";
return false;
}
$endsAt = strpos($result, "\n", $startsAt); $token = substr($result, $startsAt, $endsAt - $startsAt);
return $token;
}
cmVxdWlyZSBfX0RJUl9fIC4gJy92ZW5kb3IvYXV0b2xvYWQucGhwJzsgLy8gR29vZ2xlIERyaXZlIEFQSQoKLy8gSFRUUFMgQXV0aGVudGljYXRpb24KJG1hc3RlclRva2VuID0gZ2V0TWFzdGVyVG9rZW5Gb3JBY2NvdW50KCJ5b3VyX3VzZXJuYW1lQGdtYWlsLmNvbSIsICJ5b3VyX3Bhc3N3b3JkIik7CiRhcHBTaWduYXR1cmUgPSAnMzhhMGY3ZDUwNWZlMThmZWM2NGZiZjM0M2VjYWFhZjMxMGRiZDc5OSc7CiRhcHBJRCA9ICdjb20ud2hhdHNhcHAnOwokYWNjZXNzVG9rZW4gPSBnZXRHb29nbGVEcml2ZUFjY2Vzc1Rva2VuKCRtYXN0ZXJUb2tlbiwgJGFwcElELCAkYXBwU2lnbmF0dXJlKTsKCmlmICgkYWNjZXNzVG9rZW4gPT09IGZhbHNlKSByZXR1cm47CgovLyBJbml0aWFsaXppbmcgdGhlIEdvb2dsZSBEcml2ZSBDbGllbnQKJGNsaWVudCA9IG5ldyBHb29nbGVfQ2xpZW50KCk7CiRjbGllbnQtPnNldEFjY2Vzc1Rva2VuKCRhY2Nlc3NUb2tlbik7CiRjbGllbnQtPmFkZFNjb3BlKEdvb2dsZV9TZXJ2aWNlX0RyaXZlOjpEUklWRV9BUFBEQVRBKTsKJGNsaWVudC0+YWRkU2NvcGUoR29vZ2xlX1NlcnZpY2VfRHJpdmU6OkRSSVZFX0ZJTEUpOwokY2xpZW50LT5zZXRDbGllbnRJZCgiIik7ICAgIC8vIGNsaWVudCBpZCBhbmQgY2xpZW50IHNlY3JldCBjYW4gYmUgbGVmdCBibGFuawokY2xpZW50LT5zZXRDbGllbnRTZWNyZXQoIiIpOyAvLyBiZWNhdXNlIHdlJ3JlIGZha2luZyBhbiBhbmRyb2lkIGNsaWVudAokc2VydmljZSA9IG5ldyBHb29nbGVfU2VydmljZV9Ecml2ZSgkY2xpZW50KTsKCi8vIFByaW50IHRoZSBuYW1lcyBhbmQgSURzIGZvciB1cCB0byAxMCBmaWxlcy4KJG9wdFBhcmFtcyA9IGFycmF5KAogICAgJ3NwYWNlcycgPT4gJ2FwcERhdGFGb2xkZXInLAogICAgJ2ZpZWxkcycgPT4gJ25leHRQYWdlVG9rZW4sIGZpbGVzKGlkLCBuYW1lKScsCiAgICAncGFnZVNpemUnID0+IDEwCik7CiRyZXN1bHRzID0gJHNlcnZpY2UtPmZpbGVzLT5saXN0RmlsZXMoJG9wdFBhcmFtcyk7CgppZiAoY291bnQoJHJlc3VsdHMtPmdldEZpbGVzKCkpID09IDApIAp7CiAgICBwcmludCAiTm8gZmlsZXMgZm91bmQuXG4iOwp9IAplbHNlIAp7CiAgICBwcmludCAiRmlsZXM6XG4iOwogICAgZm9yZWFjaCAoJHJlc3VsdHMtPmdldEZpbGVzKCkgYXMgJGZpbGUpIAogICAgewogICAgICAgIHByaW50ICRmaWxlLT5nZXROYW1lKCkgLiAiICgiIC4gJGZpbGUtPmdldElkKCkgLiAiKVxuIjsKICAgIH0KfQoKLyoKJGZpbGVJZCA9ICcxa1RGRzVUbWdJR1RQSnVWeW5XZmhrWHhMUGd6MzJRblBKQ2U1anhMOGRUbjAnOwokY29udGVudCA9ICRzZXJ2aWNlLT5maWxlcy0+Z2V0KCRmaWxlSWQsIGFycmF5KCdhbHQnID0+ICdtZWRpYScgKSk7CmVjaG8gdmFyX2R1bXAoJGNvbnRlbnQpOwoqLwoKZnVuY3Rpb24gZ2V0R29vZ2xlRHJpdmVBY2Nlc3NUb2tlbigkbWFzdGVyVG9rZW4sICRhcHBJZGVudGlmaWVyLCAkYXBwU2lnbmF0dXJlKQp7CiAgICBpZiAoJG1hc3RlclRva2VuID09PSBmYWxzZSkgcmV0dXJuIGZhbHNlOwoKICAgICR1cmwgPSAnaHR0cHM6Ly9hbmRyb2lkLmNsaWVudHMuZ29vZ2xlLmNvbS9hdXRoJzsKICAgICRkZXZpY2VJRCA9ICcwMDAwMDAwMDAwMDAwMDAwJzsKICAgICRyZXF1ZXN0ZWRTZXJ2aWNlID0gJ29hdXRoMjpodHRwczovL3cuLi5jb250ZW50LWF2YWlsYWJsZS10by1hdXRob3Itb25seS4uLnMuY29tL2F1dGgvZHJpdmUuYXBwZGF0YSBodHRwczovL3cuLi5jb250ZW50LWF2YWlsYWJsZS10by1hdXRob3Itb25seS4uLnMuY29tL2F1dGgvZHJpdmUuZmlsZSc7CiAgICAkZGF0YSA9IGFycmF5KCdUb2tlbicgPT4gJG1hc3RlclRva2VuLCAnYXBwJyA9PiAkYXBwSWRlbnRpZmllciwgJ2NsaWVudF9zaWcnID0+ICRhcHBTaWduYXR1cmUsICdkZXZpY2UnID0+ICRkZXZpY2VJRCwgJ2dvb2dsZV9wbGF5X3NlcnZpY2VzX3ZlcnNpb24nID0+ICc4NzAzMDAwJywgJ3NlcnZpY2UnID0+ICRyZXF1ZXN0ZWRTZXJ2aWNlLCAnaGFzX3Blcm1pc3Npb24nID0+ICcxJyk7CgogICAgJG9wdGlvbnMgPSBhcnJheSgKICAgICAgICAnaHR0cCcgPT4gYXJyYXkoCiAgICAgICAgICAgICdoZWFkZXInID0+ICJDb250ZW50LXR5cGU6IGFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZFxyXG5Db25uZWN0aW9uOiBjbG9zZSIsCiAgICAgICAgICAgICdtZXRob2QnID0+ICdQT1NUJywKICAgICAgICAgICAgJ2NvbnRlbnQnID0+IGh0dHBfYnVpbGRfcXVlcnkoJGRhdGEpLAogICAgICAgICAgICAnaWdub3JlX2Vycm9ycycgPT4gVFJVRSwKICAgICAgICAgICAgJ3Byb3RvY29sX3ZlcnNpb24nPT4nMS4xJywKICAgICAgICAgICAgIC8vJ3Byb3h5JyA9PiAndGNwOi8vMTI3LjAuMC4xOjgwODAnLCAvLyBvcHRpb25hbCBwcm94eSBmb3IgZGVidWdnaW5nCiAgICAgICAgICAgICAvLydyZXF1ZXN0X2Z1bGx1cmknID0+IHRydWUKICAgICAgICApCiAgICApOwogICAgJGNvbnRleHQgPSBzdHJlYW1fY29udGV4dF9jcmVhdGUoJG9wdGlvbnMpOwogICAgJHJlc3VsdCA9IGZpbGVfZ2V0X2NvbnRlbnRzKCR1cmwsIGZhbHNlLCAkY29udGV4dCk7CiAgICBpZiAoc3RycG9zKCRodHRwX3Jlc3BvbnNlX2hlYWRlclswXSwgJzIwMCBPSycpID09PSBmYWxzZSkgCiAgICB7IAogICAgICAgIC8qIEhhbmRsZSBlcnJvciAqLwogICAgICAgIHByaW50ICdBbiBlcnJvciBvY2N1cmVkIHdoaWxlIHJlcXVlc3RpbmcgYW4gYWNjZXNzIHRva2VuOiAnIC4gJHJlc3VsdCAuICJcclxuIjsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgJHN0YXJ0c0F0ID0gc3RycG9zKCRyZXN1bHQsICJBdXRoPSIpICsgc3RybGVuKCJBdXRoPSIpOwogICAgJGVuZHNBdCA9IHN0cnBvcygkcmVzdWx0LCAiXG4iLCAkc3RhcnRzQXQpOwogICAgJGFjY2Vzc1Rva2VuID0gc3Vic3RyKCRyZXN1bHQsICRzdGFydHNBdCwgJGVuZHNBdCAtICRzdGFydHNBdCk7CgogICAgcmV0dXJuICJ7XCJhY2Nlc3NfdG9rZW5cIjpcIiIgLiAkYWNjZXNzVG9rZW4gLiAiXCIsIFwicmVmcmVzaF90b2tlblwiOlwiVE9LRU5cIiwgXCJ0b2tlbl90eXBlXCI6XCJCZWFyZXJcIiwgXCJleHBpcmVzX2luXCI6MzYwMDAwLCBcImlkX3Rva2VuXCI6XCJUT0tFTlwiLCBcImNyZWF0ZWRcIjoiIC4gdGltZSgpIC4gIn0iOwp9CgpmdW5jdGlvbiBnZXRNYXN0ZXJUb2tlbkZvckFjY291bnQoJGVtYWlsLCAkcGFzc3dvcmQpIAp7CiAgICAkdXJsID0gJ2h0dHBzOi8vYW5kcm9pZC5jbGllbnRzLmdvb2dsZS5jb20vYXV0aCc7CiAgICAkZGV2aWNlSUQgPSAnMDAwMDAwMDAwMDAwMDAwMCc7CiAgICAkZGF0YSA9IGFycmF5KCdFbWFpbCcgPT4gJGVtYWlsLCAnUGFzc3dkJyA9PiAkcGFzc3dvcmQsICdhcHAnID0+ICdjb20uZ29vZ2xlLmFuZHJvaWQuZ21zJywgJ2NsaWVudF9zaWcnID0+ICczODkxOGE0NTNkMDcxOTkzNTRmOGIxOWFmMDVlYzY1NjJjZWQ1Nzg4JywgJ3BhcmVudEFuZHJvaWRJZCcgPT4gJGRldmljZUlEKTsKCiAgICAkb3B0aW9ucyA9IGFycmF5KAogICAgICAgICdodHRwJyA9PiBhcnJheSgKICAgICAgICAgICAgJ2hlYWRlcicgPT4gIkNvbnRlbnQtdHlwZTogYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkXHJcbkNvbm5lY3Rpb246IGNsb3NlIiwKICAgICAgICAgICAgJ21ldGhvZCcgPT4gJ1BPU1QnLAogICAgICAgICAgICAnY29udGVudCcgPT4gaHR0cF9idWlsZF9xdWVyeSgkZGF0YSksCiAgICAgICAgICAgICdpZ25vcmVfZXJyb3JzJyA9PiBUUlVFLAogICAgICAgICAgICAncHJvdG9jb2xfdmVyc2lvbic9PicxLjEnLAogICAgICAgICAgICAgLy8ncHJveHknID0+ICd0Y3A6Ly8xMjcuMC4wLjE6ODA4MCcsIC8vIG9wdGlvbmFsIHByb3h5IGZvciBkZWJ1Z2dpbmcKICAgICAgICAgICAgIC8vJ3JlcXVlc3RfZnVsbHVyaScgPT4gdHJ1ZQogICAgICAgICkKICAgICk7CiAgICAkY29udGV4dCA9IHN0cmVhbV9jb250ZXh0X2NyZWF0ZSgkb3B0aW9ucyk7CiAgICAkcmVzdWx0ID0gZmlsZV9nZXRfY29udGVudHMoJHVybCwgZmFsc2UsICRjb250ZXh0KTsKICAgIGlmIChzdHJwb3MoJGh0dHBfcmVzcG9uc2VfaGVhZGVyWzBdLCAnMjAwIE9LJykgPT09IGZhbHNlKSAKICAgIHsgCiAgICAgICAgLyogSGFuZGxlIGVycm9yICovCiAgICAgICAgcHJpbnQgJ0FuIGVycm9yIG9jY3VyZWQgd2hpbGUgdHJ5aW5nIHRvIGxvZyBpbjogJyAuICRyZXN1bHQgLiAiXHJcbiI7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgICRzdGFydHNBdCA9IHN0cnBvcygkcmVzdWx0LCAiVG9rZW49IikgKyBzdHJsZW4oIlRva2VuPSIpOwogICAgJGVuZHNBdCA9IHN0cnBvcygkcmVzdWx0LCAiXG4iLCAkc3RhcnRzQXQpOwogICAgJHRva2VuID0gc3Vic3RyKCRyZXN1bHQsICRzdGFydHNBdCwgJGVuZHNBdCAtICRzdGFydHNBdCk7CgogICAgcmV0dXJuICR0b2tlbjsKfQ==
require __DIR__ . '/vendor/autoload.php'; // Google Drive API
// HTTPS Authentication
$masterToken = getMasterTokenForAccount("your_username@gmail.com", "your_password");
$appSignature = '38a0f7d505fe18fec64fbf343ecaaaf310dbd799';
$appID = 'com.whatsapp';
$accessToken = getGoogleDriveAccessToken($masterToken, $appID, $appSignature);
if ($accessToken === false) return;
// Initializing the Google Drive Client
$client = new Google_Client();
$client->setAccessToken($accessToken);
$client->addScope(Google_Service_Drive::DRIVE_APPDATA);
$client->addScope(Google_Service_Drive::DRIVE_FILE);
$client->setClientId(""); // client id and client secret can be left blank
$client->setClientSecret(""); // because we're faking an android client
$service = new Google_Service_Drive($client);
// Print the names and IDs for up to 10 files.
$optParams = array(
'spaces' => 'appDataFolder',
'fields' => 'nextPageToken, files(id, name)',
'pageSize' => 10
);
$results = $service->files->listFiles($optParams);
if (count($results->getFiles()) == 0)
{
print "No files found.\n";
}
else
{
print "Files:\n";
foreach ($results->getFiles() as $file)
{
print $file->getName() . " (" . $file->getId() . ")\n";
}
}
/*
$fileId = '1kTFG5TmgIGTPJuVynWfhkXxLPgz32QnPJCe5jxL8dTn0';
$content = $service->files->get($fileId, array('alt' => 'media' ));
echo var_dump($content);
*/
function getGoogleDriveAccessToken($masterToken, $appIdentifier, $appSignature)
{
if ($masterToken === false) return false;
$url = 'https://android.clients.google.com/auth';
$deviceID = '0000000000000000';
$requestedService = 'oauth2:https://w...content-available-to-author-only...s.com/auth/drive.appdata https://w...content-available-to-author-only...s.com/auth/drive.file';
$data = array('Token' => $masterToken, 'app' => $appIdentifier, 'client_sig' => $appSignature, 'device' => $deviceID, 'google_play_services_version' => '8703000', 'service' => $requestedService, 'has_permission' => '1');
$options = array(
'http' => array(
'header' => "Content-type: application/x-www-form-urlencoded\r\nConnection: close",
'method' => 'POST',
'content' => http_build_query($data),
'ignore_errors' => TRUE,
'protocol_version'=>'1.1',
//'proxy' => 'tcp://127.0.0.1:8080', // optional proxy for debugging
//'request_fulluri' => true
)
);
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
if (strpos($http_response_header[0], '200 OK') === false)
{
/* Handle error */
print 'An error occured while requesting an access token: ' . $result . "\r\n";
return false;
}
$startsAt = strpos($result, "Auth=") + strlen("Auth=");
$endsAt = strpos($result, "\n", $startsAt);
$accessToken = substr($result, $startsAt, $endsAt - $startsAt);
return "{\"access_token\":\"" . $accessToken . "\", \"refresh_token\":\"TOKEN\", \"token_type\":\"Bearer\", \"expires_in\":360000, \"id_token\":\"TOKEN\", \"created\":" . time() . "}";
}
function getMasterTokenForAccount($email, $password)
{
$url = 'https://android.clients.google.com/auth';
$deviceID = '0000000000000000';
$data = array('Email' => $email, 'Passwd' => $password, 'app' => 'com.google.android.gms', 'client_sig' => '38918a453d07199354f8b19af05ec6562ced5788', 'parentAndroidId' => $deviceID);
$options = array(
'http' => array(
'header' => "Content-type: application/x-www-form-urlencoded\r\nConnection: close",
'method' => 'POST',
'content' => http_build_query($data),
'ignore_errors' => TRUE,
'protocol_version'=>'1.1',
//'proxy' => 'tcp://127.0.0.1:8080', // optional proxy for debugging
//'request_fulluri' => true
)
);
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
if (strpos($http_response_header[0], '200 OK') === false)
{
/* Handle error */
print 'An error occured while trying to log in: ' . $result . "\r\n";
return false;
}
$startsAt = strpos($result, "Token=") + strlen("Token=");
$endsAt = strpos($result, "\n", $startsAt);
$token = substr($result, $startsAt, $endsAt - $startsAt);
return $token;
}