Alexa intent is not waiting for the api response - javascript

We are developing alexa skill using alexa-app, in one of our intent we are trying to fetch albums from facebook and on success/failure we want alexa to respond accordingly. But intent is not waiting for FB call to complete. Below is the code snippet we are using:
function fetchAlbums(){
return new Promise(resolve =>{
FB.api("/me/albums", function (res) {
if (res && !res.error) {
// If we have data
if (res.data) {
resolve("Got Albums");
} else {
// REPORT PROBLEM WITH PARSING DATA
resolve("Error getting albums");
}
} else {
// Handle errors here.
resolve("Error hitting endpoint");
}
});
});
}
alexaApp.intent("readFeedIntent", {
"utterances": [
"read my facebook feed", "read facebook feed", "read feed"
]
},
function(request, res1) {
// Again check if we have an access token
if(request.hasSession() && !accessToken){
accessToken = request.data.session.user.accessToken;
FB.setAccessToken(accessToken);
}
if (accessToken) {
var session = request.getSession();
fetchAlbums().then(function(data){
console.log(data);
res1.say(data);
});
} else {
res1.say(noAccessToken, tryLaterText).send();
}
});
It is not throwing any errors, but Alexa is not speaking the anything where I can see the response in the console logs.
If I add: res1.say("Whatever!") at the end of function, then Alexa will speak 'Whatever' in response to this intent.

Got it solved my myself:
instead of this:
fetchAlbums().then(function(data){
console.log(data);
res1.say(data);
})
you have to return it, like:
return fetchAlbums().then(function(data){
console.log(data);
res1.say(data);
})

Related

Why does this javascript code not redirect the user after the metamask transaction?

I want to make a javascript code that does a metamask transaction and redirects the user to another page after the transation is completed. How easy this may sound, I can not figure it out.
My current code lets the user complete the transaction, but it does not redirect the user to another page. Instead, it gives this error: "MetaMask - RPC Error: invalid argument 0: json: cannot unmarshal non-string into Go value of type common.Hash"
I have looked it up, but I could not find any possible fix for my problem.
This is my code:
try {
// send the transaction
ethereum.send({
method: 'eth_sendTransaction',
params: [
{
to: contractAddress,
from: userAddress,
value: amt
},
],
}, (error, transactionHash) => {
if (error) {
console.error(error);
} else {
// check the status of the transaction using the transaction hash
ethereum.request({
method: 'eth_getTransactionReceipt',
params: [transactionHash],
}).then((receipt) => {
// check if the transaction was successful
if (receipt.status === '0x1') {
console.log(`Transaction was successful`);
// redirect to another page
window.location.href = "page.php";
} else {
console.log(`Transaction failed`);
}
}).catch((error) => {
// This is the line of code the error is assigned to:
console.error(error);
});
}
});
} catch (error) {
console.error(error);
}
});
} else {
document.getElementById("bericht").innerHTML = "Install Metamask before you continue";
return;
}
I have tried looking the error up on internet, but nothing significant showed up. Could anyone help? Thank you in advance!

Firebase response depending on Firestore Query does not work

Depending on whether there is an entry in Cloud Firestore with the correct DocumentId. However, this does not work because my function sends the status 200 before even finishing the query. So how can I get that working?
Here is my code:
access = false;
admin.firebase().collection("tuere").doc(door).collection("eintritt").get().then((snapshot) => {
snapshot.forEach((doc) => {
if(doc.id === uid){
access = true;
console.log("May open door " + uid);
}
});
}).catch((err) => {
console.log(err);
});
res.status(200).send(access);
When I open the Tab in Chrome and let it load "false" appears, but when I wait like 15 Seconds "May open door (uid)" appears in the Logs.
How can I solve this problem and how can i get my function to run faster?
You should send the HTTP response when the promise resolves, so within the then of the query promise: like that:
access = false;
admin.firebase().collection("tuere").doc(door).collection("eintritt").get()
.then((snapshot) => {
snapshot.forEach((doc) => {
if(doc.id === uid){
access = true;
console.log("May open door " + uid);
}
});
res.status(200).send(access);
}).catch((err) => {
console.log(err);
res.status(500).send(err);
});
Also, you should send an HTTP response in case of error, this is why I added res.status(500).send(err); in the catch
I would suggest you look this video from Doug Stevenson: https://www.youtube.com/watch?v=7IkUgCLr5oA
Also there is a point which surprises me: shouln't you use
admin.firestore().collection("tuere").doc(door)....
instead of
admin.firebase().collection("tuere").doc(door)
I have to look in the reference, but I have the feeling that admin.firebase() does not exist.

What would be necessary to code the callback function to receive the access token?

I am trying to retrieve the access token from an API (https://github.com/Axosoft/node-axosoft/)
To receive an access token we have to follow this process:
var axo = nodeAxosoft(axosoftUrl, credentials);
axo.Api.getLoginUrl(function(url) {
// open browser using authorizationUrl and get code parameter from
//redirected Url after login
var code = 'code received from redirect';
axo.Api.exchangeCodeForToken(code);
});
As I did not understood exactly how to get the code following that example nor what is the url parameter on getLoginUrl, I did it on my own.
I have a login route that redirects the user to the axosoft website for authentication and redirects the user to the /authorization-process route on my application.
On the /authorization-process I get the code returned by the login and call a function that should get the access token by calling:
axo.Api.exchangeCodeForToken(code);
Code:
var axosoft_code = req.query.code;
console.log(axosoft_code);
var token = request.exchangeAuthCodeForAccessToken(axosoft_code)
.then(function(token)
{
res.send(token);
})
The Method:
var connection = nodeAxosoft(client_url, credentials);
return new Promise(function(resolve, reject){
console.log("CODE: ", axosoft_code)
var token = connection.Api.exchangeCodeForToken(axosoft_code, function(token){
console.log(token);
resolve(token)
})
The problem is that returns null
I had a look at the API lib api.js and found that:
https://github.com/Axosoft/node-axosoft/blob/master/lib/api.js
function exchangeCodeForToken(code, callback) {
_credentials.code = code;
_access_token = '';
_authenticateCredentails(function (err) {
if (!err) {
callback(null, _access_token);
} else {
callback(err);
}
})
}
So I have two questions:
Does anyone has an Idea what am I doing wrong?
What would be necessary to code the callback function?
The method expects a callback function but I don't really know how to do it.
EDIT:
return new Promise(function(resolve, reject){
var token = connection.Api.exchangeCodeForToken(axosoft_code, function(response,err){
if(!err){
console.log("token",response)
resolve(token);
}
else{
console.log("error",err)
resolve(token);
}
});
})
OR
var token = connection.Api.exchangeCodeForToken(axosoft_code, function(response,err){
if(!err){
console.log("token",response.body)
return response.body;
}
else{
console.log("error",err)
return err;
}
});
I am giving to my callback function two args (response and err), my problem is that I am falling at the else condition.
The output of err is something similar to a token though the documentation here shows that it should be like that:
{
"error" : "invalid_request",
"error_description" : "One or more parameters are missing: client_secret"
}
Another point is that the page is frozen waiting for something to happen but nothing happens.
Given that this is the input:
function exchangeCodeForToken(code, callback) {
_credentials.code = code;
_access_token = '';
_authenticateCredentails(function (err) {
if (!err) {
callback(null, _access_token);
} else {
callback(err);
}
})
}
You should format your call as:
exchangeCodeForToken(axosoft_code, function(err, response) {
if (err) {
// Deal with error
} else {
// Deal with response
}
}
Node functions often pass through error variables first so that you have to receive them, which is considered good practice.

MobileServices.web.js unauthorized api call

When I leave my WinJS app dormant for a while and then come back to it, and i click on a button, for some reason my calls to my backend aren't working.
I get an "Unauthorized" error from the server.
How do I modify the invokeApi so that it reauthenticates the user or something?
Does anybody have any experience using mobileservices.web.js and how to keep the end user perpetually logged in without having to reauthenticate themselves?
Thankyou.
client.invokeApi("getTopForumsTotal", {
method: "post"
}).then(function (results) {
// do something
}, function (error) {
WinJS.log(error);
});
I use winjs mobileService to authenticate the user.
client.login("microsoftaccount").done(function (results) {
// Create a credential for the returned user.
credential = new Windows.Security.Credentials.PasswordCredential("myapp", results.userId, results.mobileServiceAuthenticationToken);
vault.add(credential);
completeDispatcher();
}, function (error) {
WinJS.log(JSON.stringify(error));
errorDispatcher(error);
});
and this is what I use to refresh the end users token.
client._request("GET", "/.auth/refresh", null, null, {
accept: "application/json",
"ZUMO-API-VERSION": "2.0.0"
}, [], (error, response) => {
if (!error) {
var userObject = JSON.parse(response.responseText)
if (userObject.authenticationToken) {
client.currentUser.mobileServiceAuthenticationToken = userObject.authenticationToken;
testCall().done(function (success) {
if (success) {
credential = new Windows.Security.Credentials.PasswordCredential("myapp", userObject.user.userId, userObject.authenticationToken);
vault.add(credential);
authenticated = true;
completeDispatcher();
}
else errorDispatcher('testCall API does not exist');
});
}
else errorDispatcher('no authentication token returned');
}
else errorDispatcher(error);
});
Instead of wrapping a promise around every API call I just incorporated an idle routine on the client that refreshes the user token when they return to the app as well as refreshes the token every 59 seconds that they are idle.
So for all intense and purposes they will always have an valid token or perpetual state.
$(document).idle({
onIdle: function () {
// refresh user token
if (User.Person !== null)
User.Person.reauthenticate().done();
},
onActive: function () {
// when the user returns refresh their token 1 more time
if (User.Person !== null)
User.Person.reauthenticate().done();
},
idle: 59000, // 59 seconds
recurIdleCall: true // will keep refreshing every 59 seconds
});
https://github.com/kidh0/jquery.idle

How to preserve user logged in using Parse JS and Facebook SDK

I'm using Parse Server + Parse JS Sdk to handle user login through Facebook. Everything works fine until I refresh web browser. What data should I store after login process is done? I belive that FB AccessToken is important to keep Facebook Session, but what about Parse Session.
Current code:
login: function (callback) {
console.log('loggin in...')
Parse.FacebookUtils.logIn('user_likes,email', {
success: function (parseUser) {
if (!parseUser.existed()) {
console.log('signed up and logged in!')
} else {
console.log('logged in!')
}
console.log('parse user is: ', parseUser.id)
if (callback) { callback() }
},
error: function (parseUser, error) {
console.log('login cancelled: ', error.message)
}
})
}
You don't need to manually store anything. You can use the parse function:
Parse.User.current()
To see if there is already a user logged-in.
We made this function:
function userAuthenticated(){
if(Parse.User.current() === null){
return false;
}
if(Parse.User.current().authenticated()){
return true;
}
else{
return false
}
}

Categories

Resources