node.jsjsonaws-sqs-fifo

Get JSON Object from AWS SQS Event


I have a AWS lamda function that read events from SQS FIFO Queue as below

const CreateItemfromSQS: Handler = async ( event: SQSEvent,context: Context,callback: Callback ) => {
  
  console.log("*** New event Called ***");
  var x : any;
  x = event.Records[0];
  console.log("1-->",x.body);
  console.log("2-->",x.body.body);
  console.log("3-->",x.body.body.messageId);

   var test : any = x.body;
   var testParse : any = JSON.parse(x.body);
   
   
..........
}

when i print X.body I'm Getting Below output

2023-09-16T19:33:51.413Z    9efdf27b-9c46-5c90-8360-affb9919b5aa    INFO    1--> 
{
    "messageId": "1694892825379",
    "body": {
        "itemInfo": {
            "availability": [
                {
                    "warehouseID": "df681a53-2f55-44d6-a33d-7c8d84430c91",
                    "warehouseName": "Foggy Frog - Virginia beach",
                    "availableQuantity": 0
                },
                {
                    "warehouseID": "487cd6d7-0510-4c71-be4b-02ded47ee35d",
                    "warehouseName": "Foggy Frog Cedar",
                    "availableQuantity": 0
                },
                {
                    "warehouseID": "8f93c13a-2717-4cf5-add1-4842deb89428",
                    "warehouseName": "Foggy Frog Suffolk",
                    "availableQuantity": 0
                },
                {
                    "warehouseID": "f257115b-6783-472a-9b9a-213228bea5a8",
                    "warehouseName": "Foggy Frog Chesapeake",
                    "availableQuantity": 0
                }
            ],
            "productVariantID": "3038c5ae-8a55-4795-9bee-ab0d14ed558a:9eea9d80-7dfb-4ac7-a009-1addfb0fd750",
            "productName": "Pre Rolls Infused Liquid Diamonds – 5pk",
            "variantName": "Sour Lifter - SATIVA",
            "images": {
                "varianttag": null,
                "folder": "Product",
                "imagefocused": false,
                "imagepath": "https://d4rap9xlo870y.cloudfront.net/Product/3038c5ae-8a55-4795-9bee-ab0d14ed558a/strawberry-cough-pre-rolls-infused-liquid-diamonds-render.jpeg",
                "name": "strawberry-cough-pre-rolls-infused-liquid-diamonds-render.jpeg",
                "index": 1,
                "id": "3038c5ae-8a55-4795-9bee-ab0d14ed558a"
            },
            "lastupdated": "",
            "procurementlistID": "0f8a2ff9-3fc8-4b61-b103-517caf4582ff",
            "listName": "1234567890"
        }
    }
}

but i wanted to get access for all the information inside the itemInfo block.but this event comes body part as string

i tried so many ways to access those information and always i'm getting errors like below

console.log("2-->",x.body.body);

2023-09-16T19:33:51.413Z    9efdf27b-9c46-5c90-8360-affb9919b5aa    INFO    

2--> undefined

console.log("3-->",x.body.body.messageId);

2023-09-16T19:33:51.414Z    9efdf27b-9c46-5c90-8360-affb9919b5aa    ERROR   Invoke Error    
{
    "errorType": "TypeError",
    "errorMessage": "Cannot read properties of undefined (reading 'messageId')",
    "stack": [
        "TypeError: Cannot read properties of undefined (reading 'messageId')",
        "    at Runtime.r [as handler] (/var/task/API/Procurement/CreateItemfromSQS.js:1:1291)",
        "    at Runtime.handleOnceNonStreaming (file:///var/runtime/index.mjs:1147:29)"
    ]
}

and i tried as below too it also undefine or throw some sort of error

  const jsonObject = JSON.parse(JSON.stringify(x.body));
console.log("Message ID",jsonObject.messageId);
console.log("Product Name",jsonObject.body.itemInfo.productName);

what am i doing wrong here..? how can i parse these Item info to an Object...?

this is how i send these messages to the SQS

async SendToSQS(procurementItem : ProcurementAvailability) {

        const ID = Date.now();
        console.log("SQS URL",process.env.PROCUREMENT_ITEMLIST_QUEUE_URL);
        
        const message = {
            "messageId": ID.toString(), // Unique identifier for the message
            "body": {
              "itemInfo" : procurementItem
            }
          };

          const params = {
            MessageBody: JSON.stringify(message),
            QueueUrl: 'https://sqs.us-east-1.amazonaws.com/...../.......-ProcurementItemListQueue.fifo', 
            MessageGroupId: ID.toString(), // Optional: required for FIFO queues
            MessageDeduplicationId: ID.toString() // Optional: required for FIFO queues
          };

          try {
            const result = await SQS.sendMessage(params).promise();
            console.log('Message sent:', result.MessageId);
            return result;

          } catch (error) {
            console.error('Error sending message:', error);
            return "Error";
          }
    }

SQS Event Structure . This is inbuild structure by AWS

export interface SQSRecord {
    messageId: string;
    receiptHandle: string;
    body: string;
    attributes: SQSRecordAttributes;
    messageAttributes: SQSMessageAttributes;
    md5OfBody: string;
    eventSource: string;
    eventSourceARN: string;
    awsRegion: string;
}

export interface SQSEvent {
    Records: SQSRecord[];
}

export interface SQSRecordAttributes {
    AWSTraceHeader?: string | undefined;
    ApproximateReceiveCount: string;
    SentTimestamp: string;
    SenderId: string;
    ApproximateFirstReceiveTimestamp: string;
    SequenceNumber?: string | undefined;
    MessageGroupId?: string | undefined;
    MessageDeduplicationId?: string | undefined;
    DeadLetterQueueSourceArn?: string | undefined; // Undocumented, but used by AWS to support their re-drive functionality in the console
}

Solution

  • If x.body is a string, you should be able to parse it into an object and then extract your desired values:

    const x = { body : `{
        "messageId": "1694892825379",
        "body": {
            "itemInfo": {
                "availability": [
                    {
                        "warehouseID": "df681a53-2f55-44d6-a33d-7c8d84430c91",
                        "warehouseName": "Foggy Frog - Virginia beach",
                        "availableQuantity": 0
                    },
                    {
                        "warehouseID": "487cd6d7-0510-4c71-be4b-02ded47ee35d",
                        "warehouseName": "Foggy Frog Cedar",
                        "availableQuantity": 0
                    },
                    {
                        "warehouseID": "8f93c13a-2717-4cf5-add1-4842deb89428",
                        "warehouseName": "Foggy Frog Suffolk",
                        "availableQuantity": 0
                    },
                    {
                        "warehouseID": "f257115b-6783-472a-9b9a-213228bea5a8",
                        "warehouseName": "Foggy Frog Chesapeake",
                        "availableQuantity": 0
                    }
                ],
                "productVariantID": "3038c5ae-8a55-4795-9bee-ab0d14ed558a:9eea9d80-7dfb-4ac7-a009-1addfb0fd750",
                "productName": "Pre Rolls Infused Liquid Diamonds – 5pk",
                "variantName": "Sour Lifter - SATIVA",
                "images": {
                    "varianttag": null,
                    "folder": "Product",
                    "imagefocused": false,
                    "imagepath": "https://d4rap9xlo870y.cloudfront.net/Product/3038c5ae-8a55-4795-9bee-ab0d14ed558a/strawberry-cough-pre-rolls-infused-liquid-diamonds-render.jpeg",
                    "name": "strawberry-cough-pre-rolls-infused-liquid-diamonds-render.jpeg",
                    "index": 1,
                    "id": "3038c5ae-8a55-4795-9bee-ab0d14ed558a"
                },
                "lastupdated": "",
                "procurementlistID": "0f8a2ff9-3fc8-4b61-b103-517caf4582ff",
                "listName": "1234567890"
            }
        }
    }` }
    
    const jsonObject = JSON.parse(x.body);
    const messageId = jsonObject.messageId;
    const productName = jsonObject.body.itemInfo.productName;
    
    console.log(messageId)
    console.log(productName)