I have a Google script trigger for tracking the plugin's version from all my wp websites by fetching an API from each website, I also attach the "last update" time to see the last time the API was called.
but when my trigger runs, it keeps resulting in the same data since the first call, even when I add/delete new plugins. From the error catch, the function runs smoothly but the result doesn't there.
why is it? do google script store the data? or is there any limitation in fetching API data?
edit
here's the code of the function to fetch the API and the trigger function
function teste()
{
var all_data = getDataFromPluginList()
/*return
[ { first_cell: 'A2',
last_cell: 'I8',
first_row: 2,
last_row: 8,
total_row: 7,
url: 'https://example1.wpengine.com/' },
{ first_cell: 'A10',
last_cell: 'I15',
first_row: 9,
last_row: 14,
total_row: 6,
url: 'https://example2.wpengine.com/' } ]
*/
for (var i = 0; i < all_data.length; i++) {
trigger_(all_data[i].url, all_data[i].first_row, all_data[i].last_row, all_data[i].total_row);
}
}
function trigger_(url, first_row, last_row, total_row)
{
var new_trigger = ScriptApp.newTrigger("writePluginData").timeBased().everyMinutes(1).create();
var trigger_id = new_trigger.getUniqueId();
PropertiesService.getUserProperties().setProperty(trigger_id, url+","+first_row+","+last_row+","+ total_row);
}
function writePluginData(event)
{
var trig = ScriptApp.getProjectTriggers();
let sheet_name = 'trigger_result';
let lowest_row = lowestRow(sheet_name);
for(var i =0; i<trig.length; i++)
{
if(trig[i].getUniqueId()== event.triggerUid )
{
var urlParam = PropertiesService.getUserProperties().getProperty(event.triggerUid);
urlParam = urlParam.split(",");
var url = urlParam[0];
var first_row = urlParam[1];
var last_row = urlParam[2];
var total_row = urlParam[3];
var new_first_row = 0;
var ss = SpreadsheetApp.getActive().getSheetByName(sheet_name); // change accordingly
var data = ListPlugins(url);
for (var i = 1; i < data.length; i++) {
let empty = ''
data[i].push(empty);
}
if(total_row != data[0][7]){
ss.deleteRows(first_row, first_row);
ss.getRange(lowest_row + 1 , 1,data[0][7],9).setValues(data);
} else {
ss.getRange(first_row, 1,total_row,9).setValues(data);
}
}
}
}
function ListPlugins(url) {
let sheet_name = 'apps and plugins'
var options = {
"async": true,
"crossDomain": true,
"method" : "GET",
"headers" : {
"Token" : TOKEN_HERE,
"cache-control": "no-cache"
}
};
var urlEncoded = encodeURI(url)
let api_url = urlEncoded + "/wp-json/bd/v1/public/plugin-list/"
var jsondata = UrlFetchApp.fetch(api_url,options)
var object = JSON.parse(jsondata.getContentText())
if(object){
return object;
} else {
return "not found"
}
}
and the result data would be like this
Related
I'm trying to pull data from Airtable using Apps Scripts but all of it doesn't transfer over due to size. What do I need to add/change in order for it work?
function importCA() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ca_sheet = ss.getSheetByName("CA")
var ca = getCA();
ca_sheet.getRange(1,1, ca.length, ca[00].length).setValues(ca)
}
function getCA() {
var ca = requestAirtable();
//console.log("ca: ", ca)
var ca_info = []
ca_info.push(["Name", "Emails", "Districts", "Job Title", "Course", "Completed", "Start Dates"])
for(i=0; i<ca.length; i++) {
var fields = ca[i].fields;
ca_info.push([
fields.Name,
fields.Emails,
fields.Districts,
fields.Title,
fields.Course,
fields.Completed,
fields.StartDates,
])
}
console.log("CA ", ca_info)
return ca_info;
}
function requestAirtable() {
var url = "[removed]"
var headers ={
"Authorization": "[removed]",
"Content-type" : "application/json"
}
var options = {
headers: headers,
method: "GET"
}
var response = UrlFetchApp.fetch(url, options).getContentText();
var result = JSON.parse(response);console.log("result: ", result)
return result.records
}
I tried to altering the line:
for(i=0; i<ca.length; i++) {
but didn't work.
If you must log it to console, you could always log it while you are pushing it to the array instead of trying to log the entire array later.
console.log(ca_info.push([
fields.Name,
fields.Emails,
fields.Districts,
fields.Title,
fields.Course,
fields.Completed,
fields.StartDates
])
I'm just learning javascript and I'm trying to update woocommerce products through GAS.
The issue in question is the following:
I have a variable that parses the response from woocommerce
for (let sku of skuSearch) {
var surl = website + "/wp-json/wc/v3/products?consumer_key=" + ck + "&consumer_secret=" + cs + "&sku=" + sku;
var url = surl
Logger.log(url)
var result = UrlFetchApp.fetch(url, optionsGet);
if (result.getResponseCode() == 200) {
var wooProducts = JSON.parse(result.getContentText());
Logger.log(result.getContentText());
}
Then I have another for to iterate and from a new array that contains id + sku of wooProducts and price from a different variable that takes the updated price from my sheet:
var idLength = wooProducts.length;
Logger.log(idLength);
for (var i = 0; i < idLength; i++) {
var container = [];
Logger.log(i);
container.push({
id: wooProducts[i]["id"],
sku: wooProducts[i]["sku"],
price: data[i]["price"],
});
I can't tell exactly why it doesn't work. I mean the for loop works, it pushes id, sku and price in every loop, it's just that data[i] only provides the first ¿object? instead of looping like wooProducts which add +1 at every loop.
I'll copy 3 loops so it's crystal clear, I'm not sure it's already clear.
Loop 1:
[{"id":1622,"sku":"PD-1000-B","price":8145.9}]
Loop 2:
[{"id":1624,"sku":"PD-1007-A","price":8145.9}]
Loop 3:
[{"id":1625,"sku":"PD-1014","price":8145.9}]
As you can see id+sku change but price doesn't.
For further context, I'll include the data variable that is declaed outside the For:
const data = codigos.map(function(codigos, indice) {
return {
sku: codigos[0],
price: precios[indice][0]
}
})
//** EDIT:
I'm adding the entire code so it makes more sense maybe?
function getDataloopwoo() {
var ck = 'xxx'
var cs = 'xxx'
var website = 'xxx'
var optionsGet =
{
"method": "GET",
"Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
"muteHttpExceptions": true,
};
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('PreciosBULK');
var codigos = sheet.getRange("A2:A").getValues();
var precios = sheet.getRange("B2:B").getValues();
var skuSearch = sheet.getRange("A2:A").getValues();
const data = codigos.map(function(codigos, indice) {
return {
sku: codigos[0],
price: precios[indice][0]
}
})
Logger.log(skuSearch)
for (let sku of skuSearch) {
var surl = website + "/wp-json/wc/v3/products?consumer_key=" + ck + "&consumer_secret=" + cs + "&sku=" + sku;
var url = surl
Logger.log(url)
var result = UrlFetchApp.fetch(url, optionsGet);
if (result.getResponseCode() == 200) {
var wooProducts = JSON.parse(result.getContentText());
Logger.log(result.getContentText());
}
var idLength = wooProducts.length;
Logger.log(idLength);
var container = [];
for (var i = 0; i < idLength; i++) {
Logger.log(i);
container.push({
id: wooProducts[i]["id"],
sku: wooProducts[i]["sku"],
price: data[i]["price"],
});
Logger.log(container);
var wooBatch = JSON.stringify(container);
Logger.log(wooBatch);
}
}
}
// FINAL EDIT with "solve":
So I figured it was inefficient to ask by 1 sku at a time, so now I'm asking by the 100, and paginating with a while if and saving id, sku, price to the container array.
I will need now to compare the container array to the array with the updated prices and form a new array with id, sku and updated price, I'm reading up on that right now. The code:
function getDataloopwoo() {
var ck = 'xx'
var cs = 'xx'
var website = 'xx'
var optionsGet =
{
"method": "GET",
"Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
"muteHttpExceptions": true,
};
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('PreciosBULK');
var codigos = sheet.getRange("A2:A").getValues();
var precios = sheet.getRange("B2:B").getValues();
const data = codigos.map(function(codigos, indice) {
return {
sku: codigos[0],
price: precios[indice][0]
}
})
var container = [];
var surl = website + "/wp-json/wc/v3/products?consumer_key=" + ck + "&consumer_secret=" + cs + "&per_page=100";
var url = surl
//Logger.log(url)
var result = UrlFetchApp.fetch(url, optionsGet);
var headers = result.getAllHeaders();
var total_pages = headers['x-wp-totalpages'];
var pages_count = 0;
while (pages_count < total_pages) {
if (result.getResponseCode() == 200) {
var wooProducts = JSON.parse(result.getContentText());
//Logger.log(result.getContentText());
}
for (var i = 0; i < wooProducts.length; i++) {
//Logger.log(i);
container.push({
id: wooProducts[i]["id"],
sku: wooProducts[i]["sku"],
price: wooProducts[i]["price"],
});
Logger.log(container);
}
pages_count++;
if (pages_count < total_pages){
var surl = website + "/wp-json/wc/v3/products?consumer_key=" + ck + "&consumer_secret=" + cs + "&per_page=100" + "&page=" + (pages_count + 1);
var url = surl
var result = UrlFetchApp.fetch(url, optionsGet);
Logger.log(url);
}
}
}
You're reseting the array container in every iteration of the loop:
for (var i = 0; i < idLength; i++) {
var container = []; // <-----------------here
...
container.push({
...
I think the array should be defined outside the loop:
var container = [];
for (var i = 0; i < idLength; i++) {
...
container.push({
...
I am using this function to pull information from coinmarketcap using their v2 api. The problem I am getting is that if a "website_slug" does not exist on coinmarketcap, I get an incorrect range width error instead of the function just putting xxx in the cell. This can be recreated by having a cell in column B that doesn't match a website_slug on cmc (https://api.coinmarketcap.com/v2/ticker/).
function getMarketCap(sheetname) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName(sheetname);
var assets = [];
var idRange = sheet.getRange("B1:B");
var lastRow = getLastRowOfRange(idRange);
var cellRange = sheet.getRange(1, 2, lastRow).getValues();
var mcRange = sheet.getRange(1, 3, lastRow);
var mcValues = [];
for (var i = 0; i < cellRange.length; i++) {
assets[i] = cellRange[i];
}
var req = [];
for (var i = 0; i < 16; i++) {
req.push({
muteHttpExceptions: true,
method: "get",
url: "https://api.coinmarketcap.com/v2/ticker/?start=" + (i * 100 + 1),
});
}
var responses = UrlFetchApp.fetchAll(req);
var res = responses.filter(function(e){return e.getResponseCode() == 200}).map(function(e){return JSON.parse(e.getContentText())});
if (responses.length != res.length) Logger.log("%s errors occurred.", responses.length - res.length);
var mcValues = [];
assets.forEach(function(e, h) {
mcValues[h] = []
res.some(function(f) {
Object.keys(f.data).some(function(g) {
if (f.data[g].website_slug == e[0]) {
mcValues[h][0] = f.data[g].quotes.USD.market_cap;
return true;
}
});
if (mcValues[h][0]) return true;
});
if (!mcValues[h][0]) mcValues[h][0] = 'xxx';
});
mcRange.setValues(mcValues);
}
I would like to make a object with the data I retrieve with ajax call.
The problem, I call my function every ajax call and it make a array with 1 entries * my 10 files but I would like 1 array with 10 entries.
function mapXML(data) {
for (let i = 0; i < data.length; i++) {
let maps = 'maps/' + data[i];
$.ajax({
url: maps,
type: "GET",
datatype: "xml",
success: function(xml) {
traitementCarte(xml)
}
});
}
}
function traitementCarte(xml) {
console.log(xml)
let lat = [],
lng = [],
test = [];
var lastElementLat,
lastElementLng;
$(xml).find('trkpt').each(function(i, el) {
lat[i] = parseFloat($(this).attr('lat'));
lng[i] = parseFloat($(this).attr('lon'))
});
lastElementLat = lat[lat.length - 1];
lastElementLng = lng[lng.length - 1];
let locations = {
lat: lastElementLat,
lon: lastElementLng
};
test.push(locations);
console.log(test)
}
I don't have solution for my problem.
Thanks
You need to declare the array variable outside the traitementCarte() function, otherwise you're creating a new array every time you call it.
var test = [];
function traitementCarte(xml) {
console.log(xml)
let lat = [],
lng = [];
var lastElementLat,
lastElementLng;
$(xml).find('trkpt').each(function(i, el) {
lat[i] = parseFloat($(this).attr('lat'));
lng[i] = parseFloat($(this).attr('lon'))
});
lastElementLat = lat[lat.length - 1];
lastElementLng = lng[lng.length - 1];
let locations = {
lat: lastElementLat,
lon: lastElementLng
};
test.push(locations);
console.log(test)
}
I have got an ajax GET request that pulls in data through a loop. What I am trying to achieve is to get posts that are relevant but are not in the predefined id value of the current post you are on. So I have this function below:
var _permId = $('#work-area').data('current-id');
var getRelatedPosts = function() {
$.ajax({
url: '/wp-json/posts?type=case-studies&filter[taxonomy]=awards&filter[term]='+_awardsPart+'',
success: function ( query ) {
//List some global variables here to fetch post data
// We use base as our global object to find resources we need
// _permId is the var that tells me the current id of this post
var posts = query;
postFull = [];
for(var i = 0; i < posts.length; i++) {
//terms.push(term);
var postObject = posts[i];
postFull.push(postObject);
for (var key in postObject) {
//console.log(postObject[key]);
if (postObject[key] === _permId) {
console.log('this is the same as this post');
}
}
};
},
cache: false
});
};
What I want to do is not allow any content through if the post object id is the same value as _permId.
Here is an idea of the json that is retrieved with keys and values:
Object {ID: 4434, title: "new brand case", status: "publish", type: "case-studies", author: Object…}
The ID is the value I want to set an argument against.
You haven't to loop on the object if you just want to check the ID :
...
postFull = [];
for(var i = 0; i < posts.length; i++) {
var postObject = posts[i];
postFull.push(postObject);
if(postObject.ID === _permId) {
//they have the same id
}
};
EDIT :
To get the datas you want you can use $.grep :
var newArray = $.grep(posts, function(e, i){return e.ID !== _permiId;});
or in pure JS
var newArray = [];
for(var i = 0; i < posts.length; i++){
var p = posts[i];
if(p.ID !== _permId){
newArray.push(p);
}
}