Skip to content

UK Car Registration - AWS Connect / Lambda Passing Attribute Code Issue

0

I wanted to test sending a numberplate collected in Amazon Connect as an attribute, then pass it through Lambda for validation, to show its a correct reg plate, however its not reading the attribute.

E.G "plate": "plo2 zna"

If I test the Lambda on its own, without using Amazon Connect, I use this in Lambda test area:

{
  "plate": "pl02 zna"
}

I get a correct response from the Lambda, which shows the number plate is valid. All good with this.

If I use Amazon Connect to pass the attribute, I see in the Cloudwatch logs a 400 error, saying it hasn't received the attribute. But I can see "plate": "plo2 zna" is being passed in the log under the parameters which shows "plo2 zna".


{
    
    "ContactFlowName": "Car Registration Phonetic Test",
    "ContactFlowModuleType": "InvokeExternalResource",
    "Identifier": "Valid Reg Check",
    "Timestamp": "2025-03-16T01:35:17.933Z",
    "ExternalResults": {
**        "body": "\"Missing plate attribute in request.\"",**
        "statusCode": "400"
    },
    "Parameters": {
        "FunctionArn": "arn:aws:lambda:eu-west-2:12345:function:CarRegValidation",
        "Parameters": {
            "plate": "plo2 zna"
        },
        "ResponseValidation": "ResponseType=STRING_MAP",
        "TimeLimit": "3000"
    }
}

Here is the Lambda code:

import json
import re

def is_valid_uk_plate(plate):
    # Regular expression for UK number plates (simplified)
    pattern = r"^[A-Z]{2}[0-9]{2} [A-Z]{3}$|^[A-Z]{1,2}[0-9]{1,4} [A-Z]{1,3}$|^[A-Z]{3} [0-9]{1,4}$"
    return bool(re.match(pattern, plate))

def lambda_handler(event, context):
    # Extract the plate number from the nested event structure
    plate = event.get("Parameters", {}).get("Parameters", {}).get("plate")
    
    if not plate:
        return {
            "statusCode": 400,
            "body": json.dumps("Missing plate attribute in request.")
        }
    
    # Convert plate to uppercase
    plate = plate.upper()
    
    if not is_valid_uk_plate(plate):
        return {
            "statusCode": 400,
            "body": json.dumps("Invalid UK registration plate format.")
        }
    
    # Store the plate (In a real-world scenario, this might involve a database or other storage solution)
    stored_plate = {"plate": plate}
    
    return {
        "statusCode": 200,
        "body": json.dumps(stored_plate)
    }

Hoping someone can help me understand why its not accepting the attribute when using Connect to pass the attribute.

Lambda attribute

3 Answers
0

To fix the issue, modify your lambda_handler function as follows:

def lambda_handler(event, context):
    # Extract the plate number from the nested event structure
    plate = event.get("Details", {}).get("Parameters", {}).get("plate")
    
    if not plate:
        return {
            "statusCode": 400,
            "body": json.dumps("Missing plate attribute in request.")
        }
    
    # Rest of your function remains the same
    # ...

This change adjusts how the function accesses the plate number from the event object. When invoked by Amazon Connect, the plate number will be nested under event["Details"]["Parameters"]["plate"].

Also, ensure that in your Amazon Connect flow, you're setting up the "Invoke AWS Lambda function" block correctly:

  1. In the Lambda function parameter section, add a parameter named "plate".
  2. Set its value to the contact attribute where you've stored the plate number.

For example, if you've stored the plate number in a contact attribute named "CarPlate", you would set the parameter value to $.Attributes.CarPlate.

By making these adjustments, your Lambda function should be able to correctly receive and process the plate number sent from Amazon Connect.

Sources
Grant Amazon Connect access to your AWS Lambda functions - Amazon Connect

answered 2 years ago

EXPERT

reviewed a year ago

0

Hi, The issue is with how AWS Connect passes parameters to Lambda versus how you're accessing them. Here's the fix:

  1. Modify Lambda function to handle Connect's parameter structure:
import json
import re

def is_valid_uk_plate(plate):
    pattern = r"^[A-Z]{2}[0-9]{2} [A-Z]{3}$|^[A-Z]{1,2}[0-9]{1,4} [A-Z]{1,3}$|^[A-Z]{3} [0-9]{1,4}$"
    return bool(re.match(pattern, plate))

def lambda_handler(event, context):
    # Handle both direct Lambda testing and Connect inputs
    if isinstance(event, dict):
        if "plate" in event:
            # Direct Lambda test
            plate = event["plate"]
        elif "Details" in event:
            # Connect integration
            plate = event.get("Details", {}).get("Parameters", {}).get("plate")
        else:
            plate = None
    
    if not plate:
        return {
            "statusCode": 400,
            "body": "Missing plate attribute in request."
        }
    
    plate = plate.upper()
    
    if not is_valid_uk_plate(plate):
        return {
            "statusCode": 400,
            "body": "Invalid UK registration plate format."
        }
    
    return {
        "statusCode": 200,
        "body": {"plate": plate}
    }
  1. In AWS Connect flow:
  • Set Contact Attributes before Lambda invocation
  • Use exactly "plate" as the parameter name
  • Ensure the attribute value is properly formatted

Key points:

  • Connect passes parameters in event.Details.Parameters
  • Return format must match Connect's expectations
  • Don't use json.dumps() for body when used with Connect

For more details:

AWS

answered 2 years ago

EXPERT

reviewed a year ago

0

I think I spotted the problem 👀

In your Lambda, you're trying to access the plate like this:

python plate = event.get("Parameters", {}).get("Parameters", {}).get("plate") But from your CloudWatch logs, the event structure looks different. The "plate" is actually inside "Parameters" at the top level, not nested twice.

From your log:

json "Parameters": { "FunctionArn": "...", "Parameters": { "plate": "plo2 zna" }, ... } Wait, actually I see it is nested twice 😅 – but the error says "Missing plate attribute in request." which means your Lambda isn't finding it.

Try this fix instead: Change your Lambda code to handle both cases – when it comes from Connect vs when you test it manually:

python def lambda_handler(event, context): # Try different ways to get the plate plate = None

# If testing manually with {"plate": "pl02 zna"}
if "plate" in event:
    plate = event.get("plate")

# If coming from Connect with nested Parameters
elif "Parameters" in event:
    if "Parameters" in event["Parameters"]:
        plate = event["Parameters"]["Parameters"].get("plate")
    else:
        plate = event["Parameters"].get("plate")

# If none of the above worked
if not plate:
    return {
        "statusCode": 400,
        "body": json.dumps("Missing plate attribute in request.")
    }

Another thing I noticed: Your test input has "pl02 zna" (with a zero) but Connect is passing "plo2 zna" (with the letter 'o'). Make sure the user is saying the plate clearly, but that shouldn't cause the 400 error – it would just fail validation later.

answered a month ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.