Can not construct instance of IntentResponse, The validated object is null - java

I have been following the youtube tutorial : https://www.youtube.com/watch?v=HkMi5xPyz1g&t=1533s
public Object handleRequest(Map<String,Object> input, Context context) {
LexRequest lexRequest= LexRequestFactory.createLexRequest(input);
String orgbotcommand= lexRequest.getCommand()+" "+lexRequest.getOld_variable();
String content = String.format("command recieved by %s is %s",
lexRequest.getBotName(),
orgbotcommand);
Message message = new Message("Plain text",content);
DialogueAction dialogueAction = new DialogueAction("Close", "Fulfilled or Failed", message );
System.out.println(dialogueAction);
return new LexRespond(dialogueAction);
}
Above is the java code i am using.
it is giving me the desired output while testing with lambda function test events, but when i try to call this lambda function from my lex bot , it throws the error below:
An error has occurred: Invalid Lambda Response: Received invalid response
from Lambda: Can not construct instance of IntentResponse, problem: The
validated object is null at [Source: {"dialogueAction":
{"type":"Close","fulfillmentState":"Fulfilled or Failed","message":
{"contentType":"Plain text","content":"command recieved by OrgBot is Delete asd"}}}; line: 1, column: 168]
Output in lambda test event is :
{
"dialogueAction": {
"type": "Close",
"fulfillmentState": "Fulfilled or Failed",
"message": {
"contentType": "Plain text",
"content": "command recieved by OrgBotchatbot is delete asd"
}
}
}
I am new to Amazan lex and lambda. Please tell me what i am doing wrong

It is probably just your response formatting. Check out the Response Format Docs.
Firstly, contentType needs to be either 'PlainText' or 'SSML'.
So change 'Plain text' to be 'PlainText'
Message message = new Message("PlainText",content);
Secondly, the fulfillmentState needs to be either 'Fulfulled' or 'Failed'.
So remove 'or Failed' from your DialogueAction line to be:
DialogueAction dialogueAction = new DialogueAction("Close", "Fulfilled", message );
Thirdly, dialogAction. Lex must be American because it only accepts the response when you spell 'Dialogue' as 'Dialog'. So change what you need to in your code so that the response returns this:
{
"dialogAction": {
"type": "Close",
"fulfillmentState": "Fulfilled",
"message": {
"contentType": "PlainText",
"content": "command recieved by OrgBotchatbot is delete asd"
}
}
};

If you are using Lex v2, the expected response format is different from v1.
See https://docs.aws.amazon.com/lexv2/latest/dg/lambda.html#lambda-response-format
{
"sessionState": {
"activeContexts": [
{
"name": "string",
"contextAttributes": {
"key": "value"
},
"timeToLive": {
"timeToLiveInSeconds": number,
"turnsToLive": number
}
}
],
"sessionAttributes": {
"string": "string"
},
"dialogAction": {
"slotToElicit": "string",
"type": "Close | ConfirmIntent | Delegate | ElicitIntent | ElicitSlot"
},
"intent": {
"confirmationState": "Confirmed | Denied | None",
"name": "string",
"slots": {
"string": {
"value": {
"interpretedValue": "string",
"originalValue": "string",
"resolvedValues": [
"string"
]
}
},
"string": {
"shape": "List",
"value": {
"originalValue": "string",
"interpretedValue": "string",
"resolvedValues": [
"string"
]
},
"values": [
{
"shape": "Scalar",
"value": {
"originalValue": "string",
"interpretedValue": "string",
"resolvedValues": [
"string"
]
}
},
{
"shape": "Scalar",
"value": {
"originalValue": "string",
"interpretedValue": "string",
"resolvedValues": [
"string"
]
}
}
]
}
}
},
"state": "Failed | Fulfilled | InProgress | ReadyForFulfillment"
},
"messages": [
{
"contentType": "CustomPayload | ImageResponseCard | PlainText | SSML",
"content": "string",
"imageResponseCard": {
"title": "string",
"subtitle": "string",
"imageUrl": "string",
"buttons": [
{
"text": "string",
"value": "string"
}
]
}
}
],
"requestAttributes": {
"string": "string"
}
}

With the new V2, you don't need to fill out all the examples, here is a minimal version of the response in Python (say that you want to send a final message):
return {
"sessionState": {
"dialogAction": {
"type": "Close",
},
"intent": {
"name": "IntentName",
"state": "Fulfilled"
}
},
"messages": [
{
"contentType": "PlainText",
"content": "Thank you for doing business with me!"
}
]
}

The format of your output must follow specific minimal layouts.
I use the following two functions to make it easy.
Just call them from any function when you are ready to tell Lex
//SessionAttributes any session variables
//fulfillmentState - 'Fulfilled' or 'Failed' depending on if successful or not
//message - the actual response text you want lex to say/type
function close(sessionAttributes, fulfillmentState, message) {
return {
sessionAttributes,
dialogAction: {
type: 'Close',
fulfillmentState,
message,
},
};
}
function delegate(sessionAttributes, slots) {
return {
sessionAttributes,
dialogAction: {
type: 'Delegate',
slots,
},
};
}

Related

Java bolt for slack mapping block json and sending it to slack

I am trying to see the following message on slack:
{
"blocks": [{
"type": "actions",
"elements": [{
"type": "button",
"text": {
"type": "plain_text",
"text": "Farmhouse",
"emoji": true
},
"value": "click_me_123"
},
{
"type": "button",
"text": {
"type": "plain_text",
"text": "Kin Khao",
"emoji": true
},
"value": "click_me_123",
"url": "https://google.com"
},
{
"type": "button",
"text": {
"type": "plain_text",
"text": "Ler Ros",
"emoji": true
},
"value": "click_me_123",
"url": "https://google.com"
}
]
}]
}
Now on the java side I am using gson to map this to an object and then send it using ctx.say():
List<LayoutBlock> blocks = answers.stream().map(ans ->
gson.fromJson(ans.getContent(), LayoutBlock.class)
).collect(Collectors.toList());
Now this mapping fails. If I try to use a simpler json it works:
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"text": "Option 1",
"emoji": true
},
"value": "{ \"name\": \"smalltalk.appraisal.thank_you\", \"entities\": { \"reply\": \"test\", \"option\": \"1\" } }"
},
{
"type": "button",
"text": {
"type": "plain_text",
"text": "Option 2",
"emoji": true
},
"value": "{ \"name\": \"smalltalk.appraisal.thank_you\", \"entities\": { \"reply\": \"test\", \"option\": \"2\" } }"
}
]
}
Basically what I'm seeing is that when using ctx.say(), you can either send a String or a List of Blocks:
default ChatPostMessageResponse say(String text) throws IOException, SlackApiException {
this.verifyChannelId();
ChatPostMessageResponse response = this.client().chatPostMessage(ChatPostMessageRequest.builder().text(text).channel(this.getChannelId()).build());
return response;
}
default ChatPostMessageResponse say(List<LayoutBlock> blocks) throws IOException, SlackApiException {
this.verifyChannelId();
ChatPostMessageResponse response = this.client().chatPostMessage(ChatPostMessageRequest.builder().blocks(blocks).channel(this.getChannelId()).build());
return response;
}
How am I supposed to convert the json shown in the slack block kit builder into a java object that can actually be sent using ctx.say()?

GSON serialize of SNSEvent resulting in lower case fields which lambda expects Capitalize words

I have a lambda function which takes SNSEvent(http://javadox.com/com.amazonaws/aws-lambda-java-events/1.1.0/com/amazonaws/services/lambda/runtime/events/SNSEvent.html) as the input and then works on that. For writing the some integration test cases, I wanted to call this lambda with the SNSEvent serialized using using lambda.invoke in which the message would be string.
So, for that, I was doing GSON.toJson([object of SNSEvent type]) and from this, I was getting a string. But the problem is, when I am using this string the invoke the lambda, I am getting an exception that deserialization of this string is failing.
Eg. GSON.toJson is deserializing to :
{
"records": [
{
"eventSource": "aws:sns",
"eventVersion": "1.0",
"eventSubscriptionArn": "arn:aws:sns:us-west-2:{{{accountId}}}:ExampleTopic",
"sns": {
"type": "Notification",
"messageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e",
"topicArn": "arn:aws:sns:us-west-2:{{accountId}}:ExampleTopic",
"subject": "example subject",
"message": "example message",
"timestamp": "1970-01-01T00:00:00.000Z",
"signatureVersion": "1",
"signature": "EXAMPLE",
"signingCertUrl": "EXAMPLE",
"unsubscribeUrl": "EXAMPLE",
"messageAttributes": {
"test": {
"type": "String",
"value": "TestString"
},
"testBinary": {
"type": "Binary",
"value": "TestBinary"
}
}
}
}
]
}
while, the actual, it wants is (with capital letters):
{
"Records": [
{
"EventSource": "aws:sns",
"EventVersion": "1.0",
"EventSubscriptionArn": "arn:aws:sns:us-west-2:{{{accountId}}}:ExampleTopic",
"Sns": {
"Type": "Notification",
"MessageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e",
"TopicArn": "arn:aws:sns:us-west-2:{{accountId}}:ExampleTopic",
"Subject": "example subject",
"Message": "example message",
"Timestamp": "1970-01-01T00:00:00.000Z",
"SignatureVersion": "1",
"Signature": "EXAMPLE",
"SigningCertUrl": "EXAMPLE",
"UnsubscribeUrl": "EXAMPLE",
"MessageAttributes": {
"Test": {
"Type": "String",
"Value": "TestString"
},
"TestBinary": {
"Type": "Binary",
"Value": "TestBinary"
}
}
}
}
]
}
Any idea why is it so? And how can I fix it? Should I use some other object instead of SNSEvent while invoking the lambda.

How to stop getting back AutoResponded code for an Envelope

I know the fact that in case of an invalid email address DocuSign sends back AutoResponded as an envelope status. So, whenever I get back AutoResponded some of my services break. Is there a way to turn this feature off of my DocuSign account?
In simple words just ignore if an status is AutoResponded.
Thanks
You can exclude the AutoResponded recipientEventStatusCode from the eventNotification.
Here is a sample CreateEnvelope request which includes all eventNotifications. You can remove the events that you do not want to receive.
{
"eventNotification": {
"url": "[Callback Url]",
"loggingEnabled": "true",
"requireAcknowledgment": "true",
"envelopeEvents": [
{ "envelopeEventStatusCode": "Delivered" },
{ "envelopeEventStatusCode": "Completed" },
{ "envelopeEventStatusCode": "Declined" },
{ "envelopeEventStatusCode": "Voided" },
{ "envelopeEventStatusCode": "Sent" }
],
"recipientEvents": [
{ "recipientEventStatusCode": "Sent" },
{ "recipientEventStatusCode": "Delivered" },
{ "recipientEventStatusCode": "Completed" },
{ "recipientEventStatusCode": "Declined" },
{ "recipientEventStatusCode": "AuthenticationFailed" },
{ "recipientEventStatusCode": "AutoResponded" }
],
},
"recipients": {
"signers": [
{
"name": "john smith",
"email": "johnsmith#foo.com",
"recipientId": "1",
"routingOrder": "1"
}
]
},
"documents": [
{
"documentId": "1",
"name": "Agreement ",
"fileExtension": "pdf",
"documentBase64": "[Document Bytes]"
}
],
"status": "sent",
"emailSubject": "Envelope for auto responded status"
}

How to parse a DiagnosticReport from a JSON and print the same JSON again?

I'm parsing a DiagnosticReport from a JSON file and It works fine, but when I try to print the same JSON file throught IParser encode function, the JSON is different to the original. I need to print the same JSON.
Original JSON (String json)
{
"resourceType": "DiagnosticReport",
"text": {
"status": "generated",
"div": "<div><p><b>Narrative A</b></p></div>"
},
"contained": [
{
"resourceType": "Patient",
"id": "1"
},
{
"resourceType": "Observation",
"id": "2",
"meta": {
"lastUpdated": "2017-03-22T22:00:28.089-05:00"
},
"text": {
"div": "<div><p><b>Narrative B</b></p></div>"
},
"comment": "a comment"
}
],
"status": "appended",
"code": {
"coding": [
{
"code": "Report01"
}
]
},
"subject": {
"reference": "#1"
},
"effectiveDateTime": "2017-03-22T22:00:28-05:00",
"issued": "2017-03-22T22:00:28.070-05:00",
"result": [
{
"reference": "#2"
}
]
}
First step is parse and the second step is encode and print
DiagnosticReport report = parser.parseResource(DiagnosticReport.class, json);
String encodeJSON = parser.encodeResourceToString(report);
System.out.println(encodeJSON);
And the result is different because the text tag in the Observation is not showed
{
"resourceType": "DiagnosticReport",
"text": {
"status": "generated",
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><p><b>Narrative A</b></p></div>"
},
"contained": [
{
"resourceType": "Patient",
"id": "1"
},
{
"resourceType": "Observation",
"id": "2",
"meta": {
"lastUpdated": "2017-03-22T22:00:28.089-05:00"
},
"comment": "a comment"
}
],
"status": "appended",
"code": {
"coding": [
{
"code": "Report01"
}
]
},
"subject": {
"reference": "#1"
},
"effectiveDateTime": "2017-03-22T22:00:28-05:00",
"issued": "2017-03-22T22:00:28.070-05:00",
"result": [
{
"reference": "#2"
}
]
}
I'm trying this because I have a DiagnosticReport generated by my software and I need print it completely in a JSON file.
Thanks for your help!!
It's not legal to have narrative in a contained resource, nor is it legal to have meta/lastUpdated. There are invariants that prohibit both. Ideally, the parsing software should have thrown an exception, but it's not overly surprising that the serializer has trouble serializing content that's not supposed to be there.
Look at dom-1 and dom-4 in dstu3 or dstu2

How can I tell if a build is in progress when I call the Jenkins json api?

I'm calling a url like this: /job/My-Job/710/api/json and it's returning some json like this:
{
"actions": [
{
"parameters": [
{
"name": "DEPLOY_HOST",
"value": ""
}
]
},
{
"causes": [
{
"shortDescription": "Started by user Hudson Admin",
"userId": "username",
"userName": "Hudson Admin"
}
]
},
{},
{},
{}
],
"artifacts": [],
"building": true,
"description": null,
"duration": 0,
"estimatedDuration": 390011,
"executor": {},
"fullDisplayName": "My-App #711",
"id": "2013-08-30_12-50-14",
"keepLog": false,
"number": 711,
"result": "SUCCESS",
"timestamp": 1377892214231,
"url": "http://hudsonurl:8081/job/My-App/711/",
"builtOn": "",
"changeSet": {
"items": [
{}
],
"kind": "svn",
"revisions": [
{
"module": "https://oursvn",
"revision": 27498
}
]
},
"culprits": [
{
"absoluteUrl": "http://hudsonsurl:8081/user/handsomeg",
"fullName": "handsome guy"
}
],
"mavenArtifacts": null,
"mavenVersionUsed": "3.0.4"
}
This build is actually in progress right now, but I can't see a way to know that. You'd think that the value of result should be in progress, but it's not. Is this a bug, or is there some other way to check? I'm using Jersey version 1.523
I just noticed there's a "building": true.
Makes me wonder what result is for. Maybe builds are considered SUCCESS until proven otherwise.

Categories