-
-
Save gekidoslair/b9ca1c010ece7bef35a65d861753e672 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
PHP script that uses Unity Publisher API for PHP (https://github.com/LostPolygon/Unity-Publisher-API-PHP) to retrieve new asset sales, put them into a MySQL database, and notify about the sales via e-mail. | |
Data is inserted into `sales` table, which can be created from sales_table.sql file. Just set up the credentials and put this script on cron with whatever interval you want. Delete the email notification part if you don't need it. | |
Requires PHP 5.4, php_json extension, and remote socket access. | |
Also, I know it's ugly, but it does the job and served me well for over a year. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"assetstore": { | |
"login": "[email protected]", | |
"password": "123456" | |
}, | |
"mysql": { | |
"domain": "localhost", | |
"user": "root", | |
"password": "654321", | |
"db": "as_stats" | |
}, | |
"receiver_mail": "[email protected]" | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CREATE TABLE IF NOT EXISTS `sales` ( | |
`id` int(11) NOT NULL AUTO_INCREMENT, | |
`date` datetime NOT NULL, | |
`name` varchar(64) NOT NULL, | |
`price` float NOT NULL, | |
`quantity` smallint(5) unsigned NOT NULL, | |
`refunds` smallint(5) unsigned NOT NULL, | |
`chargebacks` smallint(5) unsigned NOT NULL, | |
`payout_cut` float NOT NULL, | |
`shorturl` varchar(24) NOT NULL, | |
PRIMARY KEY (`id`) | |
) DEFAULT CHARSET=utf8 ; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
chdir(__DIR__); | |
error_reporting(E_STRICT | E_ALL); | |
require_once 'AssetStorePublisherClient.class.php'; | |
date_default_timezone_set('America/Los_Angeles'); | |
// This is the minimum amount of net revenue per launch to trigger an email | |
$minNetToSendMail = 0; | |
$credentials = json_decode(file_get_contents('credentials.json'), true); | |
function loginAndRetrieve($action) { | |
global $credentials; | |
$actionResult = null; | |
$store = new AssetStore\Client(); | |
$loginToken = @file_get_contents("loginToken.txt"); | |
if ($loginToken == null) { | |
echo "No cached login token, retrieving\r\n"; | |
$tfaResumeDataJsonFile = 'tfaResumeData.json'; | |
$tfaResumeData = null; | |
if (file_exists($tfaResumeDataJsonFile)) { | |
$tfaResumeDataJson = file_get_contents($tfaResumeDataJsonFile); | |
$tfaResumeData = json_decode($tfaResumeDataJson, true); | |
} | |
$tfaCodeFile = 'tfaCode.txt'; | |
$tfaCode = null; | |
if (file_exists($tfaCodeFile)) { | |
$tfaCode = trim(file_get_contents($tfaCodeFile)); | |
} | |
if ($tfaResumeData != null && $tfaCode == null) { | |
die("No TFA code yet in tfaCode.txt, exiting"); | |
} | |
$loginToken = $store->Login($credentials['assetstore']['login'], $credentials['assetstore']['password'], $tfaResumeData, $tfaCode); | |
if ($loginToken === AssetStore\Client::TFA_CODE_REQUESTED) { | |
file_put_contents($tfaResumeDataJsonFile, json_encode($store->getTfaResumeData(), JSON_PRETTY_PRINT)); | |
die("TFA requested, exiting"); | |
} else { | |
if (file_exists($tfaResumeDataJsonFile)) { | |
unlink($tfaResumeDataJsonFile); | |
} | |
if (file_exists($tfaCodeFile)) { | |
unlink($tfaCodeFile); | |
} | |
file_put_contents("loginToken.txt", $loginToken); | |
$actionResult = $action($store); | |
} | |
} else { | |
echo "Using cached login token\r\n"; | |
$store->LoginWithToken($loginToken); | |
try { | |
$actionResult = $action($store); | |
} catch (AssetStore\AssetStoreException $e) { | |
// Get new token on 401 Unauthorized | |
if ($e->getCode() == 401) { | |
echo "Cached login token is invalid, retrieving new one\r\n"; | |
$store = new AssetStore\Client(); | |
$loginToken = $store->Login($credentials['assetstore']['login'], $credentials['assetstore']['password']); | |
file_put_contents("loginToken.txt", $loginToken); | |
$actionResult = $action($store); | |
} else { | |
throw $e; | |
} | |
} | |
} | |
return $actionResult; | |
} | |
function getCurrentSales($year, $month) { | |
$sales = loginAndRetrieve(function($store) use ($year, $month) { | |
return $store->FetchSales($year, $month); | |
}); | |
return $sales->ToArray(); | |
} | |
function diffSales($prevSales, $curSales) { | |
$data = Array(); | |
foreach ($curSales as $key => $curSale) { | |
$prevSale = array_filter($prevSales, function($element) use ($curSale) { | |
return $element['packageName'] == $curSale['packageName'] && | |
$element['price'] == $curSale['price']; | |
}); | |
@$prevSale = reset($prevSale); | |
$diffItem = Array( | |
'packageName' => $curSale['packageName'], | |
'price' => $curSale['price'], | |
'quantity' => (int)$curSale['quantity'] - (int)$prevSale['quantity'], | |
'refunds' => (int)$curSale['refunds'] - (int)$prevSale['refunds'], | |
'chargebacks' => (int)$curSale['chargebacks'] - (int)$prevSale['chargebacks'], | |
'shortUrl' => $curSale['shortUrl'], | |
); | |
if (!($diffItem['quantity'] == 0 && | |
$diffItem['refunds'] == 0 && | |
$diffItem['chargebacks'] == 0)) { | |
$data[] = $diffItem; | |
} | |
} | |
return $data; | |
} | |
function saveStats($sales, $year, $month) { | |
$sales['year'] = $year ; | |
$sales['month'] = $month; | |
file_put_contents('prevStats.json', json_encode($sales, JSON_PRETTY_PRINT)); | |
} | |
// MAIN start | |
$curYear = date('Y'); | |
$curMonth = date('m'); | |
if (!file_exists('prevStats.json')) { | |
$sales = getCurrentSales($curYear , $curMonth); | |
saveStats($sales, $curYear, $curMonth); | |
} | |
$prevSales = json_decode(file_get_contents('prevStats.json'), true); | |
if ($prevSales['year'] != $curYear || $prevSales['month'] != $curMonth) | |
$prevSales = Array('packageSales' => Array()); | |
$sales = getCurrentSales($curYear , $curMonth); | |
$diff = diffSales($prevSales['packageSales'], $sales['packageSales']); | |
saveStats($sales, $curYear, $curMonth); | |
$mysqli = new mysqli($credentials['mysql']['domain'], | |
$credentials['mysql']['user'], | |
$credentials['mysql']['password'], | |
$credentials['mysql']['db']); | |
if (mysqli_connect_errno()) { | |
printf("Connection error: %s\n", mysqli_connect_error()); | |
exit(); | |
} | |
foreach ($diff as $value) { | |
$stmt = $mysqli->prepare("INSERT INTO `sales` (`date`, `name`, `price`, `quantity`, `refunds`, `chargebacks`, `payout_cut`, `shorturl`) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); | |
$date = date ("Y-m-d H:i:s", time()); | |
$name = $value['packageName']; | |
$price = $value['price']; | |
$quantity = (int)$value['quantity']; | |
$refunds = (int)$value['refunds']; | |
$chargebacks = (int)$value['chargebacks']; | |
$shortUrl = $value['shortUrl']; | |
$payout_cut = 0.7; | |
$stmt->bind_param("ssdiiids", $date, $name, $price, $quantity, $refunds, $chargebacks, $payout_cut, $shortUrl); | |
if (!$stmt->execute()) { | |
echo "Unable to execute query: (" . $stmt->errno . ") " . $stmt->error; | |
} | |
} | |
$netRevenueDiff = round($sales["revenueNet"] - $prevSales["revenueNet"], 2); | |
if (sizeof($diff) > 0 && $netRevenueDiff >= $minNetToSendMail) { | |
// CONSTRUCT MAIL | |
$mail_content = ''; | |
foreach ($diff as $value) { | |
$mail_content .= "• <a href=\"{$value['shortUrl']}\">{$value['packageName']}</a>. "; | |
if ($value['quantity'] != 0) | |
$mail_content .= "Purchases: {$value['quantity']} "; | |
if ($value['refunds'] != 0) | |
$mail_content .= "Refunds: {$value['refunds']} "; | |
if ($value['chargebacks'] != 0) | |
$mail_content .= "Chargebacks: {$value['chargebacks']} "; | |
$mail_content .= "\r\n<br>"; | |
} | |
$mail_content .= "\r\n<br>Net: \${$sales['revenueNet']}"; | |
if ($prevSales['year'] == $curYear && $prevSales['month'] == $curMonth) { | |
$mail_content .= ", "; | |
if ($netRevenueDiff > 0) { | |
$mail_content .= "+"; | |
} | |
$mail_content .= '$' + $netRevenueDiff; | |
} | |
$mail_title = "Asset Store purchase!"; | |
$header .= "Content-type: text/html; charset=\"utf-8\""; | |
mail($credentials["receiver_mail"], $mail_title, $mail_content, $header); | |
} | |
if (sizeof($diff) > 0) | |
file_put_contents("update.log", date ("Y-m-d H:i:s", time()) . ', ' . sizeof($diff) . " added\r\n", FILE_APPEND); | |
echo "Stats updated, inserted ". sizeof($diff) . " values\r\n"; | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment