Rev 2 | Rev 4 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
<!DOCTYPE html>
<html lang="en">
<head>
<title>eBay Listing Promotion</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
<link rel="icon" href="favicon.ico" type="image/x-icon">
<script src="js/jquery.js"></script>
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet">
<link rel="stylesheet" href="css/style.css">
<script src="js/XMLWriter.js"></script>
<script src="js/vkbeautify.js"></script>
<script src="js/lodash.min.js"></script>
<script src="js/XMLparse.js"></script>
<script src="js/moment.js"></script>
<script src="js/moment-timezone.js"></script>
<script src="js/muna-tools.js"></script>
</head>
<body onload="return initConfig();">
<div class="w3-main">
<div class="w3-container w3-padding w3-margin w3-card-4">
<div class="w3-container w3-gray" style="height:100px">
<img class="w3-image" src="images/MUNA%20-%20Logo%20100x100.png" alt="MUNA Trading Logo" style="height:100px">
<p id="connected" class="w3-xxlarge w3-right">eBay Listing Promotion
<input id="login" type="button" class="w3-btn w3-large w3-green w3-margin w3-round-large w3-ripple w3-right w3-hide" onclick="eBayLogin();" value="Login" />
</p>
</div>
<div class="w3-row">
<div>
<form id="searchForm" class="w3-container w3-light-grey w3-padding w3-small" onsubmit="return getListingsForPromote();">
<div class="w3-container w3-card-2 w3-cell w3-padding">
<textarea id="bearer" rows="4" cols="80"></textarea>
<input id="promoteButton" type="button" class="w3-btn w3-large w3-red w3-margin w3-round-large w3-ripple" onclick="getListingsForPromote();" value="Promote" />
</div>
</form>
</div>
<div id="progressBarDiv" class="w3-container w3-padding w3-margin w3-card-4 w3-hide">
<h2 id="progressBarHeader"></h2>
<div class="w3-light-grey">
<div id="progressBar" class="w3-container w3-green w3-center" style="width:0%">0%</div>
</div>
</div>
<div id="results" class="w3-container w3-padding w3-card-4 w3-hide"></div>
<div id="logging" class="w3-container w3-padding"></div>
</div>
</div>
<footer class="w3-container w3-center w3-border-top w3-margin">
Copyright © 2018 MUNA Trading. All rights reserved.
</footer>
</div>
<script>
// Config
var configCampaignId = '10477406018';
var pagesToProcess = 0;
var pagesProcessed = 0;
var html = [];
// Initialize Configuration Variables
function initConfig() {
eBayAuthToken = readCookie();
if (eBayAuthToken.length > 0) {
connected();
}
if (eBayAuthTokenFlag === false) {
var x = document.getElementById("login");
if (x.className.indexOf("w3-show") == -1) {
x.className += " w3-show";
}
}
getOAuthToken();
}
function requireNewLogin() {
// dummy
}
function connected() {
var x;
eBayAuthTokenFlag = true;
document.getElementById("connected").innerHTML += " (Connected)";
x = document.getElementById("promoteButton");
x.className = x.className.replace(" w3-red", " w3-black");
x = document.getElementById("login");
x.className = x.className.replace(" w3-show", "");
x = document.getElementById("results");
x.innerHTML = "";
x.className = x.className.replace(" w3-show", "");
x.className = x.className.replace("process-errors", "");
}
function getListingsForPromote() {
var x;
if (eBayAuthTokenFlag === false) {
return;
}
userAccessToken = document.getElementById("bearer").value;
if (userAccessToken.length < 1) {
return;
}
document.getElementById("logging").innerHTML = '';
x = document.getElementById("results");
if (x.className.indexOf("w3-show") == -1) {
x.className += " w3-show";
}
x.innerHTML = '<p><strong>Retrieving Listings...</strong></p>';
x.className = x.className.replace("process-errors", "");
pagesToProcess = 1;
pagesProcessed = 0;
initProgressBar("Retrieving Listings...");
eBaySearch(1);
function checkpagesToProcess() {
if (pagesToProcess > 0) {
window.setTimeout(checkpagesToProcess, 300); // wait 100 milliseconds
} else {
endProgressBar();
document.getElementById("results").innerHTML += '<p><strong>Sorting / Cleaning List...</strong></p>';
sortTable();
removeDuplicateRows($('#promoteTable'));
processCurrentAds();
}
}
checkpagesToProcess();
}
function processCurrentAds() {
adsToRead = 1;
getCurrentAds(1);
function checkAdsToRead() {
if (adsToRead > 0) {
window.setTimeout(checkAdsToRead, 100); // wait 100 milliseconds
} else {
updateAds();
}
}
checkAdsToRead();
}
function updateAds() {
var i = 1;
var pt = document.getElementById("promoteTable");
var x;
var updateList = [];
var addList = [];
var entry;
var maxAds = 500;
adsToUpdate = 0;
for (i = 1; i < pt.rows.length; i++) {
if (pt.rows[i].cells[1].innerHTML != pt.rows[i].cells[3].innerHTML) {
entry = '{"bidPercentage":"' + pt.rows[i].cells[1].innerHTML + '","listingId" : "' + pt.rows[i].cells[0].innerHTML + '"}';
if (pt.rows[i].cells[2].innerHTML.length > 0) {
if (updateList.indexOf(entry) == -1) {
updateList.push(entry);
}
} else {
if (addList.indexOf(entry) == -1) {
addList.push(entry);
}
}
}
}
for (i = 0; (i * maxAds) < updateList.length; i++) {
++adsToUpdate;
updateAd(1, updateList.slice(i * maxAds, (i + 1) * maxAds));
}
for (i = 0; (i * maxAds) < addList.length; i++) {
++adsToUpdate;
updateAd(0, addList.slice(i * maxAds, (i + 1) * maxAds));
}
function checkAdsToUpdate() {
if (adsToUpdate > 0) {
window.setTimeout(checkAdsToUpdate, 100); // wait 100 milliseconds
} else {
x = document.getElementById("results");
x.innerHTML += '<p><strong>Report Finished!</strong></p>';
if (!x.className.includes("process-errors")) {
setTimeout(function() {
x.className = x.className.replace(" w3-show", "");
}, 3000);
}
}
}
checkAdsToUpdate();
}
function getCurrentAds(pageNumber) {
var i;
var response;
var limit = 500;
url = configeBayAdCampaign;
url += configCampaignId;
url += '/ad?';
url += 'offset=';
url += (pageNumber - 1) * limit;
url += '&limit=';
url += limit;
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4) {
if (this.status == 200) {
response = JSON.parse(this.responseText);
for (i = 0; i < response.ads.length; i++) {
itemId = response.ads[i].listingId;
if (document.getElementById('AdId' + itemId) !== null) {
document.getElementById('AdId' + itemId).innerHTML = response.ads[i].adId;
document.getElementById('CurrentRate' + itemId).innerHTML = response.ads[i].bidPercentage;
}
}
if (Number(response.total) > (pageNumber * limit)) {
++adsToRead;
document.getElementById("results").innerHTML += '<p><strong>Retrieving Ads (' + pageNumber + '/' + Number((response.total / limit) + 1).toFixed(0) + ')</strong></p>';
getCurrentAds(pageNumber + 1);
}
}
--adsToRead;
}
};
xhttp.open("GET", configProxyUrl, true);
xhttp.setRequestHeader("X-Proxy-Url", encodeURI(url));
xhttp.setRequestHeader('X-Authorization', 'Bearer ' + userAccessToken);
xhttp.send();
}
function updateAd(flag, list) {
var xhttp;
var json;
var i;
var obj;
if (list.length === 0) {
return;
}
json = '{"requests":[' + list.join(',') + ']}';
if (flag) {
url = configeBayAdCampaign;
url += configCampaignId;
url += '/bulk_update_ads_bid_by_listing_id';
xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4) {
obj = JSON.parse(this.responseText);
if (this.status == 200 || this.status == 207) {
for (i = 0; i < obj.responses.length; i++) {
if (Number(obj.responses[i].statusCode) == 200) {
document.getElementById('AdId' + obj.responses[i].listingId).innerHTML = obj.responses[i].adId;
document.getElementById('UpdateStatus' + obj.responses[i].listingId).innerHTML = 'Updated';
document.getElementById('UpdateStatus' + obj.responses[i].listingId).style.color = 'green';
} else {
document.getElementById('UpdateStatus' + obj.responses[i].listingId).innerHTML = 'Update Failed (';
if (obj.responses[i].errors !== undefined) {
document.getElementById('UpdateStatus' + obj.responses[i].listingId).innerHTML += obj.responses[i].errors[0].message;
} else if (obj.responses[i].statusCode !== undefined) {
document.getElementById('UpdateStatus' + obj.responses[i].listingId).innerHTML += obj.responses[i].statusCode;
}
document.getElementById('UpdateStatus' + obj.responses[i].listingId).innerHTML += ')';
document.getElementById('UpdateStatus' + obj.responses[i].listingId).style.color = 'red';
}
}
} else {
var x = document.getElementById("results");
x.className += " process-errors";
x.innerHTML += '<p class="w3-red">Bulk Update Ads: <strong>' + this.status + '</strong></p>';
}
--adsToRead;
}
};
xhttp.open("POST", configProxyUrl, true);
xhttp.setRequestHeader("X-Proxy-Url", encodeURI(url));
xhttp.setRequestHeader('X-Authorization', 'Bearer ' + userAccessToken);
xhttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhttp.send(json);
} else {
url = configeBayAdCampaign;
url += configCampaignId;
url += '/bulk_create_ads_by_listing_id';
xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4) {
obj = JSON.parse(this.responseText);
if (this.status == 200 || this.status == 207) {
for (i = 0; i < obj.responses.length; i++) {
if (Number(obj.responses[i].statusCode) == 201) {
document.getElementById('AdId' + obj.responses[i].listingId).innerHTML = obj.responses[i].adId;
document.getElementById('UpdateStatus' + obj.responses[i].listingId).innerHTML = 'Added';
document.getElementById('UpdateStatus' + obj.responses[i].listingId).style.color = 'green';
} else {
document.getElementById('UpdateStatus' + obj.responses[i].listingId).innerHTML = 'Add Failed (' + obj.responses[i].errors[0].message + ')';
document.getElementById('UpdateStatus' + obj.responses[i].listingId).style.color = 'red';
}
}
} else {
var x = document.getElementById("results");
x.className += " process-errors";
x.innerHTML += '<p class="w3-red">Bulk Create Ads: <strong>' + this.status + '</strong></p>';
}
--adsToRead;
}
};
xhttp.open("POST", configProxyUrl, true);
xhttp.setRequestHeader("X-Proxy-Url", encodeURI(url));
xhttp.setRequestHeader('X-Authorization', 'Bearer ' + userAccessToken);
xhttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhttp.send(json);
}
--adsToUpdate;
}
// Build an HTML table to display search results
function eBaySearch(pageNo) {
var i;
var xml;
if (eBayAuthTokenFlag === false) {
return;
}
var xw = new XMLWriter('UTF-8', '1.0');
var xhr = new XMLHttpRequest();
if (!createAddXMLSearch(xw, xhr, 'GetSellerList', pageNo)) {
return;
}
xml = xw.flush();
xw.close();
//window.alert(vkbeautify.xml(xml));
xhr.onload = function() {
var obj = XMLparse(xhr.responseXML);
//window.alert(JSON.stringify(obj));
//window.alert(vkbeautify.xml(xhr.responseText));
var returnCode = obj.Ack;
var x = document.getElementById("results");
if (returnCode == 'Success') {
createTable(obj.ItemArray, pageNo, Number(obj.PaginationResult.TotalNumberOfPages));
if (Number(obj.PaginationResult.TotalNumberOfPages) > pageNo) {
maxPagesToProcess = Number(obj.PaginationResult.TotalNumberOfPages);
++pagesToProcess;
eBaySearch(pageNo + 1);
}
updateProgressBar(maxPagesToProcess, pagesProcessed);
} else {
x.className += " process-errors";
x.innerHTML += '<p class="w3-red"><strong>' + returnCode + ':</strong></p>';
var errors = obj.Errors;
x.innerHTML += "<p>";
if (errors.length > 0) {
for (i = 0; i < errors.length; i++) {
x.innerHTML += errors[i].SeverityCode + " (" + errors[i].ErrorCode + "): " + escapeHtml(errors[i].LongMessage) + "<br/>";
}
} else {
x.innerHTML += obj.Errors.SeverityCode + " (" + obj.Errors.ErrorCode + "): " + escapeHtml(obj.Errors.LongMessage) + "<br/>";
}
x.innerHTML += "</p>";
}
--pagesToProcess;
++pagesProcessed;
document.getElementById("logging").innerHTML = html.join('');
updateProgressBar(maxPagesToProcess, pagesProcessed);
};
xhr.send(xml);
}
function createAddXMLSearch(xw, xhr, callname, pageNo) {
var startDate = moment(moment().subtract(31, "days").format('YYYY-MM-DD') + " 00:00:00", "YYYY-MM-DD HH:mm:ss").tz("UTC").toISOString();
var todayDate = moment(moment().format('YYYY-MM-DD') + " 23:59:59", "YYYY-MM-DD HH:mm:ss").tz("UTC").toISOString();
var endDate = moment(moment().add(31, "days").format('YYYY-MM-DD') + " 00:00:00", "YYYY-MM-DD HH:mm:ss").tz("UTC").toISOString();
xw.writeStartDocument();
xw.writeStartElement(callname + "Request");
xw.writeAttributeString('xmlns', 'urn:ebay:apis:eBLBaseComponents');
xw.writeStartElement('RequesterCredentials');
xw.writeElementString('eBayAuthToken', eBayAuthToken);
xw.writeEndElement(); /* RequesterCredentials */
xw.writeElementString('GranularityLevel', 'Coarse');
xw.writeElementString('StartTimeFrom', startDate);
xw.writeElementString('StartTimeTo', todayDate);
xw.writeElementString('EndTimeFrom', todayDate);
xw.writeElementString('EndTimeTo', endDate);
xw.writeElementString('OutputSelector', 'ItemArray.Item.ItemID');
xw.writeElementString('OutputSelector', 'ItemArray.Item.ListingType');
xw.writeElementString('OutputSelector', 'PaginationResult');
xw.writeElementString('OutputSelector', 'ItemArray.Item.SellingStatus.ConvertedCurrentPrice');
xw.writeStartElement('Pagination');
xw.writeElementString('EntriesPerPage', '200');
xw.writeElementString('PageNumber', '' + pageNo);
xw.writeEndElement(); /* Pagination*/
xw.writeElementString('ErrorLanguage', 'en_US');
xw.writeElementString('Version', configeBayTradingVersion);
xw.writeElementString('WarningLevel', configWarningLevel);
xw.writeEndElement(); /* xmlrequest */
xw.writeEndDocument();
xhr.open('POST', configProxyUrl, true);
xhr.setRequestHeader('Content-Type', 'text/xml');
xhr.setRequestHeader('X-EBAY-API-APP-NAME', configAppid);
xhr.setRequestHeader('X-EBAY-API-COMPATIBILITY-LEVEL', configeBayTradingVersion);
xhr.setRequestHeader('X-EBAY-API-CALL-NAME', callname);
xhr.setRequestHeader('X-EBAY-API-SITEID', '0');
xhr.setRequestHeader('X-EBAY-API-DEV-NAME', '');
xhr.setRequestHeader('X-EBAY-API-CERT-NAME', '');
xhr.setRequestHeader('X-Proxy-URL', configServiceEndpoint);
return true;
}
function createTable(obj, pageNumber, totalPages) {
var currentPrice;
var adRate;
if (pageNumber == 1) {
document.getElementById("logging").innerHTML = '';
html = [];
html.push('<h3>Listing Promotions</h3>');
html.push('<div class="w3-responsive">');
html.push('<table id="promoteTable" class="w3-table-all w3-hoverable">');
html.push('<thead>');
html.push('<tr>');
html.push(tableHeader('Item ID'));
html.push(tableHeader('New Ad Rate'));
html.push(tableHeader('Ad Id'));
html.push(tableHeader('Current Ad Rate'));
html.push(tableHeader('Create/Update Status'));
html.push('</tr>');
html.push('</thead>');
html.push('<tbody>');
}
for (var entry = 0; entry < obj.length; entry++) {
if (obj[entry].ListingType == 'Chinese') {
continue;
}
currentPrice = Number(obj[entry].SellingStatus.text).toFixed(2);
// minimum ad rate is 1.00%
if (currentPrice > 99.99) {
adRate = 2.0;
} else if (currentPrice > 49.99) {
adRate = 2.7;
} else if (currentPrice > 29.99) {
adRate = 3.0;
} else if (currentPrice > 19.99) {
adRate = 3.2;
} else if (currentPrice > 14.99) {
adRate = 3.5;
} else if (currentPrice > 9.99) {
adRate = 3.7;
} else if (currentPrice > 4.99) {
adRate = 4.0;
} else if (currentPrice > 3.99) {
adRate = 4.2;
} else {
continue;
}
html.push('<tr>');
html.push(tableCell(obj[entry].ItemID));
html.push(tableCell(Number(adRate).toFixed(1)));
html.push(tableCellLabel('AdId' + obj[entry].ItemID));
html.push(tableCellLabel('CurrentRate' + obj[entry].ItemID));
html.push(tableCellLabel('UpdateStatus' + obj[entry].ItemID));
html.push('</tr>');
}
if (pageNumber == totalPages) {
html.push('</tbody>');
html.push('</table>');
html.push('</div>');
}
}
function sortTable() {
var i;
var tbl = document.getElementById("promoteTable").tBodies[0];
var store = [];
for (i = 0, len = tbl.rows.length; i < len; i++) {
var row = tbl.rows[i];
var sortnr = parseFloat(row.cells[0].textContent || row.cells[0].innerText);
if (!isNaN(sortnr)) store.push([sortnr, row]);
}
store.sort(function(x, y) {
return x[0] - y[0];
});
for (i = 0, len = store.length; i < len; i++) {
tbl.appendChild(store[i][1]);
}
store = null;
}
function getOAuthToken() {
var code = "";
var win = window.open(configeBayLoginUrl, "eBay OAUTH", "");
var pollTimer = window.setInterval(function() {
if (win.closed !== false) {
window.clearInterval(pollTimer);
getApplicationToken(code);
} else {
if (code === null || code.length === 0) {
try {
code = getUrlParameter(win, 'code');
} catch(err) {
// empty
}
}
}
}, 200);
}
function getApplicationToken(code) {
var param;
param = 'grant_type=authorization_code';
param += '&code=' + code;
param += '&redirect_uri=' + configRuName;
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4) {
if (this.status == 200) {
response = JSON.parse(this.responseText);
document.getElementById("bearer").innerHTML = getJsonValue(response.access_token);
}
}
};
xhttp.open("POST", configProxyUrl, true);
xhttp.setRequestHeader("X-Proxy-Url", configOauthTokenUrl);
xhttp.setRequestHeader('X-Authorization', 'Basic ' + btoa(configAppid + ':' + configCertid));
/*
xhttp.open("POST", configOauthToken, true);
xhttp.setRequestHeader('Authorization', 'Basic ' + btoa(configAppid + ':' + configCertid));
*/
xhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhttp.send(param);
}
</script>
</body>
</html>