How do I get data from the Bitfinex web API using javascript - javascript

Here is a link to their API documentation
I would like to practice web programming by creating a bitcoin price ticker from scratch. My plan is to serve a script that makes api calls to exchanges to display the data. This will mean I only have to serve the script, not handle the data server-side.
I know that part of programming is learning from documentation, but the docs from bitfinex are very sparse and I couldn't find a tutorial.
I created an index.html to test my javascript. It returns a console error:
XMLHttpRequest cannot load https://api.bitfinex.com/v1/pubticker/:last_price.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'null' is therefore not allowed access.
Here is the full index.html:
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js">
</script>
</head>
<body>
<script>
$.getJSON("https://api.bitfinex.com/v1/pubticker/:last_price",
function(data, status){
alert("price: "+data +" status: " + status);
}
)
</script>
Thank you stack exchange
</body>

You can't — at least, not with Javascript. That API is not configured to allow calls from Javascript running on other web sites. You will need to call this API from a script running on your web server.
(Also, for what it's worth, the :symbol token in the URL is supposed to be replaced with the symbol of the ticker you're trying to look up, e.g. /v1/pubticker/BTCUSD for BTC/USD exchange prices.)

If you run a webserver with SSL on it (as Duskwuff said, "You will need to call this API from a script running on your web server.") then you can deploy the following file to it:
<?php
$func = $_GET['fn'];
if(in_array($func,array('getBfx')))
{
$func();
}
function getBfx()
{
$a = $_GET['api'];
echo "objData = ".file_get_contents($a);
}
?>
Then you can include the script from the URL to which you deployed it, with ?func=getBfx&api=https://api.bitfinex.com/v1{Whatever} tacked onto the end of it. I didn't have to escape that URL, but you might.

Related

doPost(e) with no result - Google script as API

I can't seem to get the simplest doPost to reply in Scripts, tried a few things from around the internet, and cannot get a Post to reply.
I have reduced it to as simple as possible to get a reply, as below.
function doPost(e) {
var HTMLString = "<style> h1,p {font-family: 'Helvitica', 'Arial'}</style>"
+ "<h1>Hello World!</h1>"
+ "<p>Welcome to the Web App";
HTMLOutput = HtmlService.createHtmlOutput(HTMLString);
Logger.log(HTMLOutput);
// Return plain text Output
return ContentService.createTextOutput(HTMLOutput);
}
Deployment settings:
I am using postman to send the POST
No result.
Any ideas?
I understood your setting of Web Apps from I have edited the question to show the deployment settings are "me" and "anyone".
About Not sure what you mean by "Reflect your latest script" to obtain a result sorry, can you explain more?, when you use Web Apps, it is required to prepare a script with Google Apps Script. In this case, when you modify your script, it is required to reflect the latest script to the current or a new version of the deployed Web Apps. Here, when the script is reflected in Web Apps as a new version, the deployment ID is changed. By this, the endpoint of Web Apps is also changed. I thought that in this case, it might not be useful for your situation. So, I proposed to reflect the latest script in Web Apps without changing the endpoint of Web Apps. If you cannot understand it, I thought that this post might be useful. Ref (Author: me)
About The goal is to create an API, that will do things, but I haven't been able to get a result for a doPost at all. I have managed to doGet with a result, which is lovely, but I want the Post version., unfortunately, in your current script, an object of "HtmlOutput" is returned by return ContentService.createTextOutput(HTMLOutput);. By this, a text of "HtmlOutput" is returned. If you want to put a value to Web Apps as the POSt method and you want to retrieve the returned value, how about the following modification?
function doPost(e) {
return ContentService.createTextOutput(JSON.stringify(e));
}
When you modified your script of Web Apps, please reflect the latest script to the Web Apps. In this case, when you want to use the endpoint of Web Apps without changing the endpoint, please check this post.
For example, when the HTTP request is run by including the request body of '{"key":"value"}' as a text with the POST method, {"parameter":{},"postData":{"contents":"'{\"key\":\"value\"}'","length":17,"name":"postData","type":"text/plain"},"parameters":{},"contextPath":"","contentLength":17,"queryString":""} is returned.
Note:
From your showing script, when you want to return your value of HTMLString, the modified script is as follows. But, in this case, the HTML is returned as text. Please be careful about this. If you want to see the rendered HTML, please use doGet and return return HtmlService.createHtmlOutput(HTMLString);.
function doPost(e) {
var HTMLString = "<style> h1,p {font-family: 'Helvitica', 'Arial'}</style>"
+ "<h1>Hello World!</h1>"
+ "<p>Welcome to the Web App";
HTMLOutput = HtmlService.createHtmlOutput(HTMLString).getContent();
return ContentService.createTextOutput(HTMLOutput);
}
Reference:
Taking advantage of Web Apps with Google Apps Script (Author: me)
Redeploying Web Apps without Changing URL of Web Apps for new IDE (Author: me)

Security Error - The page includes one or more script files from a third-party domain

I'm trying to embed "Authentication via Google" to a simple web app I am working on. I used following code to do this.
<html>
<head>
<title> Home </title>
<script src = "https://apis.google.com/js/platform.js?onload=onLoadCallback" ></script>
<script>
function changePage() {
if (!gapi.auth2.getAuthInstance().isSignedIn.get()) {
window.location.href = "login.jsp";
}
}
</script>
<script>
gapi.load('auth2', function () {
gapi.auth2.init().then(changePage);
});
</script>
<script>
</script>
<script>
var user;
function signOut() {
var auth2 = gapi.auth2.getAuthInstance();
user = auth2.signOut().then(changePage);
}
;
</script>
<meta name="google-signin-client_id" content="xxxxxxxxxxxx">
</head>
<body style="background-color:azure;">
<div class="vertcal-center">
<div class="myclass">
<h1>Welcome to home page
</h1>
<button type="button" class="button" onclick="signOut()">Log Out</button>
</div>
</div>
</body>
</html>
However, when I ran ZAP analysis on my code, it gives me a Low Risk alert saying "The page includes one or more script files from a third-party domain" . It points to following line as the line with the issue.
<script src = "https://apis.google.com/js/platform.js?onload=onLoadCallback" ></script>
I refer OWASP tutorial which describes about this issue, and I understand that this can introduce the 3 risks they have mentioned which are
The loss of control over changes to the client application.
The execution of arbitrary code on client systems.
The disclosure or leakage of sensitive information to 3rd parties.
However, I also understand that if I am going to use Google authentication, I'll have to trust Google and assume that they won't do anything bad here.
Is there any better way to do this in my code so that ZAP will not warn me?
Is it okay to ignore this alert?
What ZAP looks at is the hostname of your web page and the hostname of the embedded javascripts.
Since your website hostname will not be google.com anyway, ZAP will always complain.
Only thing is we are trusting the external JS.
But you can download the external JS file and host it within your web app.
That way you are calling your own JS file and then ZAP will ignore it.
However, if google modifies the JS file after that, your local JS file won't get the new modifications. So my opinion is you can justify this and ignore the issue in ZAP report.
When you are using external javascripts, make sure to check if they have any reported known vulnerabilities. You can refer [1] to know more information for a similar topic.
[1] https://medium.com/#PrakhashS/using-retire-js-with-zap-to-identify-vulnerabilities-in-javascript-libraries-7baad56690aa#.cotei58mk
The way this rule works is described in the help that comes with ZAP, which is also available online: https://github.com/zaproxy/zap-core-help/wiki/HelpAddonsPscanrulesPscanrules#cross-domain-script-inclusion :
Cross Domain Script Inclusion
Validates whether or not scripts are included from domains other than the domain hosting the content. By looking at the "src" attributes of "script" tags in the response. Allowed Cross-Domain scripts:
Any script with a non-empty "integrity" attribute is ignored - the
integrity value is not checked as this will be checked by the browser
At MEDIUM and HIGH thresholds if a script URL falls within a context that also includes the URL of the base message no alerts will
be raised.
So you can either specify an 'integrity' attribute or create a context and include in it all of the domains you trust.

HTTP Get request from Angular JS receives empty reply

Since I am fairly new to web development, this might very well be a very easy to solve question. Unfortunately I am not able to solve this myself as I have no clue on where to search.
Currently I'm trying to get data out of an ASP.NET Web API that is running on my local machine. To get this data I've written a small piece of JavaScript using AngularJS:
function MainController($scope, $http) {
$http.get("http://localhost/DBLayerDLL/api/tablets/1005").
then(function(response) {$scope.data=response;},
function(response){$scope.data=response;});
}
The HTML page that is used, is also very simple:
<!DOCTYPE html>
<html ng-app>
<head>
<script data-require="angular.js#*" data-semver="1.3.0-beta.5" src="https://code.angularjs.org/1.3.0-beta.5/angular.js"></script>
<script src="scripts/main.js"></script>
</head>
<body ng-controller="MainController">
<h1>Hello World!</h1>
<div>
<div>Data: {{data}}</div>
</div>
</body>
</html>
The action of the controller in my Web API is implemented as follows:
[RoutePrefix("api/tablets")]
public class TabletsController : ApiController
{
[Route("{ID}")]
[HttpGet]
public TabletRecord GetTablet(int ID)
{
TabletRecord tablet = new TabletRecord();
tablet.LoadFromID(ID);
return tablet;
}
}
The problem lies within the response I get from the HTTP request. When printed on the page it looks like this:
{"data":"","status":0,"config":{"method":"GET","transformRequest":[null],"transformResponse":[null],"url":"http://localhost/DBLayerDLL/api/tablets/1005","headers":{"Accept":"application/json, text/plain, */*"}},"statusText":""}
Which is not correct, as I know that my API will return data. It gets even weirder for me when I use Fiddler to see what is going on. Within Fiddler I can see the request and see that the response is completely different from what I see on my web page:
Due to my lack of knowledge and experience I don't know what is going on...
Is there any thing I am doing wrong in my JavaScript?
Should I do something else within the HTML page?
Or is there any special thing that I need in my Web API?
Any help or thoughts are highly appreciated!
After spending quite some more time on this I've found a couple of things were needed to solve my problem:
I've noticed that I had to enable CORS on my Web API in order for the JavaScript to be able to make requests to my Web API. I've came to this via this link, I just followed the steps as explained to get it up and running.
I've also discovered at first that I can also get my data using the general XMLHttpRequest object available in JavaScript. By first getting my data to display using this method, I've also discovered the next item:
The response object returned by the $http.get method is actually the object that is directly returned by my Web API. So I can just use the defined properties to display the required data.
On normal php i get the angular variables with
$data = file_get_contents("php://input");
you should look if
print_r($data);
contains what u need.

Format of google app engine API url

I created a google App engine project locally. Added a simple "Place" API and started the engine. I noticed that the server is waiting on http://localhost:8888/_ah/api base URL.
Now, I want to use the google javascript client API to call my API (I am assuming that is possible). So I created a simple local website and created a simple HTML/javascript page. Then I loaded the google javascript client library and executed.
Here is my page
<html>
<head>
<script>
function load() {
console.log("API client loaded");
var ROOT = 'http://localhost:8888/_ah/api';
gapi.client.load('getPlace', 'v1', function() {
console.log("API called");
}, ROOT);
}
</script>
<script src="https://apis.google.com/js/client.js?onload=load"></script>
</head>
<body>
<div> Hello </div>
</body>
</html>
Now, when I run it, I get a 404 error. Then I checked the URL that the browser places. It looks like this:
http://<local>:8888/_ah/api/discovery/v1/apis/getPlace/v1/rpc?fields=methods%2F*%2Fid&pp=0
A few questions:
What I am doing should work correct ? (local app engine + javascript
library)
What is the expected URL for app engine generated API ? (what is the "discovery" in the URL?)
What is the "rpc" at the end ? I am hoping to create REST API

Showing documents from Google Drive on webpage

Is it possible to show the documents from my drive on a webpage? I want the user to be able to click the document and download it, directly from my drive. How would I go about doing this? Thank you for your suggestions.
The fastest and easiest solution is to embed the folder using an iframe (no javascript needed). Obviously this is also the least flexible solution, although you can use CSS to change the layout of the iframe contents (see below).
Google Drive won't allow embedding of the url you would normally use. It has its X-Frame-Options header set to "SAMEORIGIN", preventing use in an iframe. So you have to use the following link, which will allow embedding:https://drive.google.com/embeddedfolderview?id=DOCUMENT_ID#VIEW_TYPE
DOCUMENT_ID is the id that is mentioned in the normal share link (which looks like https://drive.google.com/folderview?id=DOCUMENT_ID), so you can just copy that from there.
VIEW_TYPE should be either 'grid' or 'list', depending on your preference.
And if you need to change the style of the iframe content, take a look at this solution.
For HTML/JavaScript solution, look at the following links:
https://developers.google.com/drive/quickstart-js
https://www.youtube.com/watch?v=09geUJg11iA
https://developers.google.com/drive/web/auth/web-client
Here's the simplest way using JavaScript, most of the complexity is in
your WebApp authorization. The example below reads files IDs, names and description in a folder you specify.
- go to: https://cloud.google.com/console/project
and create a new project "xyz"
- Select "APIs & auth", disable the ones you don't need, enable "Drive API"
- Select "Credentials",
push "CREATE NEW CLIENT ID" button
x Web Application
Authorized Javascript origins: "https://googledrive.com/"
Authorized redirect URI: "https://googledrive.com/oauth2callback"
it will result in:
Client ID: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com
Email address: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx#developer.gserviceaccount.com
Client secret: xxxxxxxxxxxxxxxxxxxx
Redirect URIs: https://googledrive.com/oauth2callback
Javascript Origins: https://googledrive.com/
- in the code below, replace
CLIENT_ID with xxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com
FOLDER_ID with the ID you see in the folder address line,
https://drive.google.com/?tab=mo&authuser=0#folders/xxxxxxxxxxxxxxxxxxx
- run it, authorize
I don't know if you read JS, the code can be followed from bottom up, I made is as simple as possible.
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script>
var FOLDER_ID = '.xxxxxxxxxxxxxxxxxx'; // the folder files reside in
var CLIENT_ID = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com';
var SCOPE = //'https://www.googleapis.com/auth/drive';
[
'https://www.googleapis.com/auth/drive',
'https://www.googleapis.com/auth/drive.file', // for description,
];
function rsvpCB(resp) {
var picAlbumLst = '<ul>\n';
for (i=0; i<resp.items.length; i++)
picAlbumLst += (
' <li>'+resp.items[i].id+', '+resp.items[i].title+', '+resp.items[i].description+'</li>\n');
picAlbumLst += "</ul>\n";
$('#container').append(picAlbumLst);
}
function rqstCB() { //test # https://developers.google.com/drive/v2/reference/files/list
var rv = gapi.client.drive.files.list({
'q': '"'+FOLDER_ID+'" in parents and trashed = false',
'fields' : 'items(id,title,description)' //'items(id,title,description,indexableText)'
}).execute(rsvpCB);
}
// authorization server reply
function onAuthResult(authResult) {
var authButton = document.getElementById('authorizeButton');
authButton.style.display = 'none';
if (authResult && !authResult.error) { // access token successfully retrieved
gapi.client.load('drive', 'v2', rqstCB);
} else { // no access token retrieved, force the authorization flow.
authButton.style.display = 'block';
authButton.onclick = function() {
checkAuth(false);
}
}
}
// check if the current user has authorized the application.
function checkAuth(bNow) {
gapi.auth.authorize({'client_id':CLIENT_ID, 'scope':SCOPE, 'immediate':bNow}, onAuthResult);
}
// called when the client library is loaded, look below
function onLoadCB() {
checkAuth(true);
}
</script>
<script src="https://apis.google.com/js/client.js?onload=onLoadCB"></script>
<body style="background-color: transparent;">
<input type="button" id="authorizeButton" style="display: none" value="Authorize" />
<div id="container">
</div>
</body>
This should be done with Google API. You can search google drive php api list files on google. And also I found this and this on SO.
Here are some main points:
Do you want anyone with the URL to be able to see your document? You can share a document as public to anyone on the internet. Plus you can set read access to specific folders. Just right click a Google Doc file, and choose 'Share' from the short cut menu.
I'm assuming you want people to download your docs, even when you are not signed in. This is called 'Offline Access', and is one of many terms you'll need to figure out in order to do all of this with a program.
If you only want to give read access to the user, using JavaScript, jQuery, etc on the front end is a viable option. You can also do this in PHP, it's just a matter of personal preference.
To do all of this in code, you need to grant authorization to read your files. The oAuth2 process has multiple steps, and it's good to understand the basic flow. Setting up the code and the webpages to initially grant authorization, then retrieve and store the tokens can get confusing.
Your Google Project has a setting for where the origin of the authorization request is coming from. That is your website. But if you want to develop and test locally, you can set the Javascript Origins to http://localhost
How much time do you have, and how much programming experience? Would it be easier to give the user a few lines of instruction to "Manually" download your file, rather than program the authorization check?
Putting the document into your webpage is the easy part.
In order to embed a Google doc in your website, go to your Google Drive, open a document and choose File then Publish to Web, and you will be given an HTML iFrame Tag that can be embedded into you web page. You can change the height and width of the iFrame to match the document size. iFrame Instructions W3Schools
Downloading your document can be done very easily from the online version of a shared document just by choosing FILE and then DOWNLOAD AS from the menu.
To get up and running fast, just give the user a couple lines of instructions on how to download "Manually", then see if you can program the code.
Provide a link to your shared document instead of programming the button, and then work on the code.
Search Git Hub for Google Drive, you might find something there.
Some of the official Google code examples are way more complicated than you need, and will take a long time to figure out. The code examples in the documentation pages are simpler, but are almost never complete functioning code examples. You'll need to put lots of pieces of the puzzle together to make it work.

Categories

Resources