GoogleSpreadsheets UrlFetchApp.fetch having problems getting data - google-apps-script

I'm trying to get stock data from yahoo using the method found here http://www.gummy-stuff.org/Yahoo-data.htm and when using UrlFetchApp.fetch on any stock URLs, it fails most of the time. Note that the same url works perfectly if I navigate to it through my browser.
Code,
var resp = UrlFetchApp.fetch("http://finance.yahoo.com/d/quotes.csv?s=" + securityName + "&f=sl1d1t1c1ohgv&e=.csv");
Where securityName is a stock symbol like AAPL or MSFT. Usually the error is address unavailable. It always works when I navigate to it through my browser.

The error is associated with yahoo site.
I made the test through javascript and had the same problem.
If you want to test access download.finance.yahoo.com and them open chrome console via F12 and put the code bellow:
function test() {
for(var x = 0; x < 100; x++) {
var req = new XMLHttpRequest();
req.open("GET", "http://download.finance.yahoo.com/d/quotes.csv?s=AAPL&f=sl1d1t1c1ohgv&e=.csv", false);
req.send();
if(req.status != 200) {
console.log("ERROR"); return;
}else {
console.log("OK");
}
}
}
test();
Check in my example that it worked 8 times (8 OK's) but in the 9th try it failed.

I am using the same script for months and the error has started appearing only recently, seems like Yahoo! screwed something up.

Related

HTTP server response 409 // Google web app

I'm having issues lately with my web app written in Google Apps Script.. From time to time it doesn't load properly and returns a 409 response.. It seems as it has no real reason, it's randomly. If I try to reload the page sometimes it loads properly, sometimes returns 409. The issue also just occurs some days and times. I can't figure out what can be the reason, the only thing I've noticed is that when the issue occurs also Google Apps Script Program seem to be slow / failing (for example takes longer than usual to save a file, sometimes fails on saving or showing logs etc).
Screenshot from web inspector when the issue occurs..
If the issue is on Google's end on their servers I guess there's not much I can do, but still checking if anyone else experienced these issues? Or is there anything I can do?
Also want to make sure it's not in my code.. I'm not in anyway a pro when it comes to programming, but a happy amateur. But if it was in my code, at least in my mind it would fail every time and not just only sometimes? I googles a bit and found on this site that when making POST requests you need to have your parameters correct, I'm using Twilio in my script but it's in a separate function and is not initiated when the script loads and I have it written as the linked documentation suggests..
Inserting some code snippets here - if anyone sees something that looks weird or could be the reason for my issues I would much appreciate your help!
SMS Function - can this be the reason??
function sendSms_(to, body) {
var messages_url = "https://api.twilio.com/2010-04-01/Accounts/ACe5***************/Messages.json";
var payload = {
"To": to,
"Body" : body,
"From" : "Killnoise"
};
var options = {
"method" : "post",
"contentType": "application/x-www-form-urlencoded", //This line I added after reading the linked documentation
"payload" : payload
};
options.headers = {
"Authorization" : "Basic " + Utilities.base64Encode("AC********************:f8be***************")
};
try { UrlFetchApp.fetch(messages_url, options); } catch(Err) {}
return;
}
doGet function - anything wrong here??
function doGet(e){
var staffId = e.parameter.staffId;
var key = e.parameter.key;
var lang = e.parameter.lang
// staffId = "S102", key = "abc"
if(auth_(staffId, key, lang) == true){
var output = HtmlService.createTemplateFromFile('StaffHtml').getRawContent();
/*/
Am I doing right above and below when the output is returned? I'm a bit green
here - should I write this in another way? Not seeing this could be the reason
for my current issue though..
/*/
output = output.replace('{{selectAlert}}', language('selectAlert', lang));
output = output.replace('{{takenAlert}}', language('takenAlert', lang));
output = output.replace('{{declineGivenAlert}}', language('declineGivenAlert', lang));
output = output.replace('{{beta}}', language('beta', lang));
output = output.replace(/{{surgePrompt}}/g, language('surgePrompt', lang));
output = output.replace('<%staffId%>', lang + staffId);
output = output.replace('{{invitationSent}}', language('invitationSent', lang));
output = output.replace('{{timeOutAlert}}', language('timeOutAlert', lang));
output = output.replace('{{newNotifications}}', language('newNotifications', lang));
var out = HtmlService.createHtmlOutput(output)
.addMetaTag('viewport', 'width=device-width, initial-scale = 1, user-scalable = no')
.setTitle('Killnoise').setXFrameOptionsMode(HtmlService.XFrameOptionsMode.DEFAULT);
return out;
} elseĀ {
return HtmlService.createHtmlOutput('Invalid URLS');
}
}

Chromecast Launch, what's with the DIAL parameters? Aren't I runing MY application, not some registered standard?

The following code displays a proper list of available chromecast devices on my network. But when I click on the links, the application never launches. There are a couple of things that I'm quite confused about that may or may not be related to this question:
If I'm making my own custom application, what's with the DIAL parameters and why do I have to pass them? I don't want to write an app for the DIAL standard... this is MY app.
Again related to the DIAL parameters, if I search for devices with any other query other than "YouTube" (a DIAL parameter), the list always comes up blank. I suppose I shouldn't care, as long as the device is listed... but again... the app won't launch.
It should be noted that my sender app is a chrome webpage.
I'm a bit confused as to where my "appid" goes int he launch parameters,'
<html data-cast-api-enabled="true">
<body>
hi!<BR/>
<script>
var cast_api, cv_activity;
if (window.cast && window.cast.isAvailable) {
// Cast is known to be available
initializeApi();
} else {
// Wait for API to post a message to us
window.addEventListener("message", function(event) {
if (event.source == window && event.data &&
event.data.source == "CastApi" &&
event.data.event == "Hello")
{
//document.write("Initialize via message.<br/>");
initializeApi();
//document.write("Api initialized via message.");
};
});
};
initializeApi = function() {
cast_api = new cast.Api();
cast_api.addReceiverListener("YouTube", onReceiverList);
};
var g_list;
onReceiverList = function(list) {
g_list = list;
// If the list is non-empty, show a widget with
// the friendly names of receivers.
// When a receiver is picked, invoke doLaunch with the receiver.
document.write("Receivers: "+list.length+"<br/>");
var t;
for(t=0;t<list.length;t++)
document.write('found:'+list[t].name+' ' +list[t].id+'<br/>');
};
onLaunch = function(activity) {
if (activity.status == "running") {
cv_activity = activity;
// update UI to reflect that the receiver has received the
// launch command and should start video playback.
} else if (activity.status == "error") {
cv_activity = null;
}
};
function launchy(idx)
{
doLaunch(g_list[idx]);
}
doLaunch = function(receiver) {
var request = new window.cast.LaunchRequest(">>>>>what REALLY goes here?<<<<<<< ", receiver);
request.parameters = "v=abcdefg";
request.description = new window.cast.LaunchDescription();
request.description.text = "My Cat Video";
request.description.url = "http://my.website.get.your.own/chomecast/test.php";
cast_api.launch(request, onLaunch);
};
stopPlayback = function() {
if (cv_activity) {
cast_api.stopActivity(cv_activity.activityId);
}
};
</script>
</body>
</html>
The part marked "what really goes here?" is the part that I THINK is wrong... I couldn't be completely wrong. My device is white listed, I have an appid (which I thought might go in that slot)... The documentation merely says ActivityType DIAL Parmeters are valid, mandatory.
The first argument to the LaunchRequest is your App ID, the one that you have received in an email as part of whitelisting process. Also, the "YouTube" in the initialize method should also be replaced with the same App ID.
I strongly suggest you look at the sample that is on GitHub for chrome sender to see how you can send a request to load a media on a cast device.

xmlHttpRequest to absolute url in WP8

I have stumbled across an odd issue when testing an app in Windows Phone 8. I am using xmlHttpRequest (cannot use ajax as I need to send as bufferarray) to make a call to a third party url. This works perfectly in Android and iOS, but throws an error in WP8
Example:
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function (){
if(xhr.readyState == 4){
if(xhr.status==200){
alert(xhr.responseText);
}else{
console.log("Error: "+xhr.responseText);
}
}
}
console.log("1");
xhr.timeout = 30000;
console.log("2");
xhr.open("POST","http://google.com",true);
console.log("3");
xhr.setRequestHeader("Content-Type",contentType+"; boundary=" + boundary);
console.log("4");
//other headers / auth etc
console.log("about to post");
xhr.send(bodyBuf);
this will result in:
log:"before request"
log:"1"
log:"2"
log:"Error in error callback: Cameraxxxxx = InvalidStateError"
However if I chang the open to:
xhr.open("POST","google.com",true); //or www.google.com etc
This goes right through to send, but then get a 404 status as the url is not found. I am obviously not using google in my request, but the error is the same. With "http://" it errors, but without, it doesn't error but cannot find the url.
Any thoughts appreciated.
I have found one thing, but unsure if it is related. According to W3C html 5 documentation, InvalidStateError is thown on open() if document is not fully active (when it is the active document of its browsing context). And if this is the cause of the error; how can the document not be the active document and how to I define the base url of an app that does not reside on a url (document suggests setting base to the document base url of document (or setting source origin/referrer source))?
Have gotten one step closer. After lots of fiddling about, I eventually found that for some reason on WP8 is needs the xhr to be opened before anything else is applied. So moving xhr.timeout below xhr.open sort of works.
this raises another problem in my particular case.. but that is probably another topic.
Solution for this was to move the timout to below the open.. so:
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function (){
if(xhr.readyState == 4){
if(xhr.status==200){
alert(xhr.responseText);
}else{
console.log("Error: "+xhr.responseText);
}
}
}
xhr.open("POST","http://google.com",true);
xhr.timeout = 30000;
xhr.setRequestHeader("Content-Type",contentType+"; boundary=" + boundary);
//other headers / auth etc
xhr.send(bodyBuf);

window.mozIndexedDB is null in Firefox 15

I'm trying to run the "Using IndexedDB" sample code on https://developer.mozilla.org/en-US/docs/IndexedDB/Using_IndexedDB
Right out of the gate I stumble with the first line of code:
window.indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB;
Using Firebug I see that window.indexedDB is undefined as expected for FF 15, window.webkitIndexedDB is undefined as expected (FF isn't webkit) but window.mozIndexedDB is null but not undefined. If it's null that tells me it exists but doesn't have a valid value/isn't initialized.
This is with Firefox 15.0.1 on OSX 10.6.8 and Ubuntu 12.04. Can somebody tell me why I'm not able to see/use window.mozIndexedDB? Am I doing something wrong?
For completeness, here's my JavaScript file:
window.indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB;
var request = window.indexedDB.open("MyTestDatabase", 3);
var db;
request.onerror = function (event) {
alert("Oops, request.onerror");
};
request.onsuccess = function (event) {
// Do something with request.result!
alert("Made it to request.onsuccess");
db = request.result;
};
// This event is only implemented in recent browsers
request.onupgradeneeded = function (event) {
alert("Made it to request.onupgradeneeded");
};
db.onerror = function (event) {
alert("Database error (db.onerror): " + event.target.errorCode);
};
My original HTML5 application uses jQuery Mobile & REST WS. In development I would run it directly from the file system and it works fine. For sharing with coworkers I have it running behind Apache httpd.
While adding the IndexedDB, I was trying to test by viewing files from the file system via the browser. It didn't work and that's what caused me to go back to square one and try running the example code from Mozilla.
It appears IndexedDB requires a domain even if it's localhost. I simply placed my code under public_html and viewed it via httpd/localhost and it's working perfectly.

IndexedDB not working in FireFox and IE

I have the latest versions of Firefox and IE, but the example in html5rocks.com is not working in these two browsers. I tested with Chrome and it works fine.
I have noted that these browsers does not fire any event ('onsuccess' or 'onerror') on attempting to open the indexedDB as follows.
var request = indexedDB.open("todos");
Please share any ideas/solution for this issue.
to make html5rocks demo work on Firefox you need to attach onupgradeneeded event on database open instead of setversion method for creating the database.
here is the code sample that works both on Firefox and Chrome:
myStorage.indexedDB.open = function() {
var v = 1;
var request = indexedDB.open("todos", v);
//Firefox code for db init
request.onupgradeneeded = function (e) {
myStorage.indexedDB.db = e.target.result;
var db = myStorage.indexedDB.db;
// We can only create Object stores in a setVersion transaction;
if(db.objectStoreNames.contains("todo")) {
var storeReq = db.deleteObjectStore("todo");
}
var store = db.createObjectStore("todo",
{keyPath: "timeStamp"});
}
request.onsuccess = function(e) {
myStorage.indexedDB.db = e.target.result;
var db = myStorage.indexedDB.db;
//Chrome code for db init
if (v!= db.version && db.setVersion) {
var setVrequest = db.setVersion(v);
// onsuccess is the only place we can create Object Stores
setVrequest.onerror = myStorage.indexedDB.onerror;
setVrequest.onsuccess = function(e) {
if(db.objectStoreNames.contains("todo")) {
db.deleteObjectStore("todo");
}
var store = db.createObjectStore("todo",
{keyPath: "timeStamp"});
myStorage.indexedDB.getAllTodoItems();
};
}
else
myStorage.indexedDB.getAllTodoItems();
};
request.onerror = myStorage.indexedDB.onerror;
}
Edit: Here is a link to working version of the html5roks ToDo demo, which I maintain on github, expanded with two new features for viewing details data and updating values.
Chrome is behind on the IndexedDB standard.
There was a new revision introduced in December and Firefox and IE have upgraded. Chrome has not yet.
I believe it's mostly folks from the Chrome crew who run HTML5Rocks.com so it makes sense why these examples would be behind.
The big change between the pre and post-December 2010 API are the change in setVersion requests and the new onupgradeneeded callback.
Todo list example is outdated IndexedDB specification implemented on chrome. Now you got to use onupgardedneeded method, and well setVersion too for now.
IndexedDB is not supported on IE. Visit html5test.com for verification
Edit 2015: IndexedDB API is available in IE as of version 10