can load up the model due to the authentication - autodesk-forge

I just followed the startup tutorial to load up a model.
Firstly I have a exsiting client_id and client_secret from autodesk developer, and then built up a express based application with client_id and client_secret in order retrieve the access token such as
var config ={
credentials: {
client_id: 'xxxxxxxx',
client_secret: 'xxxxxxx',
grant_type: 'client_credentials',
scope:'data:read data:write data:create bucket:create bucket:read'
},
BaseEndPoint: 'https://developer.api.autodesk.com',
Version: 'v1'
} ;
config.AuthenticateEndPoint =config.BaseEndPoint + '/authentication/' + config.Version + '/authenticate' ;
unirest.post (config.AuthenticateEndPoint)
.header ('Accept', 'application/json')
.send (config.credentials)
.end (function (response) {
}
{"access_token":"ruTBP6POxlpcy8HK2KlWzoFu61oE","token_type":"Bearer","expires_in":86399}
This access token is then sent back to a simple html client.
<!DOCTYPE html>
<html>
<head>
<title>Very Basic 3D Viewer</title>
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=no" />
<meta charset="utf-8">
<script src="js/jquery-3.1.1.min.js" ></script>
<!-- The Viewer CSS -->
<link rel="stylesheet" href="https://developer.api.autodesk.com/viewingservice/v1/viewers/style.min.css" type="text/css">
<link rel="stylesheet" href="https://developer.api.autodesk.com/viewingservice/v1/viewers/A360.css" type="text/css">
</head>
<body>
<div id="viewer"></div>
<!-- The Viewer JS -->
<script src="https://developer.api.autodesk.com/viewingservice/v1/viewers/three.min.js?v=v1.2.22"></script>
<script src="https://developer.api.autodesk.com/viewingservice/v1/viewers/viewer3D.min.js?v=v1.2.22"></script>
<script src="https://developer.api.autodesk.com/viewingservice/v1/viewers/Autodesk360App.js"></script>
<!-- Developer JS -->
<script>
$(document).ready(function () {
var viewerApp;
var options = {
env: 'AutodeskProduction',
accessToken: 'YOUR ACCESS TOKEN'
};
var documentId = 'YOUR BASE 64 ENCODED URN';
$.getJSON( 'http://'+window.location.host+ "/gettoken", function( data ) {
console.log(data);
options.accessToken = data.accessToken;
documentId = data.urn;
options.document = data.urn;
});
console.log(options.accessToken, documentId);
Autodesk.Viewing.Initializer(options, function onInitialized(){
viewerApp = new Autodesk.A360ViewingApplication('viewer');
//viewerApp.registerViewer(viewerApp.k3D, Autodesk.Viewing.Private.GuiViewer3D);
//viewerApp.loadDocumentWithItemAndObject(documentId);
});
});
</script>
</body>
</html>
The problem occurred on the client-side, which can successfully get the access token. However this gave me a error
'POST https://developer.api.autodesk.com/utility/v1/settoken 401 (Unauthorized)'
Autodesk.Viewing.Initializer(options, function onInitialized(){
viewerApp = new Autodesk.A360ViewingApplication('viewer');
//viewerApp.registerViewer(viewerApp.k3D, Autodesk.Viewing.Private.GuiViewer3D);
//viewerApp.loadDocumentWithItemAndObject(documentId);
});
i can't figure out what is the problem, something wrong with api or client side or server side?
Note: on registering the developer api, i simply named callback as http://localhost:3000 because currently i am testing it on the local environment, is that the problem ?

The code here
var config ={
credentials: {
client_id: 'xxxxxxxx',
client_secret: 'xxxxxxx',
grant_type: 'client_credentials',
scope:'data:read data:write data:create bucket:create bucket:read'
},
BaseEndPoint: 'https://developer.api.autodesk.com',
Version: 'v1'
} ;
config.AuthenticateEndPoint =config.BaseEndPoint + '/authentication/' + config.Version + '/authenticate' ;
unirest.post (config.AuthenticateEndPoint)
.header ('Accept', 'application/json')
.send (config.credentials)
.end (function (response) {
}
is correct. You get a valid access token, and I assume you run this code from your node.js server. On your server you implement an endpoint, i.e /gettoken, which your client app will call to get the access token returned to your page which initialize the viewer. So far so good.
However, when you consider the calling sequence on your client, there is an issue.
$(document).ready(function () {
means that your code will execute when the DOM is ready - this is fine.
Here, you initialize your variables:
var options = {
env: 'AutodeskProduction',
accessToken: 'YOUR ACCESS TOKEN'
};
var documentId = 'YOUR BASE 64 ENCODED URN';
until here it is still ok, but note that both the accessToken and documentId have invalid valid.
Next, you query the access token using $.getJSON() which is an asynchronous way of calling an endpoint. That means this function returns immediatelly before you read the reply.
So the next code executed is not the one in the callback function, but this one:
console.log(options.accessToken, documentId);
Autodesk.Viewing.Initializer(options, function onInitialized(){
viewerApp = new Autodesk.A360ViewingApplication('viewer');
//viewerApp.registerViewer(viewerApp.k3D, Autodesk.Viewing.Private.GuiViewer3D);
//viewerApp.loadDocumentWithItemAndObject(documentId);
});
at this time, the accessToken and documentId still got invalid values, which will cause your code to fail. In short you need to initialize the Viewer from the callback to wait for the /gettoken response to come back.
$.getJSON( 'http://'+window.location.host+ "/gettoken", function( data ) {
console.log(data);
options.accessToken = data.accessToken;
documentId = data.urn;
options.document = data.urn;
Autodesk.Viewing.Initializer(options, function onInitialized(){
viewerApp = new Autodesk.A360ViewingApplication('viewer');
//viewerApp.registerViewer(viewerApp.k3D, Autodesk.Viewing.Private.GuiViewer3D);
//viewerApp.loadDocumentWithItemAndObject(documentId);
});
});

Related

How to retrieve data from AWS Lambda and display it on a static website that's hosted on AWS S3?

I'm attempting to use AWS DynamoDB, Lambda, API Gateway, and S3 to create a simple website. DDB has a table and in the table is a single entry. S3 has a simple file for a HTML for a website. The goal is to display the entry located in DDB in the website, if I update the value in DDB, then refreshing the website should change the number to reflect the update in DDB. At the moment, I have a lambda function which successfully retrieves the entry from DDB. I am stuck in trying to tell the HTML file to call the lambda function and get the data back (using API Gateway). I have never worked with AWS before, forgive me if this isn't even the right approach for this goal.
Below is code for lambda function:
'use-strict';
const AWS = require('aws-sdk');
const docClient = new AWS.DynamoDB.DocumentClient({region: 'us-location-x'});
exports.handler = (event, context, callback) => {
let tableToRead = {
TableName: 'dataStore',
Limit: 10
};
docClient.scan(tableToRead, function(err,data){
if(err){
callback(err,null);
} else {
callback(null,data);
}
});
};
And this is the HTML that's on S3:
<html>
<head>
</head>
<body>
<h1> This number that's in DDB </h1>
<div id="entries">
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script type="text/javascript">
//This is the link generated by API Gateway
var API_URL = 'https://xxxxxxxxxx.execute-api.us-location-x.amazonaws.com/prod/retrieveDDB';
$(document).ready(function(){
$.ajax({
type: 'GET',
url: API_URL,
success: function(data){
$('#entries').html('');
data.Items.forEach(function(tableItem){
$('#entries').append('<p>' + tableItem.Row + '</p>');
})
}
});
});
</script>
</body>
</html>
When I run the lambda function using the "test" button, it successfully retrieves the data from the DDB. But when I try to run the HTML, it does say the header text but then it doesn't append the value from DDB. I'm assuming I'm just not understanding how to call/parse the lambda data (If I even have it set up properly).
Thanks in advance for any help!
The cross-origin request blocked error occurs because you are trying to access the api from a different domain (for e.g www.example.com). This is a security feature of the browsers called CORS( cross origin resource sharing requests). The browser will send a pre-light request to the api to check whether the call should be allowed.
A prelight request is sent as http options request to the api method.
There are two steps.
You need to enable Cors to the API gateway, resource method. So that it will enable the Options method for the resource. In short, you need to select the particular resource and then click Enable Cors from the actions.
Reference: Please read "Enable CORS support on a REST API resource" section of https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors.html
You should return the origin header from your lambda.
const docClient = new AWS.DynamoDB.DocumentClient({ region: 'us-location-x' });
exports.handler = async (event) => {
let tableToRead = {
TableName: 'dataStore',
Limit: 10
};
const headers = {
"Access-Control-Allow-Origin": '*'
// other headers
}
try {
const data = docClient.scan(tableToRead).promise();
return {
statusCode: 200,
body: JSON.stringify(data),
headers: headers
}
} catch (error) {
return {
statusCode: 400,
body: error.message,
headers: headers
}
}
};
Hope this helps. #Ashish Modi, thanks for sharing the link.

In the Microsoft Bot Framework, how can I extract parameters from the url of the chat?

I wrote an html page where a user signs in (the data file is in json) and I can save his/her first name and gender. I pass them as parameters in the request's url where the bot lives.
var xhr = new XMLHttpRequest();
function processRequest(e) {
var url;
if (xhr.readyState == 4 && xhr.status == 200) {
var response = JSON.parse(xhr.responseText);
url = "https://webchat.botframework.com/embed/nodejsbot98?firstname="+firstname+"&gender="+gender+"&t="+response;
document.getElementById("chat").src= url;
}
}
Now in the app.js, I want the bot to greet that user with the first name and based on the gender, the bot is a male or female. How does the url call the app.js to send and receive messages? How can I access those parameters from the url?
EDIT: Using the backchannel, is that script correct?
<!DOCTYPE html>
<html>
<head>
<link href="https://cdn.botframework.com/botframework-webchat/latest/botchat.css" rel="stylesheet" />
<script src="https://cdn.botframework.com/botframework-webchat/latest/botchat.js"></script>
</head>
<body>
<div id="bot"/>
<script>
var botConnection = new BotChat.DirectLine({
secret: 'TGDGNQY7JK0.cwA.XiQ.I1LDLE5qI3Jsx6q7dlnMMrJtEoLcbTdOE-QIZ4AA_1Y',
});
var user = {
id: 'userid',
name: 'username'
};
var bot = {
id: 'botid',
name: 'botname'
};
BotChat.App({
botConnection: botConnection,
user: user,
bot: bot,
}, document.getElementById("bot"));
botConnection
.postActivity({type: "event", value: "", from: {id: "me" }, name: "greeting", data:{firstname:'Alain', gender:'male'}})
.subscribe(id => console.log("success"));
</script>
</body>
</html>
For your requirement, it's better to leverage The Backchannel feature of botframework-webchat library, as the Bot service's embed web chat is difficult to pass values from url.
Leveraging the Web chat js library, you can set the value like:
botConnection .postActivity({ type: "event", from: user, name: "customeEvt", data:{fitstname:'Gary',gender:'Male'} }) .subscribe(activity => console.log(activity));
And in bot application, you can retrieve the variables via event triggers:
bot.on('event',(event) => {
if (event.name === 'customeEvt') {
console.log(event)// use the data as **event.data** as you set the variable as 'data'
bot.beginDialog(event.address, '<any dialog>', event.data);//pass your value to dialog
}
})

invoke node.js server-side service in angularjs. getting following error. Error: [$injector:nomod] Module ‘angularjsNodejsTutorial’ is not available

This is the error: Error: [$injector:modulerr] Failed to instantiate module angularjsNodejsTutorial due to:
Error: [$injector:nomod] Module ‘angularjsNodejsTutorial’ is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.” exception. from browser or postman when I hit localhost:3000/dirPath then I get the data back but not through this html file.
//here are the files: index.html, app.js(angularjs) and index.js(node)
//index.html
<!DOCTYPE html>
<html ng-app="angularjsNodejsTutorial">
<head>
<title>Integrating AngularJS with NodeJS</title>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.2/angular.js"></script>
<script src="../node_modules/angular-route/angular-route.min.js"></script>
</head>
<body >
<div ng-controller="myController">
<ul >
<li> The Files Are: {{data}}</li>
</ul>
</div>
<script src="../public/javascripts/app.js" type="text/javascript"></script>
<script src="../node_modules/angular-route/angular-route.js"></script>
</body>
</html>
//(AngularJS Client-Side)app.js
var app = angular.module('angularjsNodejsTutorial',['ngRoute']);
app.controller('myController', function($scope, $http) {
$scope.data = [];
var request = $http.get('/dirPath');
request.success(function(data) {
console.print("The files from this directory are:", data);
$scope.data = data;
});
request.error(function(data){
console.log('Error: ' + data);
});
});
//Server-side node.js index.js file
var express = require('express');
var router = express.Router();
var path = require('path');
/* GET home page. */
router.get('/', function(req, res, next) {
res.sendFile(path.join(__dirname, '../', 'views', 'index.html'));
});
router.get("/dirPath", function(req, res) {
var fs = require("fs");
var dir = '/Users/swapnil/Documents/Test';
fileList = [];
var files = fs.readdirSync(dir);
for(var i in files){
if (!files.hasOwnProperty(i)) continue;
var name = dir+'/'+files[i];
if (!fs.statSync(name).isDirectory()){
fileList.push(name);
}
}
return res.send(fileList);
});
module.exports = router;
I think you are over thinking your route process, this will do the basics:
function config ($routeProvider, _) {
$routeProvider.
when('/Order', {
templateUrl: '../modern/sections/views/view.html',
controller: 'Controller as ctrl',
caseInsensitiveMatch: true,
resolve: {
data: function(Factory){
var view = window.location.href.match(/OrderID=(.*)#/) || 'undefined';
if(Id === 'undefined'){
return Factory.createOrder();
}else{
return Factory.currentOrder(OrderId[1]);
}
}
}
})
.otherwise({
redirectTo: '/'
});
}
FYI: Resolve calls Factories where i have services setup to get my API data.
Sorry if this is not direct, i copied this over from a current working project i have.
Resolved the issue by exposing the server side functionality as a RESTful API instead of node and modified my controller by adding appropriate header info for content type and implemented CORS filter on the server side.
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
response.addHeader("Access-Control-Allow-Origin", "*");
// CORS "pre-flight" request
response.addHeader("Access-Control-Allow-Methods",
"GET, POST, PUT, DELETE");
response.addHeader("Access-Control-Allow-Headers",
"X-Requested-With,Origin,Content-Type, Accept");
filterChain.doFilter(request, response);
}
Thanks everyone for taking time to look at my issue and offering help. Appreciate.
Check your modules and make sure they are being loaded appropriately. It's a very common error when you start out. Check your html file and make sure all the modules names are spelled correctly.
If your modules are sharing logic it's common to accidentally miss spell the module name. This case I normally copy and past it over.
Also look at your logic behind the module and make sure you are declaring it properly.

Need Help Reading JSON object from a URL in a HTML

I am trying to create a website in where I can get a particular json object from a url and then display it on the website. The field that I am trying to display is UV_INDEX out of three fields. Nothing is being printed out. I don't even know if it is getting the json object.
<!DOCTYPE html>
<html>
<body>
<h2>EPA </h2>
<p id="demo"></p>
<script>
var getJSON = function(url) {
return new Promise(function(resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open('get', url, true);
xhr.responseType = 'json';
xhr.onload = function() {
var status = xhr.status;
if (status == 200) {
resolve(xhr.response);
} else {
reject(status);
}
};
xhr.send();
});
};
getJSON('http://iaspub.epa.gov/enviro/efservice/getEnvirofactsUVDAILY/ZIP/92507/JSON').then(function(data) {
document.getElementById('UV_INDEX').innerHtml=json.result;
alert('Your Json result is: ' + json.result); //you can comment this, i used it to debug
result.innerText = data.result; //display the result in an HTML element
}, function(status) { //error detection....
alert('Something went wrong.');
});
</script>
</body>
</html>
I added a third-party chrome extenstion for CORS issue. But I get this error
Uncaught (in promise) ReferenceError: json is not definedmessage: "json is not defined"stack: (...)get stack: function () { [native code] }set stack: function () { [native code] }__proto__: Error
You can try using a Ajax plugin to make CORS request where the CORS headers are not being served from service.
Add Jquery library and add your installed CORS ajax scripts after that:
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript" src="js/jquery.ajax-cross-origin.min.js"></script>
Now you can make cross origin request by just adding crossOrigin: true in your Ajax:
E.g.
$.ajax({
crossOrigin: true,
url: "http://iaspub.epa.gov/enviro/efservice/getEnvirofactsUVDAILY/ZIP/92507/JSON/",
success: function(data) {
console.log(data);
}
});
You can try putting the same URL in the below demo page to receive the Json data.
See live demo.

SAPUI5 - Login Page

I'm building an app that communicates with an IBM software through REST.
The thing is that I have a POST Method in the NewTicket.controller, but I need to use the user and password on this method to open the ticket.
How can I send the variables (or other thing) that I have on my Login.controller to the NewTicket.controller?
This is my Post Method:
enviar:function() {
var description = this.byId("desc").getValue(); //Recebe o resumo
var long_description = this.byId("long_desc").getValue(); //Recebe a descrição
jQuery.sap.require("sap.m.MessageToast");
sap.m.MessageToast.show(user);
jQuery.sap.require("sap.m.MessageBox");
// open a fully configured message box
sap.m.MessageBox.show("Confirmar a abertura do chamado?",
sap.m.MessageBox.Icon.QUESTION,
"Confirmar",
[sap.m.MessageBox.Action.YES, sap.m.MessageBox.Action.NO],
function(sResult) {
if(sResult == sap.m.MessageBox.Action.YES) //Se clicar em SIM (popup com numero do chamado e tela com lista)
{
var oModel = new sap.ui.model.json.JSONModel();
var url = "http://xxx.xxx.xxx.xx:xxxx/maxrest/rest/mbo/sr/?_lid=" + **user** + "&_lpwd=" + **password** +"&description="+ description +"&description_longdescription=" + long_description + "&_format=json&_compact=true&_verbose=true";
var aData = jQuery.ajax({
type : "POST",
contentType : "application/json",
url : url,
dataType : "json",
async: false,
success : function(data,textStatus, jqXHR) {
oModel.setData({modelData : data});
sap.m.MessageBox.show("ABRIU");
},
error : function(data,textStatus, jqXHR) {
oModel.setData({modelData : data});
sap.m.MessageBox.show(textStatus);
}
})}
else // Se clicar em NÃO
{
}
},
sap.m.MessageBox.Action.YES);
Thank you in advance.
index.html
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta http-equiv='Content-Type' content='text/html;charset=UTF-8'/>
<script src="resources/sap-ui-core.js"
id="sap-ui-bootstrap"
data-sap-ui-libs="sap.m"
data-sap-ui-theme="sap_bluecrystal">
</script>
<script>
sap.ui.localResources("app");
var app = new sap.m.App({initialPage:"idinitial1"});
var page = sap.ui.view({id:"loginPage", viewName:"app.login", type:sap.ui.core.mvc.ViewType.XML});
app.addPage(page);
app.placeAt("content");
</script>
</head>
<body class="sapUiBody" role="application">
<div id="content"></div>
</body>
</html>
login.view.xml
<core:View xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m"
controllerName="app.login" xmlns:html="http://www.w3.org/1999/xhtml">
<Page title="Title">
<content>
<Panel headerText = "example" expandable = "true" expanded = "true">
<content>
<Input id="userID" value="User123"/>
<Button text="Login" press="btnClicked"/>
</content>
</Panel>
</content>
</Page>
</core:View>
login.controller.js
sap.ui.controller("app.login", {
btnClicked: function(){
this.userName = this.byId('userID').getValue();
//loading the second view but not placed anywhere, just for showing code usage
sap.ui.view({id:"myTickePage", viewName:"app.ticket", type:sap.ui.core.mvc.ViewType.JS});
}
});
ticket.view.xml can be anything but inside ticket.controller.js:
onInit: function() {
var user = sap.ui.getCore().byId('loginPage').getController().userName;
console.log(user);
},
Output:
Define a variable under the controller scope of Login.controller.
Eg: In Login.controller have a variable this.myValue
In MyTicket.controller:
sap.ui.getCore().byId('loginViewID').getController().myValue
This will work as long as your login view/controller are not destroyed.
Suppose two views:
login view corresponding to Login.controller (viewid_login)
ticket view corresponding to NewTicket.controller (viewid_ticket)
In Login.controller:
onInit: function() {
this.userName= "User123";
},
In NewTicket.controller:
onInit: function() {
var user = sap.ui.getCore().byId('viewid_login').getController().userName;
//this will return "User123"
},
Hope this makes it clear.
Note that your login view should not be destroyed.
Depends where you are storing the user and password. The correct way would be to actually store them in the model. Initialize the model on the onInit and then get them when you need them.
onInit: function() {
..
var data = {user: 'bla', password: 'ble'};
var oModel = new sap.ui.model.json.JSONModel();
oModel.setData(data);
sap.ui.getCore().setModel(oModel);
..
}
then on the view you can get the values with:
var oModel = sap.ui.getCore().getModel();
var data = oModel.getData();
//data.password
//data.user