paws-r/paws

Invoke Lambda with escaped strings not working

Closed this issue · 3 comments

I have been unable to successfully use your package to invoke a lambda which expects a payload as follows:

{
  "bodyjson": "{\"payload\":\"payload\"}",
  "cognitoUserId": "123456",
  "cognitoUserEmail": "email@gmail.com",
  "id": "123456"
}

The error I get is :

Error: InvalidRequestContentException (HTTP 400). Could not parse request body into json: Could not parse payload into json: Unexpected character ('p' (code 112)): was expecting comma to separate Object entries
 at [Source: (byte[])"{
  "bodyjson": "{"payload":"payload"}",
  "cognitoUserId": "123456",
  "cognitoUserEmail": "email@gmail.com",
  "id": "123456"
}"; line: 2, column: 19]

I can successfully send requests where no escaped double quotes are present. This reaches the lambda - but obviously doesn't do much more since the format is wrong. So the issue appears to be in the parsing of the json. Does this example perhaps highlight a known limitation of the parser in use here?

hi @monkeytronics,

Is it possible for you to provide the paws code please.

In the meantime here is an example of how to invoke lambda from paws.

payload <- list(
  bodyjson = "{\"payload\":\"hello world\"}",
  cognitoUserId = "123456",
  cognitoUserEmail = "email@gmail.com",
  id = "111000"
)
  
lambda = paws::lambda()
resp <- lambda$invoke(
  FunctionName = "demo",
  Payload = jsonlite::toJSON(payload, auto_unbox = T)
)
jsonlite::fromJSON(rawToChar(resp$Payload))
#> $statusCode
#> [1] 200
#> 
#> $body
#> [1] "\"hello world\""
#> 
#> $cognito
#> [1] "{\"email\": \"email@gmail.com\", \"id\": \"123456\"}"
#> 
#> $id
#> [1] "111000"

Created on 2023-07-04 with reprex v2.0.2

AWS Lambda code:

import json

def lambda_handler(event, context):
    bodyjson = event.get("bodyjson")
    payload = json.loads(bodyjson).get("payload")
    
    cognitoUserEmail = event.get("cognitoUserEmail")
    cognitoUserId = event.get("cognitoUserId")
    id = event.get("id")
    
    return {
        'statusCode': 200,
        'body': json.dumps(payload),
        'cognito' : json.dumps({
            'email': cognitoUserEmail,
            'id': cognitoUserId
        }),
        'id': id
    }

Here is the same example but just using string as payload:

library(paws.common)

payload <- "{\"bodyjson\":\"{\\\"payload\\\":\\\"hello world\\\"}\",\"cognitoUserId\":\"123456\",\"cognitoUserEmail\":\"email@gmail.com\",\"id\":\"111000\"}"
  
lambda = paws::lambda()
resp <- lambda$invoke(
  FunctionName = "demo",
  Payload = payload
)
jsonlite::fromJSON(rawToChar(resp$Payload))
#> $statusCode
#> [1] 200
#> 
#> $body
#> [1] "\"hello world\""
#> 
#> $cognito
#> [1] "{\"email\": \"email@gmail.com\", \"id\": \"123456\"}"
#> 
#> $id
#> [1] "111000"

Created on 2023-07-04 with reprex v2.0.2
I hope this helps.

Hey, yes, I stumbled on the solution which you also have provided, thanks. The issue was that I should have escaped the nested double quotes twice. The use of single quotes in the example code obscured this. So the following looks wrong, but actually works:

Payload <- paste0(
'{
  "bodyjson": "{\\\"deviceOwner\\\":\\\"email@email.com\\\",\\\"deviceId\\\":\\\"S000000\\\",\\\"info\\\":\\\" \\\"}",
  "cognitoUserId": "NOT_USED",
  "cognitoUserEmail": "email@gmail.com",
  "id": "NOT_USED"
}'
)

response <- lambda$invoke(
  FunctionName = "do-stuff",
  InvocationType = "RequestResponse",
  Payload = Payload,
  LogType = "Tail"
)

Thanks.

Closing this ticket