actions-on-google Account Linking Signin status is "ERROR" always - node.js

I got this sample code from the docs of actions on google account linking with google account. The signin.status is always "ERROR". I have tried on actions console simulator, google assistant app on my phone and on a google home mini with personal results on. But the result is the same in all cases.
const express = require('express');
const bodyParser = require('body-parser');
const {actionssdk, SignIn} = require('actions-on-google');
const app = actionssdk({
// REPLACE THE PLACEHOLDER WITH THE CLIENT_ID OF YOUR ACTIONS PROJECT
clientId: <client_id>,
});
// Intent that starts the account linking flow.
app.intent('actions.intent.MAIN', (conv) => {
conv.ask(new SignIn('To get your account details'));
});
// Create an Actions SDK intent with the `actions_intent_SIGN_IN` event.
app.intent('actions.intent.SIGN_IN', (conv, params, signin) => {
console.log(signin)
if (signin.status === 'OK') {
const payload = conv.user.profile.payload;
conv.ask(`I got your account details, ${payload.name}. What do you want to do next?`);
} else {
conv.ask(`I won't be able to save your data, but what do you want to do next?`);
}
});
app.intent('actions.intent.TEXT', (conv) => {
conv.close("bye");
})
//Run server
const expressApp = express().use(bodyParser.json());
expressApp.post('/', function(req,res){
app(req,res);
});
expressApp.listen(8080,() => {console.log("listening")});
This is the signin object I'm being returned
{ '#type': 'type.googleapis.com/google.actions.v2.SignInValue',
status: 'ERROR' }
EDIT
My actions.json is as follows
{
"actions": [
{
"description": "Default Welcome Intent",
"name": "MAIN",
"fulfillment": {
"conversationName": "fulfilment function"
},
"intent": {
"name": "actions.intent.MAIN",
"trigger": {
"queryPatterns": [
"talk to Care Cat"
]
}
}
},
{
"description": "Everything Else Intent",
"name": "allElse",
"fulfillment": {
"conversationName": "fulfilment function"
},
"intent": {
"name": "actions.intent.TEXT"
}
}
],
"conversations": {
"fulfilment function": {
"name": "fulfilment function",
"url": <url>
}
},
"locale": "en"
}
Could it be because it is still a test app which is not published yet?
Can someone help me with this?

In your Google Cloud Platform Account, check your IAM settings and enable the Dialogflow API Admin
Documentation for more details: https://cloud.google.com/dialogflow/docs/access-control

Related

Azure Static Web App Role Functions Not Working

I've made an attempt to get Azure Static Web Apps with customized Roles function to work in my environment just as specified by: https://learn.microsoft.com/en-us/azure/static-web-apps/assign-roles-microsoft-graph
Everything seems to work as expected but when visiting the page restricted by a specific role the API doesn't seem to be assigning the expected role.
I've modified the API and removed all the logic to assign a role to everyone logging in and still doesn't work. Here's the modified code:
const fetch = require('node-fetch').default;
module.exports = async function (context, req) {
const user = req.body || {};
const roles = [];
roles.push('superuser');
context.res.json({
roles
});
}
Here's my staticwebapp.config.json file:
{
"auth": {
"rolesSource": "/api/GetRoles",
"identityProviders": {
"azureActiveDirectory": {
"userDetailsClaim": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name",
"registration": {
"openIdIssuer": "https://login.microsoftonline.com/44263d43-a2f0-45a8-8f55-9b100ecfb4dc",
"clientIdSettingName": "AAD_CLIENT_ID",
"clientSecretSettingName": "AAD_CLIENT_SECRET"
},
"login": {
"loginParameters": ["resource=https://graph.microsoft.com"]
}
}
}
},
"routes": [
{
"route": "/secured/*",
"allowedRoles": ["superuser"]
},
{
"route": "/admin/*",
"allowedRoles": ["administrator"]
},
{
"route": "/contributors/*",
"allowedRoles": ["contributor", "Contributor"]
}
],
"responseOverrides": {
"401": {
"redirect": "/.auth/login/aad?post_login_redirect_uri=.referrer",
"statusCode": 302
}
}
}
I've tried changing the order of the config file. My last attempt before posting was to remove all logic and just assign everyone the 'superuser' role.
Everyone can login successfully & pre-defined roles work like a charm but no one ever gets the 'superuser' role.
I'm trying to figure out what I'm doing wrong or has Azure Static Web Apps changed so that this code just won't work like it did a year ago?
Thank you help in advance.

Rich response fulfillment Dialogflow Messenger

I'm using Dialogflow Messenger integration. Custom Payloads are working from the Dialogflow platform, but I don't know how to use them from Webhook.
Here is my JavaScript code that doesn't works:
const functions = require('firebase-functions');
const { dialogflow } = require('actions-on-google');
const { Card, Suggestion } = require('dialogflow-fulfillment');
const { WebhookClient } = require('dialogflow-fulfillment');
const app = dialogflow();
const response = {
"fulfillment_messages": [{
"payload": {
"richContent": [
[{
"type": "chips",
"options": [{
"text": "Empezar!"
}]
}]
]
}
}]
}
const numero = (conv) => {
conv.ask(response);
};
app.intent("numero", numero);
exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);
The intent is detected correctly but the code for the rich response is not working, the chatbot response is: 'Cannot display response in Dialogflow simulator. Please test on the Google Assistant simulator instead.'.
I want to know how to use all possible custom payloads (Info response, Description response, Button response...).
Your JSON response in the webhook should be-
const response = {
"fulfillment_messages": [{
"payload": {
"richContent": [
[{
"type": "chips",
"options": [{
"text": "Empezar!"
}]
}]
]
}
}]
}
Your response on dialogflow messenger would look like
Here is another stackoverflow post that might help-
How to show Rich Response Buttons (''Chips) Using Dialogflow Fulfillment?

Why does this fulfillment code for Dialogflow does not work?

I am playing around a bit with the Dialogflow. As I was trying to figure out the options in the responses, I also wanted to test if Dialogflow has dynamic response. For example, fetch a data from Database (Firebase Database or MongoDB) and show it as a response instead of hard coding every response.
I have learnt that Fulfillment can do that job. When I enabled the Inline editor in Fulfillment in Dialogflow, it already has some code to be deployed. I figured, just for testing, I would write some very basic function in Fulfillment and see if it works.
// See https://github.com/dialogflow/dialogflow-fulfillment-nodejs
// for Dialogflow fulfillment library docs, samples, and to report issues
'use strict';
const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card, Suggestion} = require('dialogflow-fulfillment');
process.env.DEBUG = 'dialogflow:debug'; // enables lib debugging statements
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
const agent = new WebhookClient({ request, response });
console.log('Dialogflow Request headers: ' + JSON.stringify(request.headers));
console.log('Dialogflow Request body: ' + JSON.stringify(request.body));
function welcome(agent) {
agent.add(`Welcome to my agent!`);
}
function fallback(agent) {
agent.add(`I didn't understand`);
agent.add(`I'm sorry, can you try again?`);
}
function test(agent){
agent.add('test confirmed!');
}
// // Uncomment and edit to make your own intent handler
// // uncomment `intentMap.set('your intent name here', yourFunctionHandler);`
// // below to get this function to be run when a Dialogflow intent is matched
// function yourFunctionHandler(agent) {
// agent.add(`This message is from Dialogflow's Cloud Functions for Firebase editor!`);
// agent.add(new Card({
// title: `Title: this is a card title`,
// imageUrl: 'https://developers.google.com/actions/images/badges/XPM_BADGING_GoogleAssistant_VER.png',
// text: `This is the body text of a card. You can even use line\n breaks and emoji! 💁`,
// buttonText: 'This is a button',
// buttonUrl: 'https://assistant.google.com/'
// })
// );
// agent.add(new Suggestion(`Quick Reply`));
// agent.add(new Suggestion(`Suggestion`));
// agent.setContext({ name: 'weather', lifespan: 2, parameters: { city: 'Rome' }});
// }
// // Uncomment and edit to make your own Google Assistant intent handler
// // uncomment `intentMap.set('your intent name here', googleAssistantHandler);`
// // below to get this function to be run when a Dialogflow intent is matched
// function googleAssistantHandler(agent) {
// let conv = agent.conv(); // Get Actions on Google library conv instance
// conv.ask('Hello from the Actions on Google client library!') // Use Actions on Google library
// agent.add(conv); // Add Actions on Google library responses to your agent's response
// }
// // See https://github.com/dialogflow/dialogflow-fulfillment-nodejs/tree/master/samples/actions-on-google
// // for a complete Dialogflow fulfillment library Actions on Google client library v2 integration sample
// Run the proper function handler based on the matched Dialogflow intent name
let intentMap = new Map();
intentMap.set('Default Welcome Intent', welcome);
intentMap.set('Default Fallback Intent', fallback);
intentMap.set('test-intent',test);
// intentMap.set('your intent name here', yourFunctionHandler);
// intentMap.set('your intent name here', googleAssistantHandler);
agent.handleRequest(intentMap);
});
The function test is the only thing I have added to the already pre existing code along with the intentMap.set('test-intent', test);.
I have the intent as follows:
{
"id": "3fea3cec-d3f0-4d4e-a838-b4134894ea05",
"name": "test-intent",
"auto": true,
"contexts": [],
"responses": [
{
"resetContexts": false,
"affectedContexts": [],
"parameters": [
{
"id": "de3d79b3-b062-445a-8c55-d499a2d7b12d",
"required": false,
"dataType": "",
"name": "sample",
"value": "1",
"promptMessages": [],
"noMatchPromptMessages": [],
"noInputPromptMessages": [],
"outputDialogContexts": [],
"isList": false
}
],
"messages": [
{
"type": "simple_response",
"platform": "google",
"textToSpeech": "t",
"ssml": "",
"displayText": ""
}
],
"defaultResponsePlatforms": {},
"speech": []
}
],
"priority": 500000,
"webhookUsed": false,
"webhookForSlotFilling": false,
"fallbackIntent": false,
"events": [],
"userSays": [
{
"id": "d8aee895-8326-4454-b0f4-c2237984d968",
"data": [
{
"text": "testing...",
"userDefined": false
}
],
"isTemplate": false,
"count": 0,
"updated": 0,
"isAuto": false
}
],
"followUpIntents": [],
"liveAgentHandoff": false,
"endInteraction": false,
"templates": []
}
It is bare bones with nothingness. I just wanted to test the response in Actions on Google.
I only get the response I have manually entered in the 'testing-intent' in Actions on Google..
What am I doing wrong?
I already figured out the problem I have when I looked at the testing-intent's json before posting this question. I had to Enable webhook call for this intent.
Go to bottom portion of the selected intent page you want to enable Fulfillment.
Click Fulfillment to expand it.
Click Enable webhook call for this intent

How to connect watson assisstant v2 with Amazon skill kit in Aws Lambda?

Hello I want to connect my watson assisstant with an alexa device,
for this I need Amazon development skill kit and AWS lambda. But i can't connect watson because i got problem with my promises and i can't see the logs of my code in the amazon developer console. And my assistant work on nodeJs application.
There is the headers of my watson :
const assistant = new AssistantV2({
version: '2019-02-28',
iam_apikey: 'apiSecretKey',
url: 'https://gateway-lon.watsonplatform.net/assistant/api'
});
const assistant_id = "assistantIDSecret" ;
There is some codes that i tried :
const MyNameIsIntentHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'IntentRequest'
&& handlerInput.requestEnvelope.request.intent.name === 'SearchIntent';
},
async handle(handlerInput) {
assistant.createSession({
assistant_id: assistant_id
})
.then(res => {
session_id = res.session_id;
})
.catch(err => {
console.log(err);
});
assistant.message({
assistant_id: assistant_id,
session_id: session_id,
input: {
'message_type': 'text',
'text': "hello"
}
})
.then(res => {
console.log(JSON.stringify(res, null, 2));
speechText = res.output.generic.response.text;
})
.catch(err => {
speechText = err;
});
}, function(err){
speechText = "Problem with Api call";
});
return handlerInput.responseBuilder
.speak(speechText)
.getResponse();
},
};
I tried to replace then, catch by an await:
try{
let res = await assistant.createSession({
assistant_id: assistant_id
});
session_id = res.session_id;
let message = await assistant.message({
assistant_id: assistant_id,
session_id: session_id,
input: {
'message_type': 'text',
'text': "hello"
}
});
speechText = message.output.generic.response.text;
}catch(err){
speechText = err;
}
The results of speechText should give me "Good day to you" it's a response that comes from Watson.but now Alexa says "Sorry, I can't understand the command. Please say again."
Do you have an others ways to try this? thanks you!
Sounds like you have managed to call out to Watson Assistant, and if the response configured in your dialog node was "Good day to you" -which is what you have received, then that connection is working. If I remember right however the response that Alexa is expecting is a JSON object, not a string. So you need to format the response to meet Alexa's needs.
A quick look at this site: https://developer.amazon.com/docs/custom-skills/request-and-response-json-reference.html
indicates that the following is a good example the required response json packet.
{
"version": "string",
"sessionAttributes": {
"key": "value"
},
"response": {
"outputSpeech": {
"type": "PlainText",
"text": "Plain text string to speak",
"playBehavior": "REPLACE_ENQUEUED"
},
"reprompt": {
"outputSpeech": {
"type": "PlainText",
"text": "Plain text string to speak",
"playBehavior": "REPLACE_ENQUEUED"
}
},
"shouldEndSession": true
}
}
Note. I cannot confirm as I have never had an Alexa Skill taken to production ( only built them as demo's under the development environment, and shared with a limited few). But I have been informed that Amazon are not happy for their skills to off load work to Watson. Which is a shame.

Paypal single payout: TRANSACTION_LIMIT_EXCEEDED API Error

I'm trying to make a singe payout with the REST API of PayPal with Node.js and get this error:
//...
"errors": {
"name": "TRANSACTION_LIMIT_EXCEEDED",
"message": "Either the sender or receiver exceeded the transaction limit",
}
//...
What I do:
I use this example Code:
var paypal = require('paypal-rest-sdk');
module.exports = {
payMe: function (req, res,next) {
var mail = req.param('mail'); //this email comes from the paypal sandbox
paypal.configure({
'mode': 'sandbox',
'client_id': 'mycliendID',
'client_secret': 'myClientSecret'
});
var sender_batch_id = Math.random().toString(36).substring(9);
var create_payout_json = {
"sender_batch_header": {
"sender_batch_id": sender_batch_id,
"email_subject": "You have a payment"
},
"items": [
{
"recipient_type": "EMAIL",
"amount": {
"value": 0.90,
"currency": "CHF" //changed from Dollar to CHF
},
"receiver": mail,
"note": "Thank you.",
"sender_item_id": "item_3"
}
]
};
var sync_mode = 'true'; //for single payout
paypal.payout.create(create_payout_json, sync_mode, function (error, payout) {
if (error) {
console.log(error.response);
res.json(error.response);
throw error;
} else {
console.log("Create Single Payout Response");
console.log(payout);
payout.status= "You are in the else";
res.json(payout);
}
});
}
}
=>The Email-Address comes from my sandbox account - the Balance of this User is set to 900.00 CHF! (Much more than the 0.90 CHF which I want to payout)
=>I created under My Apps and Credentials a new REST API App and select the previous created User (with 900.00CHF balance). Those credentials are used in the above code snipped in paypal.configure()
"Either the sender or receiver exceeded the transaction limit"
Where can I change the transaction limit for the App and User in the sandbox?
OK Solved.
I logged in with the sandbox email address - there you can see all transactions.
Under "Denied" I saw the 0.90CHF - With a popup: "The receiver decided to deny the payment"
Then I realised that I used the same E-Mail Address for the Receiver and the Sender. That accused the Error. - The error-message is not very clear.
Maybe someone else is also doing the same mistake, so I let this here.

Resources