如何使用控制台在aws SNS中发送json消息体

如何使用控制台在aws SNS中发送json消息体,json,amazon-web-services,aws-lambda,amazon-sns,Json,Amazon Web Services,Aws Lambda,Amazon Sns,我正在做一个实践,我想在lambda函数中添加一个SNS触发器,然后将消息发送到一个空闲通道。python中有一个lambda的蓝图,还有一个模板测试事件,如下所示 { "Records": [ { "EventVersion": "1.0", "EventSubscriptionArn": "arn:aws:sns:EXAMPLE", "

我正在做一个实践,我想在lambda函数中添加一个SNS触发器,然后将消息发送到一个空闲通道。python中有一个lambda的蓝图,还有一个模板测试事件,如下所示

{
  "Records": [
    {
      "EventVersion": "1.0",
      "EventSubscriptionArn": "arn:aws:sns:EXAMPLE",
      "EventSource": "aws:sns",
      "Sns": {
        "SignatureVersion": "1",
        "Timestamp": "1970-01-01T00:00:00.000Z",
        "Signature": "EXAMPLE",
        "SigningCertUrl": "EXAMPLE",
        "MessageId": "12345",
        "Message": {
          "AlarmName": "SlackAlarm",
          "NewStateValue": "OK",
          "NewStateReason": "Threshold Crossed: 1 datapoint (0.0) was not greater than or equal to the threshold (1.0)."
        },
        "MessageAttributes": {
          "Test": {
            "Type": "String",
            "Value": "TestString"
          },
          "TestBinary": {
            "Type": "Binary",
            "Value": "TestBinary"
          }
        },
        "Type": "Notification",
        "UnsubscribeUrl": "EXAMPLE",
        "TopicArn": "arn:aws:sns:EXAMPLE",
        "Subject": "TestInvoke"
      }
    }
  ]
蓝图中lambda处理程序中的代码如下

import boto3
import json
import logging
import os

from base64 import b64decode
from urllib.request import Request, urlopen
from urllib.error import URLError, HTTPError

HOOK_URL = os.environ['kmsEncryptedHookUrl']
SLACK_CHANNEL = os.environ['slackChannel']

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(event, context):
    logger.info("Event: " + str(event))
    message = event['Records'][0]['Sns']['Message']
    logger.info("Message: " + str(message))

    alarm_name = message['AlarmName']
    new_state = message['NewStateValue']
    reason = message['NewStateReason']

    slack_message = {
        'channel': SLACK_CHANNEL,
        'text': "%s state is now %s: %s" % (alarm_name, new_state, reason)
    }

    req = Request(HOOK_URL, json.dumps(slack_message).encode('utf-8'))
    try:
        response = urlopen(req)
        response.read()
        logger.info("Message posted to %s", slack_message['channel'])
    except HTTPError as e:
        logger.error("Request failed: %d %s", e.code, e.reason)
    except URLError as e:
        logger.error("Server connection failed: %s", e.reason)
当我运行测试事件时,lambda成功运行

我想从控制台在SNS主题中发布一条消息,看看lambda是否被正确触发。但是当我试图将JSON对象发布为消息体时,我得到了错误

[ERROR] TypeError: string indices must be integersTraceback (most recent call last):  File "/var/task/lambda_function.py", line 21, in lambda_handler    alarm_name = message['AlarmName']
我试着给他们简单的回答

{
  "AlarmName": "PublishedAlarm",
  "NewStateValue": "OK",
  "NewStateReason": "This alarm is published"
}
我试着给出一个字符串化的JSON

"{\"AlarmName\": \"PublishedAlarm\",\"NewStateValue\": \"OK\",\"NewStateReason\": \"This alarm is published\"}"
我尝试为每个传递选择
自定义负载
消息结构,然后给出以下消息体

{
  "default": "Sample fallback message",
  "email": "Sample message for email endpoints",
  "sqs": "Sample message for Amazon SQS endpoints",
  "lambda": "{\"AlarmName\": \"PublishedAlarm\",\"NewStateValue\": \"OK\",\"NewStateReason\": \"This alarm is published\"}",
  "http": "Sample message for HTTP endpoints",
  "https": "Sample message for HTTPS endpoints",
  "sms": "Sample message for SMS endpoints",
  "firehose": "Sample message for Amazon Kinesis Data Firehose endpoints",
  "APNS": "{\"aps\":{\"alert\": \"Sample message for iOS endpoints\"} }",
  "APNS_SANDBOX": "{\"aps\":{\"alert\":\"Sample message for iOS development endpoints\"}}",
  "APNS_VOIP": "{\"aps\":{\"alert\":\"Sample message for Apple VoIP endpoints\"}}",
  "APNS_VOIP_SANDBOX": "{\"aps\":{\"alert\": \"Sample message for Apple VoIP development endpoints\"} }",
  "MACOS": "{\"aps\":{\"alert\":\"Sample message for MacOS endpoints\"}}",
  "MACOS_SANDBOX": "{\"aps\":{\"alert\": \"Sample message for MacOS development endpoints\"} }",
  "GCM": "{ \"data\": { \"message\": \"Sample message for Android endpoints\" } }",
  "ADM": "{ \"data\": { \"message\": \"Sample message for FireOS endpoints\" } }",
  "BAIDU": "{\"title\":\"Sample message title\",\"description\":\"Sample message for Baidu endpoints\"}",
  "MPNS": "<?xml version=\"1.0\" encoding=\"utf-8\"?><wp:Notification xmlns:wp=\"WPNotification\"><wp:Tile><wp:Count>ENTER COUNT</wp:Count><wp:Title>Sample message for Windows Phone 7+ endpoints</wp:Title></wp:Tile></wp:Notification>",
  "WNS": "<badge version=\"1\" value=\"42\"/>"
}
{
“默认值”:“示例回退消息”,
“电子邮件”:“电子邮件端点的示例消息”,
“sqs”:“Amazon sqs端点的示例消息”,
“lambda”:“{\“AlarmName\”:\“PublishedAlarm\”,“NewStateValue\”:“OK\”,“NewStateReason\”:“此报警已发布”,
“http”:“http端点的示例消息”,
“https”:“https端点的示例消息”,
“sms”:“sms端点的示例消息”,
“firehose”:“Amazon Kinesis数据firehose端点的示例消息”,
“APNS”:“{\“aps\”:{\“警报\”:\“iOS端点的示例消息\”}”,
“APNS\U沙盒”:“{\“aps\”:{\“警报\”:“iOS开发端点的示例消息\”}”,
“APNS\U VOIP”:“{\”aps\“:{\”警报\“:\”苹果VOIP端点示例消息\“}}”,
“APNS\U VOIP\U沙盒”:“{\“aps\”:{\“警报\:\”Apple VOIP开发端点的示例消息\“}”,
“MACOS”:“{\'aps\':{\'alert\':\”MACOS端点示例消息\“}}”,
“MACOS_沙盒”:“{\“aps\”:{\“警报\”:“MACOS开发端点的示例消息\”}”,
“GCM”:“{\”数据\“:{\”消息\“:\”Android端点示例消息\“}}”,
“ADM”:“{\”数据\“:{\”消息\“:\”FireOS端点示例消息\“}}”,
“百度”:“{\”标题“:\”示例消息标题“,\”说明“:\”百度端点示例消息\“}”,
“MPNS”:“输入Windows Phone 7+端点的COUNTSample消息”,
“WNS”:”
}
什么都没用。我还订阅了一个主题的电子邮件地址,我收到的电子邮件没有任何问题


如何从SNS模拟lambda事件模板中给出的测试事件?

当您使用SNS发送普通json消息时,它将以以下格式发送给lambda:

'Message': '{\n  "AlarmName": "PublishedAlarm",\n  "NewStateValue": "OK",\n  "NewStateReason": "This alarm is published"\n}'
您可以使用“
literal\u eval
方法对其进行解析:

import ast

#...
#...

def lambda_handler(event, context):
    logger.info("Event: " + str(event))
    message = event['Records'][0]['Sns']['Message']
    logger.info("Message: " + str(message))

    message = ast.literal_eval(event['Records'][0]['Sns']['Message'])

    alarm_name = message['AlarmName']
    new_state = message['NewStateValue']
    reason = message['NewStateReason']

#...
#...

当您使用SNS发送普通json消息时,它将以以下格式发送给lambda:

'Message': '{\n  "AlarmName": "PublishedAlarm",\n  "NewStateValue": "OK",\n  "NewStateReason": "This alarm is published"\n}'
您可以使用“
literal\u eval
方法对其进行解析:

import ast

#...
#...

def lambda_handler(event, context):
    logger.info("Event: " + str(event))
    message = event['Records'][0]['Sns']['Message']
    logger.info("Message: " + str(message))

    message = ast.literal_eval(event['Records'][0]['Sns']['Message'])

    alarm_name = message['AlarmName']
    new_state = message['NewStateValue']
    reason = message['NewStateReason']

#...
#...

这件事进展如何?仍然存在吗?@Marcin我使用了
json
而不是你建议的
ast.literal\u eval
。但是是的,在lambda处理程序中解析消息是有效的。谢谢这件事进展如何?仍然存在吗?@Marcin我使用了
json
而不是你建议的
ast.literal\u eval
。但是是的,在lambda处理程序中解析消息是有效的。谢谢