AWS Lambda函数在S3上传上触发SNS主题

时间:2018-06-22 16:29:57

标签: python amazon-web-services amazon-s3 aws-lambda amazon-sns

我对SNS和Lambda相当陌生。我已经成功创建了一个SNS主题,并且能够发送短信。上传文件时,我确实设置了S3事件。但是,我想更改该消息的文本,因此从应该向SNS主题发送消息的蓝图创建了Lambda函数。

这是设计器的屏幕截图

Here is a screenshot of the Designer

这是我正在使用的蓝图代码:

from __future__ import print_function

import json
import urllib
import boto3

print('Loading message function...')


    def send_to_sns(message, context):

        # This function receives JSON input with three fields: the ARN of an SNS topic,
        # a string with the subject of the message, and a string with the body of the message.
        # The message is then sent to the SNS topic.
        #
        # Example:
        #   {
        #       "topic": "arn:aws:sns:REGION:123456789012:MySNSTopic",
        #       "subject": "This is the subject of the message.",
        #       "message": "This is the body of the message."
        #   }

        sns = boto3.client('sns')
        sns.publish(
            TopicArn=message['arn:aws:sns:MySNS_ARN'],
            Subject=message['File upload'],
            Message=message['Files uploaded successfully']
        )

        return ('Sent a message to an Amazon SNS topic.')

在测试Lamda函数时,出现以下错误:

Response:
{
  "stackTrace": [
    [
      "/var/task/lambda_function.py",
      25,
      "send_to_sns",
      "TopicArn=message['arn:aws:sns:MySNS_ARN'],"
    ]
  ],
  "errorType": "KeyError",
  "errorMessage": "'arn:aws:sns:MySNS_ARN'"
}

Request ID:
"7253aa4c-7635-11e8-b06b-838cbbafa9df"

Function Logs:
START RequestId: 7253aa4c-7635-11e8-b06b-838cbbafa9df Version: $LATEST
'arn:aws:sns:MySNS_ARN': KeyError
Traceback (most recent call last):
  File "/var/task/lambda_function.py", line 25, in send_to_sns
    TopicArn=message['arn:aws:sns:MySNS_ARN'],
KeyError: 'arn:aws:sns:MySNS_ARN'

END RequestId: 7253aa4c-7635-11e8-b06b-838cbbafa9df
REPORT RequestId: 7253aa4c-7635-11e8-b06b-838cbbafa9df  Duration: 550.00 ms Billed Duration: 600 ms     Memory Size: 128 MB Max Memory Used: 30 MB  

我不确定我是否理解出了什么问题,将不胜感激!谢谢!

2 个答案:

答案 0 :(得分:1)

您的代码似乎来自于旧的AWS Step Functions手册,与您的用例无关。

Amazon S3发送事件通知时,它包含以下信息(来自Event Message Structure - Amazon Simple Storage Service):

{  
   "Records":[  
      {  
         "eventVersion":"2.0",
         "eventSource":"aws:s3",
         "awsRegion":"us-east-1",
         "eventTime":The time, in ISO-8601 format, for example, 1970-01-01T00:00:00.000Z, when S3 finished processing the request,
         "eventName":"event-type",
         "userIdentity":{  
            "principalId":"Amazon-customer-ID-of-the-user-who-caused-the-event"
         },
         "requestParameters":{  
            "sourceIPAddress":"ip-address-where-request-came-from"
         },
         "responseElements":{  
            "x-amz-request-id":"Amazon S3 generated request ID",
            "x-amz-id-2":"Amazon S3 host that processed the request"
         },
         "s3":{  
            "s3SchemaVersion":"1.0",
            "configurationId":"ID found in the bucket notification configuration",
            "bucket":{  
               "name":"bucket-name",
               "ownerIdentity":{  
                  "principalId":"Amazon-customer-ID-of-the-bucket-owner"
               },
               "arn":"bucket-ARN"
            },
            "object":{  
               "key":"object-key",
               "size":object-size,
               "eTag":"object eTag",
               "versionId":"object version if bucket is versioning-enabled, otherwise null",
               "sequencer": "a string representation of a hexadecimal value used to determine event sequence, 
                   only used with PUTs and DELETEs"            
            }
         }
      },
      {
          // Additional events
      }
   ]
}

然后,您可以访问有关触发事件的文件的信息。例如,此 Lambda函数将消息发送到SNS队列

import boto3

def lambda_handler(event, context):

    bucket = event['Records'][0]['s3']['bucket']['name']
    key =    event['Records'][0]['s3']['object']['key']

    sns = boto3.client('sns')
    sns.publish(
        TopicArn = 'arn:aws:sns:ap-southeast-2:123456789012:stack',
        Subject = 'File uploaded: ' + key,
        Message = 'File was uploaded to bucket: ' + bucket
    )

但是,由于您要发送 SMS ,因此实际上可以绕过SNS主题的需要,而直接发送SMS

import boto3

def lambda_handler(event, context):

    bucket = event['Records'][0]['s3']['bucket']['name']
    key =    event['Records'][0]['s3']['object']['key']

    sns = boto3.client('sns')
    sns.publish(
        Message = 'File ' + key + ' was uploaded to ' + bucket,
        PhoneNumber = "+14155551234"
    )

编写此类代码的最简单方法是使用AWS Lambda中的 Test 功能。它可以模拟来自各种来源(例如Amazon S3)的消息。实际上,这就是我测试上述功能的方式-我编写了代码,并使用Test函数测试了代码,而这一切都没有离开Lambda控制台。

答案 1 :(得分:0)

我发现一个有效的NodeJs示例:

console.log('Loading function');

var AWS = require('aws-sdk');  
AWS.config.region = 'us-east-1';

exports.handler = function(event, context) {  
    console.log("\n\nLoading handler\n\n");
    var sns = new AWS.SNS();

    sns.publish({
        Message: 'File(s) uploaded successfully',
        TopicArn: 'arn:aws:sns:_my_ARN'
    }, function(err, data) {
        if (err) {
            console.log(err.stack);
            return;
        }
        console.log('push sent');
        console.log(data);
        context.done(null, 'Function Finished!');  
    });
};