aws / aws-lambda-go

Libraries, samples and tools to help Go developers develop AWS Lambda functions.
Apache License 2.0
3.64k stars 553 forks source link

LexEvent - ResponseCard error #66

Closed iliasgal closed 6 years ago

iliasgal commented 6 years ago

I am not sure if this is a bug.

I am using a Lambda function as fulfilment to AWS Lex. I want to send a response using the code below:

func scheduleMeeting(event events.LexEvent) (events.LexEvent, error) {

    //some code here

    response := events.LexEvent{
        DialogAction: &events.LexDialogAction{
            Type:             "Close",
            FulfillmentState: "Fulfilled",
            Message:          map[string]string{"contentType": "PlainText", "content": "Thank you!"},
        },
    }

    return response, nil
}

However, I am getting the following error:

An error has occurred: Invalid Lambda Response: Received invalid response from Lambda: Can not deserialize value of type ContentType from String "": value not one of declared Enum instance names: http://application/vnd.amazonaws.card.generic at Source: {"sessionAttributes":null,"dialogAction":{"type":"Close","fulfillmentState":"Fulfilled","message":{"content":"Thank you!","contentType":"PlainText"},"intentName":"","slots":null,"slotToElicit":"","responseCard":{"version":0,"contentType":"","genericAttachments":null}}}; line: 1, column: 239

This ContentType field and the Enum application/vnd.amazonaws.card.generic are on the ResponseCard field, which is optional according to the documentation.

asuresh8 commented 6 years ago

Hmm that is strange, and if you add the the ContentType: application/vnd.amazonaws.card.generic in the ResponseCard object does the error go away?

iliasgal commented 6 years ago

I added the ResponseCard object.

var buttons []map[string]string
buttons = append(buttons, map[string]string{"text": "test", "value": "test"})

var attachements []events.Attachment
attachements = append(attachements, events.Attachment{
    Title:    "test",
    SubTitle: "test subtitle",
        ImageURL: "https://testurl.com",
    Buttons:  buttons,
})

response := events.LexEvent{
    DialogAction: &events.LexDialogAction{
        Type:             "Close",
        FulfillmentState: "Fulfilled",
        Message:          map[string]string{"contentType": "PlainText", "content": message},
        ResponseCard: events.LexResponseCard{
            Version:            1,
            ContentType:        "application/vnd.amazonaws.card.generic",
            GenericAttachments: attachements,
        },
    },
}

And the new error is:

An error has occurred: Invalid Lambda Response: Received invalid response from Lambda: Can not construct instance of GenericAttachment$Builder, problem: Image Url is not in range <1,2048> at [Source: {"sessionAttributes":null,"dialogAction":{"type":"Close","fulfillmentState":"Fulfilled","message":{"content":"Your meeting sdfsdf has been scheduled for 2018-04-05 11:00:00 +0000 UTC","contentType":"PlainText"},"intentName":"","slots":null,"slotToElicit":"","responseCard":{"version":1,"contentType":"application/vnd.amazonaws.card.generic","genericAttachments":[{"title":"test","subTitle":"test subtitle","imageUrl":"test url","attachmentLinkUrl":"","buttons":[{"text":"test","value":"test"}]}]}}}; line: 1, column: 494]

As you can see there is an Image URL field set.

asuresh8 commented 6 years ago

It almost seems as if Lex is checking the parameters on their end. What if you change the ImageURL to an actually valid URL? ex https://a0.awsstatic.com/main/images/logos/aws_logo_smile_1200x630.png

iliasgal commented 6 years ago

I had to add ImageURL, AttachmentLinkURL and IntentName

var buttons []map[string]string
buttons = append(buttons, map[string]string{"text": "test", "value": "test"})

var attachements []events.Attachment
attachements = append(attachements, events.Attachment{
    Title:             "test",
    SubTitle:          "test subtitle",
    ImageURL:          "https://a0.awsstatic.com/main/images/logos/aws_logo_smile_1200x630.png",
    AttachmentLinkURL: "https://a0.awsstatic.com/main/images/logos/aws_logo_smile_1200x630.png",
    Buttons:           buttons,
})

response := events.LexEvent{
    DialogAction: &events.LexDialogAction{
        IntentName:       event.CurrentIntent.Name,
        Type:             "Close",
        FulfillmentState: "Fulfilled",
        Message:          map[string]string{"contentType": "PlainText", "content": message},
        ResponseCard: events.LexResponseCard{
            Version:            1,
            ContentType:        "application/vnd.amazonaws.card.generic",
            GenericAttachments: attachements,
        },
    },
}

return response, nil

And the new error:

An error has occurred: Invalid Lambda Response: Received invalid response from Lambda: Unrecognized field "intentName" (class CloseDialogAction), not marked as ignorable at [Source: {"sessionAttributes":null,"dialogAction":{"type":"Close","fulfillmentState":"Fulfilled","message":{"content":"Your meeting AAA has been scheduled for 2018-04-05 11:00:00 +0000 UTC","contentType":"PlainText"},"intentName":"ScheduleMeeting","slots":null,"slotToElicit":"","responseCard":{"version":1,"contentType":"application/vnd.amazonaws.card.generic","genericAttachments":[{"title":"test","subTitle":"test subtitle","imageUrl":"https://a0.awsstatic.com/main/images/logos/aws_logo_smile_1200x630.png","attachmentLinkUrl":"https://a0.awsstatic.com/main/images/logos/aws_logo_smile_1200x630.png","buttons":[{"text":"test","value":"test"}]}]}}}; line: 1, column: 642]

I do not know what is wrong with intentName, but it is obvious that the LexEvent requires all fields to be populated, even those that make no sense to populate as response.

asuresh8 commented 6 years ago

Yeah the error here is that we don't add omitEmpty to the json serialization of all of the struct fields

brieuc-le-faucheur commented 6 years ago

Hey ! Did you find any fix to this ? I got the same error, in the same context (I want to create an answer without any responseCard)

bmoffatt commented 6 years ago

Merged #75

ralf-cestusio commented 6 years ago

Does this solve the problem for any of you? i still get

An error has occurred: Invalid Lambda Response: Received invalid response from Lambda: Unrecognized field "responseCard" (class DelegateDialogAction), not marked as ignorable at [Source: {"dialogAction":{"type":"Delegate","slots":{"environment":""},"responseCard":{}}}; line: 1, column: 79]
olivoil commented 6 years ago

I still get an error despite the omitempty field tag when not including a ResponseCard

    return events.LexEvent{
        SessionAttributes: evt.SessionAttributes,
        DialogAction: &events.LexDialogAction{
            IntentName:       evt.CurrentIntent.Name,
            Type:             "Close",
            FulfillmentState: "Fulfilled",
            Message: map[string]string{
                "contentType": "PlainText",
                "content":     fmt.Sprintf("Ok, I'll send notifciations for %s to this channel.", evt.CurrentIntent.Slots["ProjectKey"]),
            },
        },
    }, nil
An error has occurred: Invalid Lambda Response: Received invalid response from Lambda: Can not construct instance of ResponseCard$Builder, problem: Content type can't be null at [Source: {"dialogAction":{"type":"Close","fulfillmentState":"Fulfilled","message":{"content":"Ok, I'll send notifciations for PQ please to this channel.","contentType":"PlainText"},"intentName":"SubscribeToJiraProject","responseCard":{}}}; line: 1, column: 227]
olivoil commented 6 years ago

@bmoffatt I think LexDialogAction should declare ResponseCard as a pointer, so it's completely omitted when serializing:

type LexDialogAction struct {
    Type             string            `json:"type,omitempty"`
    FulfillmentState string            `json:"fulfillmentState,omitempty"`
    Message          map[string]string `json:"message,omitempty"`
    IntentName       string            `json:"intentName,omitempty"`
    Slots            Slots             `json:"slots,omitempty"`
    SlotToElicit     string            `json:"slotToElicit,omitempty"`
    ResponseCard     *LexResponseCard   `json:"responseCard,omitempty"`
}