Skip to content

sns fail suddenly

1

Enter image description here

Enter image description here

nothing changed but the delivery rate drop to 0% as the utc day changes by checking the Delivery statistics (UTC) of SNS.

same number same setting. sms used to work as the destination phone numbers was added to Sandbox destination phone numbers and verified.

the number can response with Default Stop Message which tell the carrier didn't block sms from the number.

one time Publish SMS message also fails with message The SMS message to x is accepted. For delivery status, check the delivery log. Message "ID": Request "ID": while it used to deliver the sms too.

on AWS End User Messaging, Spending limits shows SMS Current spend $0.08088 while the Account limit is $1.

used the following lambda function code to test sms and it shows 'Message sent successfully' with MessageId. but sms not received.

Response:
{
  "statusCode": 200,
  "body": "{\"$metadata\":{\"httpStatusCode\":200,\"requestId\":\"f505c8f4-2b7e-5433-aee0-9743586fe9f5\",\"attempts\":1,\"totalRetryDelay\":0},\"MessageId\":\"f37b1607-c9b8-552d-8fb2-49b0baa918eb\"}"
}
import { SNSClient, PublishCommand } from "@aws-sdk/client-sns";

// Initialize the SNS client
const snsClient = new SNSClient({ region: "us-east-1" }); // Replace with your AWS region

/**
 * Sends an SMS message using Amazon SNS.
 * @param {string} phone - The recipient's phone number in E.164 format .
 * @param {string} code - The code to send in the SMS message.
 * @returns {Promise} - A promise that resolves when the message is sent.
 */
const sendSMS = async (phone, code) => {
  try {
    const params = {
      PhoneNumber: phone,
      Message: code,
    };

    const command = new PublishCommand(params);
    const response = await snsClient.send(command);
    console.log("Message sent successfully:", response.MessageId);
    return response;
  } catch (error) {
    console.error("Error sending message:", error);
  }
};


export const handler = async (event) => {
  // TODO implement
  console.log(event)
  const { phone,code } = (event);

  const r = await sendSMS(phone, code)

  const response = {
    statusCode: 200,
    body: JSON.stringify(r),
  };
  return response;
};

  • To which destination country you are sending messages ? Normal messages to the destination number is receiving ?

  • destination country is ca nada (+1) for dev now. no sms is received now

  • was using us-east-2 at the beginning, work again as region changed to ca-central-1 as I am in can ada now

1 Answer
0

Greeting

Hi Frank,

Thank you for sharing your detailed question and code. Let’s address the SNS delivery issue step by step to get it resolved.


Clarifying the Issue

The primary issue is that SMS messages, while logged as "Message sent successfully" by the Lambda function, are not being delivered. Delivery statistics indicate a 0% success rate after a UTC day change, even though the phone number is verified in the Sandbox and not blocked by the carrier. Spending limits and account configurations seem appropriate, as SMS activity shows a small spend.

Potential causes include sandbox limitations, SMS type mismatches, or regional restrictions. We’ll walk through each potential point of failure and suggest a solution.


Key Terms

  • AWS SNS (Simple Notification Service): A service to send notifications, including SMS, to multiple destinations.
  • Sandbox Mode: A restricted environment for testing SNS messages, requiring explicit verification of phone numbers.
  • E.164 Format: The standardized format for international phone numbers required by SNS.
  • CloudWatch Logs: A tool to analyze execution details and debug Lambda functions.
  • Transactional SMS: A message type optimized for critical use cases like authentication, with higher delivery rates.

The Solution (Our Recipe)

Steps at a Glance:

  1. Verify Sandbox settings and upgrade to Production.
  2. Confirm spending limits, SMS type, and regional support.
  3. Analyze SNS Delivery Logs and CloudWatch Logs for failures.
  4. Enhance the Lambda function with improved error handling and validation.

Step-by-Step Guide:

Step 1: Verify Sandbox Settings and Upgrade to Production

  • Navigate to the Text Messaging Preferences in the SNS console and confirm that the destination phone number is verified in Sandbox Mode. Sandbox limits may block unrestricted delivery.
  • To move beyond Sandbox mode, follow these steps to upgrade to Production:
    1. Open the SNS console and go to Text Messaging Preferences.
    2. Enable Production SMS.
    3. Update configurations to support non-verified phone numbers.

Step 2: Confirm Spending Limits, SMS Type, and Regional Support

  • Check the Spending Limits in the SNS dashboard under SMS Preferences. By default, the limit is $1.00, which may restrict further messages. Raise the limit to allow more usage.
  • Set the SMS message type to Transactional. AWS prioritizes transactional messages over promotional ones, which may be deprioritized by carriers.
  • Review the Regional SMS Support in AWS’s documentation. Ensure that both your AWS region and the destination region support SMS delivery. Use this link to verify supported countries and regions.

Step 3: Analyze SNS Delivery Logs and CloudWatch Logs

  • In the SNS console, enable Delivery Status Logging for SMS. This will provide detailed carrier responses and error codes for each sent message. Use this guide to configure delivery logs.
  • Check CloudWatch Logs for the Lambda function to locate the MessageId returned by the SNS send operation.
  • Cross-reference the MessageId in the Delivery Logs for insights. Example of a failed delivery log:
    {
        "deliveryStatus": "FAILURE",
        "statusCode": "InvalidPhoneNumber",
        "providerResponse": "Phone number is not reachable"
    }
    From this, you can identify issues like invalid phone numbers or carrier blocks.

Step 4: Enhance the Lambda Function with Improved Error Handling

Original Code with Inline Comments:

try {
    // Send the SMS message using the SNS client
    const response = await snsClient.send(command);
    
    // Log the success message along with the returned MessageId
    console.log("Message sent successfully:", response.MessageId);
    
    // Return the response object directly (not structured for readability)
    return response;
} catch (error) {
    // Log the error if the message fails to send
    console.error("Error sending message:", error);
}

This code attempts to send an SMS message and logs any errors encountered. However, it lacks validation for input parameters (like phone numbers) and doesn't provide structured error feedback to the caller.

Enhanced Code with Inline Comments:

try {
    // Prepare the parameters for the PublishCommand
    const params = {
        PhoneNumber: "+<E.164_PHONE_NUMBER>", // Replace with a valid E.164 formatted number
        Message: code, // The message content, such as an OTP or notification
    };

    // Validate the phone number format using a regular expression for E.164
    if (!/^\+\d{1,15}$/.test(phone)) {
        // Throw an error if the phone number doesn't match the required format
        throw new Error("Invalid phone number format. Must be in E.164 format.");
    }

    // Create a new PublishCommand with the parameters
    const command = new PublishCommand(params);

    // Send the SMS message using the SNS client
    const response = await snsClient.send(command);
    
    // Log the success message along with the returned MessageId
    console.log("Message sent successfully:", response.MessageId);

    // Return a structured response indicating success
    return {
        statusCode: 200,
        body: JSON.stringify({ success: true, messageId: response.MessageId }),
    };
} catch (error) {
    // Log the error message for debugging purposes
    console.error("Error sending message:", error.message);

    // Return a structured response indicating failure, including error details
    return {
        statusCode: 500,
        body: JSON.stringify({
            success: false, // Indicate failure
            errorType: error.name, // Provide the error type (e.g., ValidationError)
            errorMessage: error.message, // Provide the error message
        }),
    };
}

This enhanced version:

  1. Validates the phone number format before attempting to send the message, reducing errors from invalid inputs.
  2. Provides detailed error messages, including error type and description, in a structured response.
  3. Includes inline comments explaining every key line of code, ensuring clarity for readers.

Closing Thoughts

Frank, by moving out of Sandbox mode, validating your configurations, and analyzing logs, you should be able to resolve the delivery issue. The enhanced Lambda function will make future troubleshooting more efficient. If the problem persists, contact AWS Support with specific Message IDs and delivery logs for deeper investigation.

Let me know if you need further clarification or assistance. 😊


Farewell

Best of luck, and I hope this resolves your SNS delivery challenges! 🚀


Cheers, Aaron 😊

answered 2 years 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.