I'm trying to do a script which pauses an adgroup based in the field AVAILABILITY in a XML (a Google Merchant XML).
I have a merchant XML, and want to use the ID (the id is algo used in the adgroup name) and AVAILABILITY (In Stock, Out of Stock, Preorder) from the XML to pause Adgroups in my campaign.
I tried to modify an example, I had found here, using adgroups in place of campaigns, but I think the error is when the script try to read the XML.
In the lines bellow lines I receive the error: "TypeError: Cannot call method "getValue" of null. (line 16)"
var id = entries[i].getChild('g:id').getValue();
var availability = entries[i].getChild('g:availability').getValue();
My XML is like this:
<rss xmlns:g="http://base.google.com/ns/1.0" version="2.0">
<channel>
<item>
<title>
<![CDATA[ Far Cry 4: Overrun ]]>
</title>
<link>https://www.nuuvem.com/item/far-cry-4-overrun</link>
<description>
<![CDATA[
Neste novo conteúdo para Far Cry 4, enquanto a guerra sem trégua por Kyrat continua, os jogadores assumirão o papel dos Rakshasa e do Caminho Dourado para manter locais que dão pontos no mapa da batalha.
]]>
</description>
<g:availability>in stock</g:availability>
<g:price currency="BRL">8.99</g:price>
<g:image_link> http://dskhvldhwok3h.cloudfront.net/image/upload/t_boxshot_big/v1/products/557dbcb269702d0a9c490801/boxshots/ynhjodwlnmur0crkiaxp.jpg </g:image_link>
<g:product_type>
<![CDATA[ Ação ]]>
</g:product_type>
<g:google_product_category>Software > Video Game Software > Computer Games</g:google_product_category>
<g:condition>new</g:condition>
<g:identifier_exists>FALSE</g:identifier_exists>
<g:id>2668</g:id>
</item>
My script now looks like this:
function main() {
// Load an XML file:
var xmlURL = "XML URL HERE";
var xmlFile = UrlFetchApp.fetch(xmlURL);
// Parse the XML file:
var document = XmlService.parse(xmlFile);
var root = document.getRootElement();
// Go through all children of <deepdive_pages>:
var entries = document.getRootElement().getChildren();
for (var i = 0; i < entries.length; i++) {
//for (var i = 0; i < 10; i++) {
var id = entries[i].getChild('g:id').getValue();
var availability = entries[i].getChild('g:availability').getValue();
// If company_root_id has 0 jobs
if (availability == "out of stock") {
var adGroupIterator = AdWordsApp.adGroups().withCondition('Name CONTAINS "| ' + id + ' |"').get(); // Find all campaigns with the company name
while (adGroupIterator.hasNext()) { // Go over all campaings with company id in the name
var adgroup = adGroupIterator.next();
if (adgroup.isEnabled()) { // If campaign is enables, pause it
adgroup.pause();
Logger.log("adgroup " + adgroup.getName() + " was paused.");
}
}
}
// If company_root_id has MORE than 0 jobs
else {
var adGroupIterator = AdWordsApp.adGroups().withCondition('Name CONTAINS "| ' + id + ' |"').get(); // Find all campaigns with the company name
while (adGroupIterator.hasNext()) { // Go over all campaings with company id in the name
var adgroup = adGroupIterator.next();
if (adgroup.isPaused()) { // If campaign is paused, enable it
adgroup.enable();
Logger.log("adgroup " + adgroup.getName() + " was enabled.");
}
}
} // End If Else
}
}
Many thanks for any help!
With the help of Calin in this post: https://www.en.advertisercommunity.com/t5/Advanced-Features/Script-to-pause-Adggroups-based-in-information-from-a-Merchant/m-p/1024590#
I solved my problem.
To read the XML correctly, I used:
// Load an XML file:
var xmlURL = "XML_MERCHANT_URL_HERE";
var xmlFile = UrlFetchApp.fetch(xmlURL);
// Parse the XML file:
var document = XmlService.parse(xmlFile);
var ns = XmlService.getNamespace("http://base.google.com/ns/1.0");
var rss = document.getRootElement().getChildren(); //root element is <rss>; it's children are actually only one, <channel>
var entries = rss[0].getChildren('item'); //getting all 'item' children of the first rss element, <channel>
// Go through all children of <deepdive_pages>:
Logger.log(entries.length);
for (var i = 0; i < entries.length; i++) {
var id = entries[i].getChild('id',ns).getText();
var availability = entries[i].getChild('availability',ns).getText();
//Logger.log("ID: "+id+", Availability: "+availability);
Before I did'nt declared the XML namespace and I was using getchild, but in this case I need to use getChildren.
Related
I created a spreadsheet to keep track of all the videos uploaded by the YouTubers I follow. Then, I created a script to be executed from the console that lists all the videos of that user. I store the list in a variable, and then I log it, select it, and copy it to the clipboard, but I'd like to copy it automatically every time I run the script. The problem is that the text is not inside an element (like a div, or textarea), so I can't use either window.navigator.clipboard or document.execCommand('copy').
Is there a way to do that?.
Thanks & greets from Argentina (Hope it is from England someday).
IDsign4U (Marcelo Miguel Bazan).
This is the code I use (open the videos tab in any channel and try it):
console.clear();
console.log("Título + Duración + Estado + URL en Subscripciones (sin número de orden)");
var domains = "";
var i = "";
var text = "";
var title = "";
var duration = "";
var hours = "";
var link = "";
var video = "";
var textDuration = "";
var hoursCheck = "";
var finalDuration = "";
var finalTitle = "";
domains = document.getElementsByTagName('ytd-grid-video-renderer')
for (i = 0; i < domains.length; i++)
{title = domains[i].getElementsByTagName('h3');
duration = domains[i].getElementsByTagName('span');
link = domains[i].getElementsByTagName('a');
textDuration = duration[0].innerText.trim();
hoursCheck = "";
hoursCheck = textDuration.length > 5 ? "0": "00:";
finalDuration = hoursCheck + textDuration + "\t" + "P" + "\t";
finalTitle = title[0].innerText + "\t";
url = "https://www.youtube.com" + link[0].attributes['href'].value;
video = video + finalTitle + finalDuration + url + "\n";}
console.log(video);
Why shouldn't you be able to use navigator.clipboard? It works fine while providing variables to copy to clipboard.
document.getElementById("copy").addEventListener("click", async () => {
const text = "Text copied to the clipboard"
await navigator.clipboard.write(text)
})
<button id="copy">
Copy to clipboard
</button>
When you say "from the console", do you mean the browser console? If so, there's a built-in global copy function (not window.copy, just copy).
Yes!! Thank you Zac (and wOxxOm and Jannis Ioannou) for the answer.
It's just a matter of deleting the, for me, weird DOM element with the ID 'copy' to be able to use the copy function in the console.
Thanks & greets from Argentina (Hope it is from England someday).
IDsign4U (Marcelo Miguel Bazan).
I am trying to use an AJAX call to retrieve data from a movie API on the web. Here is my HTML code:
<html>
<head>
<meta charset=utf-8>
<title>Movie Database</title>
</head>
<body onload = "loadMyData(), loadYear()">
<div id = "main-content">
<h1>Movie Database</h1>
<select id="genre" class="filterButton">
</select>
<select id="releaseDate" class="filterButton">
</select>
<input type="text" value="Enter Release Date YYYY-MM-DD">
<button id="search">SEARCH</button>
</div>
<div id = "content"></div>
<script src = "myScript4.js"></script>
</body>
</html>
Here is my JS file:
/* THIS IS THE JS FILE FOR THE www.themoviedb.org WEBSITE API */
// MY GLOBAL VARIABLES
var title;
var genre;
var releaseYear;
var summary;
var actors;
var languages; // What languges is the movie in?
var status; // Is this movie releases or still in production?
/* ======================= HERE ARE MY EVENT LISTENERS ==================*/
var myList = document.getElementById("getList");
var myYear = document.getElementById("getRelease");
var getGenre = document.getElementById("genre");
var getYear = document.getElementById("releaseDate");
/* ======================= End of my Event Listeners =================== */
/* =========This is the function to display the data in the HTML ======= */
function displayData(results, title, poster_path, overview)
{
var div = document.createElement('div');
div.setAttribute('results', Results);
div.innerHTML = Title + '<br />' + Poster + Overview;
document.body.appendChild(div);
}
/* ============================ End function ========================= */
/* ============This is how the data from the genre is loaded ========== */
function loadMyData() {
var data = "{}";
var xhr = new XMLHttpRequest();
xhr.withCredentials = false;
console.log(xhr);
xhr.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
//console.log(this.responseText);
var sourceData = JSON.parse(xhr.responseText);
console.log(sourceData);
displayData(results, title, poster_path, overview);
var source = document.getElementById("genre");
for (var i = 0; i < sourceData.genres.length; i++) {
console.log(i);
optionID = sourceData.genres[i].id;
var optionName = sourceData.genres[i].name;
var option = document.createElement("option");
option.innerHTML = optionName;
option.setAttribute("value", optionID);
option.setAttribute("name", optionName);
source.appendChild(option);
//displayData(results, title, poster_path, overview);
//console.log(optionName);
}
}
});
xhr.open("GET", "https://api.themoviedb.org/3/genre/movie/list?language=en-US&api_key=**************");
xhr.send(data);
}
// loads the year from the Discover part of the API
function loadYear() {
var data = "{}";
var newxhr = new XMLHttpRequest();
newxhr.withCredentials = false;
console.log(newxhr);
newxhr.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
console.log(this.responseText);
var sourceData = JSON.parse(newxhr.responseText);
//console.log(sourceData);
var source = document.getElementById("releaseDate");
for (var i = 0; i < sourceData.results.length; i++) {
console.log(i);
optionID = sourceData.results[i].id;
var optionName = sourceData.results[i].release_date;
var option = document.createElement("option");
option.innerHTML = optionName;
option.setAttribute("value", optionID);
option.setAttribute("name", optionName);
source.appendChild(option);
console.log(optionName);
}
}
});
newxhr.open("GET", "https://api.themoviedb.org/3/discover/movie?page=1&include_video=false&include_adult=false&sort_by=popularity.desc&language=en-US&api_key=*****************");
newxhr.send(data);
}
/* --------------------------------------------- On click show the data ------------------------------------------------ */
document.getElementById("search").addEventListener("click", displayData);
LoadMyData() loads the data for the genre. I suppose I should rename it. LoadYear() of course loads the date of the movie.
DisplayData() is supposed to display the data from the JSON file once the user clicks the button.
Can someone please give me an idea as to how to use plain javascript and html to show the JSON data? Right now I get an error telling me this:
myScript4.js:55 Uncaught ReferenceError: results is not defined
at XMLHttpRequest. (myScript4.js:55)
Line 55 is here: displayData(results, title, poster_path, overview);
Any help would be appreciated :) I've also gotten rid of the API Key for security reasons. I know you're not supposed to give them away.
Here is a snippet of the outputted JSON file for the loadYear() function:
{
"page": 1,
"total_results": 328130,
"total_pages": 16407,
"results": [
{
"vote_count": 2039,
"id": 346364,
"video": false,
"vote_average": 7.4,
"title": "It",
"popularity": 745.88068,
"poster_path": "/9E2y5Q7WlCVNEhP5GiVTjhEhx1o.jpg",
"original_language": "en",
"original_title": "It",
"genre_ids": [
12,
18,
27
],
"backdrop_path": "/tcheoA2nPATCm2vvXw2hVQoaEFD.jpg",
"adult": false,
"overview": "In a small town in Maine, seven children known as The Losers Club come face to face with life problems, bullies and a monster that takes the shape of a clown called Pennywise.",
"release_date": "2017-09-05"
},
As you can see "results" is in the JSON file. This is the bit that was undefined in the JavaScript file. How do I define it?
At this part of the code:
var sourceData = JSON.parse(xhr.responseText);
console.log(sourceData);
displayData(results, title, poster_path, overview);
'results' is not yet defined. I don't know where or what you expect 'results' to be, but I'm going to make a guess that it's just an object inside the json of responseText, so you should add this line before your displayData call:
var results = sourceData.results; If results is not a property of sourceData then obviously make var results equal to whatever, in the response, you need it to be.
Javascript is case a sensitive language
so your displayData function seems to have some incorrect variables, should be like this:
function displayData(results, title, poster_path, overview)
{
var div = document.createElement('div');
div.setAttribute('results', results);
div.innerHTML = title + '<br />' + poster_path + overview;
document.body.appendChild(div);
}
I am parsing the following XML:
<?xml version="1.0" encoding="utf-8" ?><rss version="2.0" xml:base="https://www.sportsbook.ag/rss/nfl-football" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
<title>Sportsbook.com Live Football Betting Odds RSS Feed</title>
<link>https://www.sportsbook.ag/rss/nfl-football</link>
<description>Football Betting Feed</description>
<language>en</language>
<item>
<title>Dallas Cowboys # Minnesota Vikings</title>
<link>http://www.sportsbook.ag/livesports/nfl</link>
<description><strong>12-1-16 8:25 PM</strong>
Bet on Dallas Cowboys <a href="https://www.sportsbook.ag/sbk/sportsbook4/www.sportsbook.ag/updatecart5.cgi?sportTypeId=203&action=addBet&betTypeId=80&selection[Foot-Dalla-Minne-120116PSA]=Foot-Dalla-Minne-120116|PSA|1|100|115|-7|-115">-3.5 (-115)</a>
Money:<a href="https://www.sportsbook.ag/sbk/sportsbook4/www.sportsbook.ag/updatecart5.cgi?sportTypeId=203&action=addBet&betTypeId=80&selection[Foot-Dalla-Minne-120116MLA]=Foot-Dalla-Minne-120116|MLA|1|100|180|0|-180">-180</a>
or Minnesota Vikings <a href="https://www.sportsbook.ag/sbk/sportsbook4/www.sportsbook.ag/updatecart5.cgi?sportTypeId=203&action=addBet&betTypeId=80&/selection[Foot-Dalla-Minne-120116PSH]=Foot-Dalla-Minne-120116|PSH|1|100|105|7|-105">3.5 (-105)</a>
Money:<a href="https://www.sportsbook.ag/sbk/sportsbook4/www.sportsbook.ag/updatecart5.cgi?sportTypeId=203&action=addBet&betTypeId=80&selection[Foot-Dalla-Minne-120116MLA]=Foot-Dalla-Minne-120116|MLA|1|100|180|0|-180">+157</a>.
Totals: <a href="https://www.sportsbook.ag/sbk/sportsbook4/www.sportsbook.ag/updatecart5.cgi?sportTypeId=203&action=addBet&betTypeId=80&selection[Foot-Dalla-Minne-120116TLO]=Foot-Dalla-Minne-120116|TLO|1|100|110|89|-110">Over 44.5 (-110)</a>
<a href="https://www.sportsbook.ag/sbk/sportsbook4/www.sportsbook.ag/updatecart5.cgi?sportTypeId=203&action=addBet&betTypeId=80&selection[Foot-Dalla-Minne-120116TLU]=Foot-Dalla-Minne-120116|TLU|1|100|110|89|-110">Under 44.5 (-110)</a></description>
<pubDate>12-1-16 8:25 PM</pubDate>
<dc:creator />
<guid isPermaLink="false" />
</item>
with the following Google Apps Script:
function stugass() {
var live = new Array();
var url = "https://www.sportsbook.ag/rss/nfl-football";
var parameters = {method : "get", payload : ""};
var xml = UrlFetchApp.fetch(url, parameters).getContentText();
var document = XmlService.parse(xml);
var games = document.getRootElement().getChild('channel').getChildren('item');
if(document == null) {
document.getRootElement().getChild('channel').getChildren('item');
}
for (var i=0; i < games.length-1; i++) {
vegas = [];
var game = games[i];
vegas.push(game.getChildText('title'));
vegas.push(game.getChildText('link'));
vegas.push(game.getChildText('description'));
live.push(vegas);
}
return live;
}
How do I split up the "BLOB" portion of the 'description' tag into multiple cells in the Google Spreadsheet?
It's not obvious how far you want to split that field, but here is one way to do it, using split string method with regex argument that splits by HTML tags found in that description. The array returned by this method is filtered to eliminate any whitespace-only pieces.
var description = game.getChildText('description').split(/<\/?strong>|<a href="|">[^<]*<\/a>/);
vegas = vegas.concat(description.filter(function (a) {return a.trim().length;}));
live.push(vegas);
Output looks like
12-1-16 8:25 PM | Bet on Dallas Cowboys | https://www.sportsbook.ag/sbk/sportsbook4/www.sportsbook.ag/updatecart5.cgi?sportTypeId=203&action=addBet&betTypeId=80&selection[Foot-Dalla-Minne-120116PSA]=Foot-Dalla-Minne-120116|PSA|1|100|105|-7|-105 | ...
You can keep it simple like this:
function stugass() {
var live = new Array();
var url = "https://www.sportsbook.ag/rss/nfl-football";
var parameters = {method : "get", payload : ""};
var xml = UrlFetchApp.fetch(url, parameters).getContentText();
var document = XmlService.parse(xml);
var games = document.getRootElement().getChild('channel').getChildren('item');
if(document == null) {
document.getRootElement().getChild('channel').getChildren('item');
}
for (var i=0; i < games.length-1; i++) {
vegas = [];
var game = games[i];
vegas.push(game.getChildText('title'));
vegas.push(game.getChildText('link'));
vegas.push(game.getChildText('description').replace(/<a href=\S+\">|<\S+>/g,''));
live.push(vegas);
}
return live;
}
The output looks like this:
I have a tracking script on an E-commerce site receipt page. The script simply fetches the product information from the DOM and tracks it using the Piwik E-commerce tracking functions. This works fine in all browsers except Internet Explorer 8 and below. I've been trying to figure out what's wrong with the script for weeks. I've tested it locally on a dummy receipt page and it works fine in IE, but it's not tracking any sales for IE 5-8 on the live page.
The tracking script is inserted to the receipt page via an OpenTag tag and so is piwik.js, but I'm using the asynchronous tracker so that shouldn't be an issue, as all browsers except IE confirms.
Here is the code that is injected via OpenTag:
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<script type="text/javascript">
// Closure that supports jQuery
(function($) {
// Function for removing everything from a string except numbers and
// returning that number as an integer
var num = function(text) {
return parseInt(text.replace(/[^0-9]/g, ''));
};
// Trims whitespace from before and after a string. " hello " => "hello"
var trim = function(text) {
return text.replace(/^\s+|\s+$/g, '');
};
// Run on document ready
$(function() {
// Ready a reference to Piwik async queue
_paq = _paq || [];
// Referansenummeret
var order_id = num(
$('span#ctl00_CPHCnt_McInPlaceEdYourRefNbr_McInPlaceEdYourRefNbr')
.closest('p').text()
);
// Hent verdien som ligger etter "Total:"
// var total = num(
// $('span#ctl00_CPHCnt_HandlevognProdukListe1_McInPlaceEdTotInclAVT2_McInPlaceEdTotInclAVT2')
// .closest('tr').children('td:last-child').text()
// );
var total = 0;
// Hent verdien som ligger etter "Sum:"
var sub_total = num(
$('span#ctl00_CPHCnt_HandlevognProdukListe1_McInPlaceEditorSum_McInPlaceEditorSum')
.closest('tr').children('td:last-child').text()
);
// Hent verdien som ligger etter "Herav mva:"
var mva = num(
$('table.CartSummaryTable .TotalValue').closest('tr').next()
.children('td:last-child').text()
);
// Hent verdien som ligger etter "Frakt inkl. evt. gebyr:"
var shipping = num(
$('span#ctl00_CPHCnt_HandlevognProdukListe1_McInPlaceEdFreightInclFee_McInPlaceEdFreightInclFee')
.closest('tr').children('td:last-child').text()
);
// Cheat solution - the total doesn't have a 100% hitrate so just
// add the sub_total and shipping together.
total = sub_total + shipping;
// Iterate over the product rows and extract the information
$('table#ProductList tr.VerticalText').each(function(index, row) {
var sku = trim($('td:first-child', row).text());
var prod_name = trim($('div.ProduktDesc span', row).text());
var categories = [];
var price = num($('td:nth-child(5)', row).text());
var quant = num($('td:nth-child(4)', row).text());
// Extrapolate categories from the product link URL
var path = $('.ProduktDesc a', row).attr('href').split('/');
for(var i = 2; i < path.length - 1; i++)
{
categories.push(path[i]);
}
// Track this product
_paq.push(['addEcommerceItem', sku, prod_name, categories, price, quant]);
});
// Track this order
_paq.push(['trackEcommerceOrder', order_id, total, sub_total, mva, shipping, false]);
});
}(window.jQuery.noConflict(true)));
</script>
Asking on StackOverflow is my last resort, I can't for the life of me figure out why this isn't tracking any sales for Internet Explorer 5-8.
I'll accept the first answer that leads me to solve this issue.
We figured it out. It turns out OpenTag was transforming the URL "//ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js" into "////ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js" only in Internet Explorer. We solved it by figuring out the protocol using JavaScript instead.
I have been trying to convert a xml feed into human readable form but have not succeeded . I have tried seeing the example given in tutorails section but its too complex. Please can someone help me out with what is to be done. I can do fine till parsing of xml.
I am using google script and the output has to be in google docs.
here is what i came up with till now
var response = UrlFetchApp.fetch("http://getRecords.php?oauth_token=3e73c7&lat="+lat+"&lon="+lon+"&searchFor="+text+"&miles=100&response_type=xml");
var doc = Xml.parse(response.getContentText(), true)
var root = doc.getElement();
var entryList = "<ul>\n";
var entries = root.getElements("details");
for (var i=0; i<entries.length; i++) {
var e = entries[i];
var name = e.getElement("name").getText();
}
entryList += "<li>name </li>" + name;
entryList += "</ul>\n";
return entryList;
Here is the xml
<record>
<details>
<id>212929</id>
<distance>0</distance>
<category cat="8" sub="202" id="1201">General</category>
<name>Text Book Center</name>
<short_desc>One of Kenya's finest</short_desc>
<long_desc>
One of Kenya's leading bookshops, the Text Book Center offers a wide selection of titles. There is everything here from textbooks to fiction to the latest Information Technology titles. The range of maps is especially impressive. The shop is spacious and cool, giving shoppers plenty of room to browse the shelves upon shelves of books. Look out for the regular special offers.
</long_desc>
<address>
<address1>Kijabe Street</address1>
<city>Nairobi</city>
<country>Kenya</country>
<latitude>0</latitude>
<longitude>0</longitude>
</address>
<neighborhood>Downtown</neighborhood>
<phone>+254 2 330 340</phone>
<email>info#tbc.co.ke</email>
<open_hours>8am-1pm; 2pm-5.30pm Mon-Sat.</open_hours>
</details>
</record>
</records>
how do i remove the tags and just print it out in docs. Please help
thanks
Looks root node opening tag is missing. Is it original doc? or just paste error?
Try like this
var response = UrlFetchApp.fetch("http://getRecords.php? oauth_token=3e73c7&lat="+lat+"&lon="+lon+"&searchFor="+text+"&miles=100&response_type=xml");
var doc = Xml.parse(response.getContentText(), true);
var records = doc.records.getElements("record");
var entryList = "<ul>\n";
for (var i=0; i < records.length; i++) {
var details = records[i].details;
var name = details.name.getText();
entryList += "<li>" + name + "</li>\n";
}
entryList += "</ul>\n";
return entryList;