google.protobuf.Struct is coming back as just fields in NodeJS - node.js

I have the following response message in my proto file via NodeJS.
message WorkSpaceResponse{
google.protobuf.Struct workspace = 1;
}
And below is the service function that sends back the response as:
let sample = {
"name": "Test Workspace",
"id":"sampleId"
}
callback(null, { workspace: sample });
However, when the response gets back to the client all I'm getting is the following:
{
"fields": {}
}
Why is it so, I was expecting the result as
{
"name": "Test Workspace",
"id":"sampleId"
}
What am I doing wrong?

Related

Notification not delivered via server in fcm

Im using fcm-node i tried to send a push notification and it perfectly works locally, however when i try to send it using the server, it fails
var message = {
//this may vary according to the message type (single recipient, multicast, topic, et cetera)
to: notificationToken,
notification: {
bla bla
},
};
fcm.send(message, function (err, response) {
console.log("inside");
if (err) {
console.log("Something has gone wrong!", err);
} else {
console.log("Successfully sent with response: ", response);
}
});
Response for server:
Successfully sent with response: {
results: [ { error: [FirebaseMessagingError] } ],
canonicalRegistrationTokenCount: 0,
failureCount: 1,
successCount: 0,
multicastId: 502625035652113000
}
Tried to get the device notified

No json_payload for DialogFlow logs in Stackdriver in GCP

Recently, I tried to retrieve DialogFlow logs (i.e. containing everything regarding session information/interaction) from StackDriver to perform my custom analysis for dashboard purpose by enabling the option below:
However, after I checked the format of DialogFlow log entries, it seems there is only unstructured text_payload available (i.e.) and not having structured json_payload.
The pain is that I cannot easily parse the text_payload to get the data I want from it. Therefore, my question is:
Can json_payload be available by enabling some settings that I missed?
If for some reason json_payload is not available, any alternative format that can be easy to use for data retrieval? or any parser I can use onto the text_payload?
Thanks in advance.
A log entry format of a Dialogflow request:
{
"textPayload": "Dialogflow Request : {"session":"44885105","query_input":"{\n \"event\": {\n \"name\": \"WELCOME\",\n \"parameters\": {\n }\n }\n}","timezone":"Australia/Sydney"}",
"insertId": "gnp3xsg27351ns",
"resource": {
"type": "global",
"labels": {
"project_id": "ai-hackathon-2020-lrwc"
}
},
"timestamp": "2020-08-07T04:11:29.737Z",
"severity": "INFO",
"labels": {
"request_id": "05f6f343-a646-42e0-8181-48c2e853e21b-0820055c",
"protocol": "V2",
"type": "dialogflow_request"
},
"logName": "projects/ai-hackathon-2020-lrwc/logs/dialogflow_agent",
"trace": "44885105",
"receiveTimestamp": "2020-08-07T04:11:29.800030654Z"
}
A log entry format of a Dialogflow response:
{
"textPayload": "Dialogflow Response : id: "05f6f343-a646-42e0-8181-48c2e853e21b-0820055c"\nlang: "en"\nsession_id: "44885105"\ntimestamp: "2020-08-07T04:11:29.747Z"\nresult {\n source: "agent"\n resolved_query: "WELCOME"\n action: "input.welcome"\n score: 1.0\n parameters {\n }\n contexts {\n name: "defaultwelcomeintent-followup"\n lifespan: 2\n parameters {\n }\n }\n metadata {\n intent_id: "22498e9a-efcf-43e0-a945-36a7ef4c702d"\n intent_name: "Default Welcome Intent"\n webhook_used: "false"\n webhook_for_slot_filling_used: "false"\n is_fallback_intent: "false"\n }\n fulfillment {\n speech: "Hey Good Day! what kind of issue do you want to report?"\n messages {\n lang: "en"\n type {\n number_value: 0.0\n }\n speech {\n string_value: "Hey Good Day! what kind of issue do you want to report?"\n }\n }\n }\n}\nstatus {\n code: 200\n error_type: "success"\n}\n",
"insertId": "gnp3xsg27351nt",
"resource": {
"type": "global",
"labels": {
"project_id": "ai-hackathon-2020-lrwc"
}
},
"timestamp": "2020-08-07T04:11:29.789Z",
"severity": "INFO",
"labels": {
"type": "dialogflow_response",
"protocol": "V2",
"request_id": "05f6f343-a646-42e0-8181-48c2e853e21b-0820055c"
},
"logName": "projects/ai-hackathon-2020-lrwc/logs/dialogflow_agent",
"trace": "44885105",
"receiveTimestamp": "2020-08-07T04:11:29.800030654Z"
}
I had a look at this document on Processing payloads and found when the log line is a serialized JSON object and the detect_json option is enabled, the output plugin transforms the log entry into a structured (JSON) payload. By default this option is enabled for VM instances running on the App Engine flexible environment and Google Kubernetes Engine.Whereas this is not enabled by default in VM instances running on the App Engine standard environment.
However, It is possible to customize the agent's configuration to support ingesting structured logs from additional resources. Documentation on Streaming structured (JSON) log records to Cloud Logging might be helpful.
The payload of log records streamed by a custom-configured Logging agent can be either a single unstructured text message (textPayload) or a structured JSON message (jsonPayload).
You can use the parse-dialogflow-log module like so:
first remove
Dialogflow fulfillment response :
Dialogflow fulfillment request :
Dialogflow Request :
and Dialogflow Response :
for the first 3, just parse using JSON.parse()
parse the last one with parse-dialogflow-log module as shown in this simple function I made. (it can be made better to be more efficient)
async function parsePayload(odj){
let result = await odj.map((e)=>{
let a = e.textPayload;
let g;
let c;
let w = a.slice(0, 31);
if(w.includes(':')){
let t = a.slice(0,21)
g = a.replace(t, '{') + '}'
try {
c = parser.parse(g);
e.textPayload = c;
} catch (error) {
console.log('ERROR AT: ' + t)
try {
g = a.replace(t, '');
let df = JSON.parse(g)
e.textPayload = df
} catch (error) {
console.log('cannot parse req')
}
}
}else{
let u = a.slice(0, 32)
if(u.includes(':')){
g = a.replace(u, '')
try {
c = parser.parse(g);
console.log(u)
console.log(c)
} catch (error) {
console.log('ERROR AT: ' + u)
try {
let dd = JSON.parse(g)
e.textPayload = dd;
} catch (error) {
console.log('cannot parse')
}
}
}else{
let v = a.slice(0, 34);
g = a.replace(v, '')
try {
c = parser.parse(g);
} catch (error) {
console.log('ERROR AT: ' + v)
try {
let dd = JSON.parse(g)
e.textPayload = dd;
} catch (error) {
console.log('cannot parse')
}
}
}
}
return e
})
return result
}

HTTP request failing in AWS Lambda function for Alexa

I am trying to return data from an external api in my inline Lambda function but when I test this in the developer console for Alexa, I get 'There was a problem with the requested skills response' and I can't work out why.
Also, as I am doing this from the AWS console, I can't console.log to see what it actually being returned.
(I have removed the default intents for the sake of the post)
const request = require('request');
const handlers = {
'LaunchRequest': function () {
this.emit(':ask', 'Welcome');
},
'GiveUpdateIntent': function (){
var slot = this.event.request.intent.slots.line.value;
httpGet(slot, (theResult) => {
this.response.speak(theResult);
this.emit(':responseReady');
});
}
};
function httpGet(query, callback) {
var options = {
host: 'api.tfl.gov.uk',
path: '/line/' + encodeURIComponent(query) + '/status',
method: 'GET',
};
var req = http.request(options, res => {
res.setEncoding('utf8');
var responseString = "";
//accept incoming data asynchronously
res.on('data', chunk => {
responseString += chunk;
});
//return the data when streaming is complete
res.on('end', () => {
console.log(responseString[0]);
callback(responseString[0]);
});
});
req.end();
}
exports.handler = function (event, context, callback) {
const alexa = Alexa.handler(event, context, callback);
alexa.APP_ID = APP_ID;
alexa.registerHandlers(handlers);
alexa.execute();
};
"There was a problem with the requested skills response" generally means that the response from your skill was not in the expected format.
Your API request
Ex: vicotria
https://api.tfl.gov.uk/Line/victoria/Status
returns a JSON, and you can't directly pass it Alexa as response. Before you send it back to Alexa, take out status that you actually want Alexa to speak. Then put that into a meaningful sentence that any skill user will understand and send it back.
For example you can return something like:
var speech = "Status severity description for " +
this.event.request.intent.slots.line.value +
" is "
+ responseBody[0].lineStatuses.statusSeverityDescription;
this.emit(':ask',speech, "your re-prompt here");
This is a sample JSON that I got
[
{
"$type": "Tfl.Api.Presentation.Entities.Line, Tfl.Api.Presentation.Entities",
"id": "victoria",
"name": "Victoria",
"modeName": "tube",
"disruptions": [],
"created": "2018-07-31T12:11:08.477Z",
"modified": "2018-07-31T12:11:08.477Z",
"lineStatuses": [
{
"$type": "Tfl.Api.Presentation.Entities.LineStatus, Tfl.Api.Presentation.Entities",
"id": 0,
"statusSeverity": 10,
"statusSeverityDescription": "Good Service",
"created": "0001-01-01T00:00:00",
"validityPeriods": []
}
],
"routeSections": [],
"serviceTypes": [
{
"$type": "Tfl.Api.Presentation.Entities.LineServiceTypeInfo, Tfl.Api.Presentation.Entities",
"name": "Regular",
"uri": "/Line/Route?ids=Victoria&serviceTypes=Regular"
},
{
"$type": "Tfl.Api.Presentation.Entities.LineServiceTypeInfo, Tfl.Api.Presentation.Entities",
"name": "Night",
"uri": "/Line/Route?ids=Victoria&serviceTypes=Night"
}
],
"crowding": {
"$type": "Tfl.Api.Presentation.Entities.Crowding, Tfl.Api.Presentation.Entities"
}
}
]
CloudWatch:
Always make use of CloudWatch to see the logs of your Lambda function, you will get a link under Monitoring tab of your Lambda Function.
Configuring Lambda Test Events: You can test you Lambda code right from your inline editor by configuring Lambda Test Events under Test menu of your inline editor. A function can have up to 10 test events.
This is because your handler is returning before the callback is called. I strongly suggest to move away from callback based development in NodeJS and to use Promise instead.
I just answered a similar question, and provided sample code with promises. Check it here How to make an asynchronous api call for Alexa Skill application with a Lambda function?
The issue turned out to be with using http itself instead of https.
The only response back that I was getting was a status code of 302 which is a redirection because the api I was calling changes all http requests to https.
Therefore, I changed my import to https and used the https.get method (instead of http.get) to call the api and the correct response was returned.

Azure function output binding destroys collection in Cosmos DB

I am trying to save a document to a collection in CosmosDB using output binding.
The DB was created with MongoDB API access.
I noticed a few issues:
Azure function in JavaScript with output binding doesn't seem to work. Here is the code:
module.exports = function (context, req) {
if (req.body) {
context.bindings.outputObject = JSON.stringify({
name: "Mike P"
}); // tried outputObjectOut as well, no difference
context.res = {
// status: 200, /* Defaults to 200 */
body: "Hello " + (req.query.name || req.body.name)
};
}
else {
context.res = {
status: 400,
body: "Please pass a name on the query string or in the request body"
};
}
context.done();
};
The function.json for the JavaScript code is the same as given further below.
I wrote equivalent code in C# and noticed that the collection was destroyed (by the binding apparently when the document was saved).
public static HttpResponseMessage Run(HttpRequestMessage req,
out object outputObject, TraceWriter log)
{
outputObject = new {
name = "Mike P"
};
log.Info("test");
return req.CreateResponse(HttpStatusCode.OK);
}
Here is the function.json
{
"type": "documentDB",
"name": "outputObject",
"databaseName": "newexp",
"collectionName": "Test",
"createIfNotExists": true,
"connection": "newexp_DOCUMENTDB",
"direction": "out"
}
The collection can't be queried any more in the Azure console. Querying through a MongoDB client like 3T failed as well.
I would expect this code to work and a document shows up in the collection in the DB. But instead I am seeing the collection becoming unusable. Is this a bug or am I doing something wrong? Any help or pointers are appreciated.
The Azure Function CosmosDB binding is written against the DocumentDB API (or SQL API) for CosmosDB - so doesn't work out-of-the-box with Mongo API. I believe it may work if you add a required _id property in the object. Without an _id field the Mongo API call will fail

AWS lambda function- 'An error has occurred: Received error response from Lambda: Handled'

Working on AWS Lex for creating a ChatBot and using the Node.js in AWS Lambda.
Error: An error has occurred: Received error response from Lambda:
Handled
Lambda function:
var aws = require('aws-sdk');
var ses = new aws.SES({region: 'us-east-1'});
exports.handler = function(event, context, callback) {
var eParams = {
Destination: {
ToAddresses: [event.currentIntent.slots.Email]
},
Message: {
Body: {
Text: {
Data: "Hi, How are you?"
}
},
Subject: {
Data: "Title"
}
},
Source: "abc#gmail.com"
};
var email = ses.sendEmail(eParams, function(err, data){
if(err)
else {
context.succeed(event);
}
});
};
How to get a proper response from Lambda to Lex after successful execution (Email Service works properly). I have tried context.done(); but it did not worked out.
Edit 1:
Tried adding below response test from AWS Documentation for LEX still getting the same error response.
exports.handler = (event, context, callback) => {
callback(null, {
"dialogAction": {
"type": "ConfirmIntent",
"message": {
"contentType": "PlainText or SSML",
"content": "message to convey to the user, i.e. Are you sure you want a large pizza?"
}
}
});
As mentioned in the lambda-input-response-format docs here fulfillmentState property is required in the response.
Other thing is you have to pass either PlainText OR SSML for the contentType in the response. In your case its just PlainText.
exports.handler = (event, context, callback) => {
callback(null, {
"dialogAction": {
"type": "ConfirmIntent",
"fulfillmentState": "Fulfilled", // <-- Required
"message": {
"contentType": "PlainText",
"content": "message to convey to the user, i.e. Are you sure you want a large pizza?"
}
}
});
The above code should solve your problem.
However if you see the req-res in the network tab you would receive HTTP Error 424 which says DependencyFailedException which says "Amazon Lex does not have sufficient permissions to call a Lambda function" very misleading.

Resources