You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS Lambda调用SNS发送SMS突然失效问题咨询

问题描述
  • 此前通过API Gateway(REST API)触发Lambda函数调用SNS向本人手机发送SMS,功能长期运行正常,近期突然无法收到短信
  • 使用AWS免费套餐账户,已确认未达到SMS发送条数配额上限
  • 自前一日功能正常、短信可成功送达已验证手机号至今,相关IAM权限、角色配置未做任何修改
  • 代码中定义了test2变量返回SNS发送结果,但该返回值无法定位问题根因

核心疑问:通过什么方式可以定位该问题的具体错误原因?该故障为何会突然出现?

关联代码与返回值

Lambda函数代码

const AWS = require("aws-sdk");
const dynamo = new AWS.DynamoDB.DocumentClient();
const SNS = new AWS.SNS();
const tableName = "Testing";  
const smsMessage = {
                PhoneNumber: '+39#mynumber#',
                Message: 'Someone called your api!'
             };
const httpMethodConverter = 'http-method';
const pathRequestConverter = "resource-path";
const headers = {
  "Access-Control-Allow-Origin":"https://#myaccount#.github.io",
  "Content-Type": "application/json",
  "Access-Control-Allow-Methods": "GET, POST, PATCH, PUT, DELETE, OPTIONS",
  "Access-Control-Allow-Headers": "Origin, Content-Type, X-Auth-Token"
};

let body;
let statusCode = 200;
let test2;

exports.handler = async (event, context) => {

  try {
    let test = JSON.stringify(event);
    let callContext = event.context;
    let httpMethod = callContext[httpMethodConverter];
    let path = callContext[pathRequestConverter];
    let methodAndPath = httpMethod + " "+ path;
    
    test2= await SNS.publish(smsMessage).promise();

    switch (methodAndPath) {

      case "DELETE /items/{id}":
        await dynamo
          .delete({
            TableName: tableName,
            Key: {
              Id: parseInt(JSON.parse(test).params.path.id)
            }
          })
          .promise();
        body = `Deleted item ${JSON.parse(test).params.path.id}`;
        break;
        
      case "GET /items/{id}":
        body = await dynamo
          .get({
            TableName: tableName,
            Key: {
              Id: parseInt(JSON.parse(test).params.path.id)
            }
          })
          .promise();
        break;
        
      case "GET /items":
        body = await dynamo.scan({ TableName: tableName }).promise();
        break;
        
      case "POST /items":
        var bodyParser = "body-json";
        var bodyPassed = JSON.parse(test)[bodyParser];

        await dynamo
          .put({
            TableName: tableName,
            Item: {
              Id: parseInt(bodyPassed.Id),
              Type: bodyPassed.Type
            }
          })
          .promise();

        body = "Put item "+ bodyPassed.Type+ " id: " + parseInt(bodyPassed.Id);
        break;
        
      default:
        throw new Error(`Unsupported route: "${event.context}"`);
    }
  } catch (err) {
    statusCode = 400;
    body = err.message;
  } finally {
    body = JSON.stringify(body);
  }

  return {
    statusCode,
    body,
    headers,
    test2
  };
};

SNS publish接口返回结果

"test2": {
    "ResponseMetadata": {
      "RequestId": "b2fbd9fc-4cc0-54e8-a660-82#########"
    },
    "MessageId": "c94393bf-cbb3-5cb9-8155-c#########"
  }

注意:SNS接口返回MessageId仅代表发送请求被SNS服务端成功接收,不代表短信已经成功投递到运营商或最终送达用户手机,这是现有返回值无法定位问题的核心原因。

问题排查步骤
  • 开启SNS SMS投递状态日志
    进入SNS控制台的文本消息(SMS)设置页,配置CloudWatch日志投递,给SNS服务关联角色授予CloudWatch Logs写入权限。重新触发发送请求后,即可在CloudWatch日志中查询到单条短信的完整投递链路,包括运营商返回的错误码、具体失败原因,常见的失败原因包括号码格式错误、运营商拦截、目的地发送受限、账户发送权限被限制等。
  • 核查SNS账户级SMS发送配额
    在SNS SMS设置页查看当前账户的月度支出限额、单条短信发送限额、默认短信发送类型。SMS配额并非仅按发送条数计算,而是按目的地实际费率折算金额,免费套餐默认的支出限额极低,即使未触达条数上限,也可能因为费率调整、发送了高费率地区短信触达金额阈值,导致发送被静默拦截。
  • 核查目标号码状态
    +39为意大利区号,首先确认目标号码没有主动/被动退订过AWS SNS发送的短信——一旦号码回复过退订关键词(如STOP、退订,部分手机的垃圾短信拦截功能会自动回复这类内容),SNS会默认永久屏蔽该号码的所有短信,且API调用不会返回报错。同时确认号码当前状态正常,无停机、无开启高强度国际短信/平台类短信拦截规则。
  • 核查SNS发送配置
    确认SNS账户级别没有配置禁止向意大利地区发送短信,确认短信发送类型没有被自动调整为Promotional(营销类短信,在意大利等欧洲国家送达率极低,极易被运营商拦截),通知类短信建议设置为Transactional(交易类),发送优先级和送达率更高。
故障突发的常见原因
  • 免费套餐SMS支出配额耗尽:意大利属于国际短信目的地,单条短信费率高于美国本土号码,若近期目的地费率上调,或账户下其他服务消耗了SMS额度,很容易触达免费套餐默认的低金额阈值,此时SNS会接收请求但不实际下发,API侧无报错。
  • 目标号码被加入SNS退订黑名单:若之前收到短信后误操作回复退订,或手机拦截功能自动发送了退订指令,SNS会直接屏蔽该号码的所有发送请求,API调用依然返回成功的MessageId。
  • 运营商侧管控规则升级:近期欧洲运营商对A2P(应用向个人发送)类短信管控收紧,未注册正规发送方ID的国际短信会被运营商直接拦截,不会投递给用户。
  • AWS侧账户发送权限调整:免费套餐账户若被系统判定存在短信滥用风险,会自动限制SMS实际下发能力,API调用可正常返回结果,但消息不会进入运营商投递链路,这类限制可通过AWS支持中心查询。

内容的提问来源于stack exchange,提问作者Gianluca Fontana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 01:21:40