UPS Tracking On Google Sheet does not work [duplicate] - google-sheets

This question already has answers here:
Scraping data to Google Sheets from a website that uses JavaScript
(2 answers)
Closed last month.
I used following formula get UPS live tracking feed and it works fine until yesterday. I think UPS has updated their site and this formula does not work anymore. Any idea or suggestions for how to get the tracking update from UPS?
=Index(IMPORTXML("https://wwwapps.ups.com/WebTracking/track?track=yes&trackNums="&A1,"//*[#id='tt_spStatus']"),1)
Now I am getting an error:
Imported content is empty

UPS updated this webpage. It no longer returns tracking information in the initial page response. It now instead makes a separate AJAX request to retrieve the information after the page is loaded.
Use this formula instead with the URL updated to a different page on their site that returns tracking information in the initial page response:
=Index(IMPORTXML("https://wwwapps.ups.com/tracking/tracking.cgi?tracknum="&A1,"//*[#id='tt_spStatus']"),1)

With Delivery Time and status where A1 has tracking code.
=index(IMPORTXML("https://wwwapps.ups.com/tracking/tracking.cgi?tracknum="&A1,"//*[contains(#class,'ups-group')]"),2)

Tracking with a few extra details (Where A1 is tracking no.):
=iferror(
IMPORTXML(
"https://wwwapps.ups.com/tracking/tracking.cgi?tracknum="&$A1,"//*[#id='tt_spStatus']")&iferror(": "&substitute(index(index(IMPORTHTML("https://wwwapps.ups.com/tracking/tracking.cgi?tracknum="&$A1,"table"),2),1),", United States",""),""
),
"--"
)
Result for package ready to ship: "Order Processed: Ready for UPS"
Result for in-transit parcel: "Picked Up: Atlanta, GA"

None of these work for me in 2020 but here's what does:
Add this function in script editor:
function IMPORTJSON(url,xpath){
try{
// /rates/EUR
var res = UrlFetchApp.fetch(url);
var content = res.getContentText();
var json = JSON.parse(content);
var patharray = xpath.split("/");
//Logger.log(patharray);
for(var i=0;i<patharray.length;i++){
json = json[patharray[i]];
}
//Logger.log(typeof(json));
if(typeof(json) === "undefined"){
return "Node Not Available";
} else if(typeof(json) === "object"){
var tempArr = [];
for(var obj in json){
tempArr.push([obj,json[obj]]);
}
return tempArr;
} else if(typeof(json) !== "object") {
return json;
}
}
catch(err){
return "Error getting data";
}
}
This formula will output transit status in your cell:
=IMPORTJSON(join("","http://shipit-api.herokuapp.com/api/carriers/ups/",A1),"activities/0/details")
I don't need the other details, so I made another cell that has a link to the ups tracking page if any other users need more information:
=HYPERLINK("https://www.ups.com/track?loc=en_US&tracknum="&A1&"&requester=WT/trackdetails)")

Related

How to connect Blogger website with Google spreadsheet using Google App script?

I want to know if I can use Google spreadsheet as a back-end database for my Blogger website. I have done so in past using Google Fusion Tables.
I can use Web Apps as well by using a custom domain to direct to their long URL. But when I update the script, I have to deploy the web app. This changes the long URL, so I need to update my redirection.
Is there a way to access & update a Google Spreadsheet from my website.
You cannot do this with Blogger.
However, you can do this with Sites.
If you setup a spreadsheet like this:
Then you create a web app from that like this:
var sheet = SpreadsheetApp.openByUrl("YOUR URL").getSheetByName("LinkConfig");
function getDataIndex(key) {
var Keys = sheet.getRange(2, 1, sheet.getMaxColumns(), 1).getValues().map(function(row) {return row[0]});
for (var i=0; i<Keys.length; i++) {
if (Keys[i]==key) return i+2;
}
}
function getData(key) {
return sheet.getRange(getDataIndex(key), 2).getValue();
}
function test() {
Logger.log(getData("url1"));
Logger.log(getData("url2"));
}
function webApp(key) {
//Get contents from target URL
var content = UrlFetchApp.fetch(getData(key)).getContentText();
return HtmlService.createHtmlOutput(content); //Returns new page with the same content
}
function doGet(e) {
if (e.parameter.key != null && e.parameter.key != undefined) {
return webApp(e.parameter.key);
} else {
return HtmlService.createHtmlOutput("<h1>Error! You didn't specify a 'key' parameter</h1>");
}
}
And deploy it.
Now, as long as you don't change that one URL (meaning you don't edit this main "config" webapp, you are able to change values on the spreadsheet and access the pages linked there by passing the key.
To use it in Sites, add an Embed element and set the URL to : yourwebappurl?key=keyvalue

How to schedule an hourly check on a list a bulk 404 URL checker?

I'm trying to set up a Google sheet that checks the response of a list of URLs (around 30) of them. I would like it to be scheduled every hour. It doesn't matter when in the hour the URL responses are checked but it would be preferable it's done every 60 minutes and also works when I'm not accessing the spreadsheet (i.e. offline)
I'm very new to using google sheets script editor so still trying to get to grips with it.
I used the script below. In the script editor I did the following:
Edit > Project Triggers > Add Trigger.
Choose Function > HTTP Response
Even source > Time driven
Select type of time based trigger > hour timer.
function HTTPResponse( uri )
{
var response_code ;
try {
response_code = UrlFetchApp .fetch( uri ) .getResponseCode() .toString() ;
}
catch( error ) {
response_code = error .toString() .match( / returned code (\d\d\d)\./ )[1]
;
}
finally {
return response_code ;
}
}
I expected the above setup to update the URL checks every hour...but they only seem to update when I manually update the cell.
Any help would be much appreciated.
Try this:
function checkUrls( ) {
var ss=SpreadsheetApp.openById('id');//set ss id
var sh=ss.getSheetByName('Sheet1');//set sheet name
var urlA=['https:example.com','http://example.com'];//u pick em
for(var i=0;i<urlA.length;i++) {
var ts=Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "'yyyy/mm/dd HH:mm:ss");//change format if you wish
var response=UrlFetchApp.fetch(urlA[i]);
sh.appendRow(ts,urlA[i],response.getResponseCode());
}
}
Setting up the Timer:
function setupHourlyTimer() {
if(!isTrigger('checkUrls')) {
ScriptApp.newTrigger('checkUrls').timeBased().everyHours(1).create();
}
}
function isTrigger(funcName){
var r=false;
if(funcName){
var allTriggers=ScriptApp.getProjectTriggers();
for(var i=0;i<allTriggers.length;i++){
if(funcName==allTriggers[i].getHandlerFunction()){
r=true;
break;
}
}
}
return r;
}

HTPP POST to Google Forms or Alternative

I have a google form setup that emails me upon a manual submission when somebody fills it out (new lead) and transfers the information to a Google spreadsheet. Easy enough to figure that out.
However, now I'm trying to figure out how to send the same information information contained within a url string and automatically POST that information to the form. Or find a company who offers that ability, via an api or other means. So far I've tested out jotform and a few others. The information passed along fine, but it doesn't auto populate the fields. I assume it's because it doesn't know that x=y due to the fields being named differently. I've found a ton of documentation about pre-populating the forms, but not much about filling out a form every time a new POST url is generated.
URL looks like the following
VARhttps://script.google.com/macros/s/XXXXXXXXXXXXXXXX/exec?/--A--
first_name--B--/--A--last_name--B--/--A--address1--B--/--A--city--B--/--A--
state--B--/--A--postal_code--B--/--A--phone_number--B--/--A--date_of_birth--
B--/--A--email--B--
Information passed is as follows
https://website
here.com/Pamela/Urne/123+Test+Street/Henderson/TX/75652/281XXXXXX/1974-01-
01/test0101cw#test.com
The script I'm testing out
// original from: http://mashe.hawksey.info/2014/07/google-sheets-as-a-database-insert-with-apps-script-using-postget-methods-with-ajax-example/
// original gist: https://gist.github.com/willpatera/ee41ae374d3c9839c2d6
function doGet(e){
return handleResponse(e);
}
// Enter sheet name where data is to be written below
var SHEET_NAME = "Sheet1";
var SCRIPT_PROP = PropertiesService.getScriptProperties(); // new property service
function handleResponse(e) {
// shortly after my original solution Google announced the LockService[1]
// this prevents concurrent access overwritting data
// [1] http://googleappsdeveloper.blogspot.co.uk/2011/10/concurrency-and-google-apps-script.html
// we want a public lock, one that locks for all invocations
var lock = LockService.getPublicLock();
lock.waitLock(30000); // wait 30 seconds before conceding defeat.
try {
// next set where we write the data - you could write to multiple/alternate destinations
var doc = SpreadsheetApp.openById(SCRIPT_PROP.getProperty("key"));
var sheet = doc.getSheetByName(SHEET_NAME);
// we'll assume header is in row 1 but you can override with header_row in GET/POST data
var headRow = e.parameter.header_row || 1;
var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
var nextRow = sheet.getLastRow()+1; // get next row
var row = [];
// loop through the header columns
for (i in headers){
if (headers[i] == "Timestamp"){ // special case if you include a 'Timestamp' column
row.push(new Date());
} else { // else use header name to get data
row.push(e.parameter[headers[i]]);
}
}
// more efficient to set values as [][] array than individually
sheet.getRange(nextRow, 1, 1, row.length).setValues([row]);
// return json success results
return ContentService
.createTextOutput(JSON.stringify({"result":"success", "row": nextRow}))
.setMimeType(ContentService.MimeType.JSON);
} catch(e){
// if error return this
return ContentService
.createTextOutput(JSON.stringify({"result":"error", "error": e}))
.setMimeType(ContentService.MimeType.JSON);
} finally { //release lock
lock.releaseLock();
}
}
function setup() {
var doc = SpreadsheetApp.getActiveSpreadsheet();
SCRIPT_PROP.setProperty("key", doc.getId());
}
I get a success message after accessing the url, but all information listed in the spreadsheet is "Undefined."
That's as far as I got so far. If somebody knows an easier solution or can point me in the right direction I'd appreciate it.

Using Google Assistant Change Firebase Database Value

I Created a android app in which if a press a button and value changes in Firebase database (0/1) , i want to do this using google assistant, please help me out, i searched out but didn't found any relevant guide please help me out
The code to do this is fairly straightforward - in your webhook fulfillment you'll need a Firebase database object, which I call fbdb below. In your Intent handler, you'll get a reference to the location you want to change and make the change.
In Javascript, this might look something like this:
app.intent('value.update', conv => {
var newValue = conv.prameters.value;
var ref = fbdb.ref('path/to/value');
return ref.set(newValue)
.then(result => {
return conv.ask(`Ok, I've set it to ${newValue}, what do you want to do now?`);
})
.catch(err => {
console.error( err );
return conv.close('I had a problem with the database. Try again later.');
});
return
});
The real problem you have is what user you want to use to do the update. You can do this with an admin-level connection, which can give you broad access beyond what your security rules allow. Consult the authentication guides and be careful.
I am actually working on a project using Dialogflow webhook and integrated Firebase database. To make this posible you have to use the fulfilment on JSON format ( you cant call firebasedatabase in the way you are doing)
Here is an example to call firebase database and display a simple text on a function.
First you have to take the variable from the json.. its something loike this (on my case, it depends on your Entity Name, in my case it was "tema")
var concepto = request.body.queryResult.parameters.tema;
and then in your function:
'Sample': () => {
db.child(variable).child("DESCRIP").once('value', snap => {
var descript = snap.val(); //firebasedata
let responseToUser = {
"fulfillmentMessages": [
{ //RESPONSE FOR WEB PLATFORM===================================
'platform': 'PLATFORM_UNSPECIFIED',
"text": {
"text": [
"Esta es una respuesta por escritura de PLATFORM_UNSPECIFIED" + descript;
]
},
}
]
}
sendResponse(responseToUser); // Send simple response to user
});
},
these are links to format your json:
Para formatear JSON:
A) https://cloud.google.com/dialogflow-enterprise/docs/reference/rest/Shared.Types/Platform
B) https://cloud.google.com/dialogflow-enterprise/docs/reference/rest/Shared.Types/Message#Text
And finally this is a sample that helped a lot!!
https://www.youtube.com/watch?v=FuKPQJoHJ_g
Nice day!
after searching out i find guide which can help on this :
we need to first create chat bot on dialogflow/ api.pi
Then need to train our bot and need to use webhook as fullfillment in
response.
Now we need to setup firebase-tools for sending reply and doing
changes in firebase database.
At last we need to integrate dialogflow with google assistant using google-actions
Here is my sample code i used :
`var admin = require('firebase-admin');
const functions = require('firebase-functions');
admin.initializeApp(functions.config().firebase);
var database = admin.database();
// // Create and Deploy Your First Cloud Functions
// // https://firebase.google.com/docs/functions/write-firebase-functions
//
exports.hello = functions.https.onRequest((request, response) => {
let params = request.body.result.parameters;
database.ref().set(params);
response.send({
speech: "Light controlled successfully"
});
});`

Script does not trigger on FormSubmit: Remove Duplicates in Google Sheet of Google Form responses based on column

I am trying to remove older duplicate form responses based on a column using the following code.
The credit for the code goes to: http://www.jacorre.com/tutorial/remove-duplicate-rows-google-spreadsheets/
The code in my script is:
function removeDuplicates() {
var ss = SpreadsheetApp.getActiveSpreadsheet(),
responses = ss.getSheetByName('Name of Source Sheet'),
range = responses.getDataRange(),
numRows = range.getNumRows()-1,
data = range.getValues(),
columnHeadings = [data[0]],
newData = [];
for (var i=numRows; i>0; i--) {
var row = data[i],
duplicate = false;
for (var j in newData) {
if (row[4] == newData[j][4]) {
duplicate = true;
// [4] is the column number from the 1st column. the above would be 1 + 4 = 5th column
}
}
if (!duplicate) {
newData.push(row);
}
}
var final = ss.getSheetByName('Name of Destination Sheet');
if (!final) {
var final = ss.insertSheet('Name of Destination Sheet');
}
final.clearContents();
final.getRange(1,1,1,columnHeadings[0].length).setFontWeight('bold').setValues(columnHeadings);
final.getRange(2, 1, newData.length, newData[0].length).setValues(newData);
}
This has been set to trigger on Form Submit. It works well on new form submissions.
However, when an existing response is edited using 'Form Edit URL' from: https://webapps.stackexchange.com/questions/89551/show-url-used-to-edit-responses-from-a-google-form-in-a-google-spreadsheet-by-us/89566 the values are not updated into the new sheet.
But if the function is run manually the updated row is updated to the new sheet.
How can I sort this problem? Any help will be appreciated. Thank you.
From my own answer posted at Web Applications SE.
I just did a test and found that the on form submit event it's not
being triggered when a response is edited.
I'm not sure if the on form submit trigger is working as intended, if
the above is due to a bug or to a glitch. To be sure, post an issue to
the Google Apps Script Issue
Tracker.
As a workaround, instead of using the on form submit event, use
another way to run your script, like a time-drive trigger.
References
Custom menus in Google Apps - Google Apps Script Guides
Simple or installable triggers - Google Apps Script Guides
Google Apps Script Support

Resources