Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS SNS - How to get subscriber lambda triggered by publisher lambda output

I have a lambda function which sends mail and returns the MessageID as output if the email was sent successfully, error message if it fails. Now I want to create an architecture where this returned email status will be saved in an SNS topic. There will be another Lambda function as subscriber which will be triggered by the Email status of the SNS topic.

Example: If the publisher Lambda returns MessageID, the subscriber Lambda will return "yes", "no" for error message. Is it possible to achieve? If not, what is the closest can I go?

What I have done so far

  1. Created an SNS Topic
  2. Created a subscriber Lambda function for the topic. Added trigger for the following SNS topic in the Lambda.
  3. Added SNS client in my existing Lambda which I want to use as publisher. This Lambda returns the MessageID if mail is sent successfully.
  4. I published a simple message to the specified SNS topic.

Here is code of subscriber function following the docs :

import json

def lambda_handler(event, context):
    # TODO implement
    return {
        # 'statusCode': 200,
        # 'body': json.dumps('Hello from Lambda!')
         message = json.loads(event['Records'][0]['Sns']['Message']) 
         print("JSON: " + json.dumps(message)) 
         return message
    }

My code for publishing message to SNS topic:

sns_client = boto3.client('sns', aws_access_key_id=AWS_ACCESS_KEY, aws_secret_access_key=AWS_SECRET_KEY, region_name=AWS_REGION)

sns_response = sns_client.publish(
        TopicArn='my-ARN',    
        Message='Hello World',    
    )
like image 640
Proteeti Prova Avatar asked Jul 24 '19 13:07

Proteeti Prova


1 Answers

I tried to reproduce your issue but could not. I used Javascript and Typescript but this should not be your problem.

Here is a CDK code to create your infrastructure :

import cdk = require('@aws-cdk/core');

import sns = require('@aws-cdk/aws-sns');
import subs = require('@aws-cdk/aws-sns-subscriptions');

import lambda = require('@aws-cdk/aws-lambda');

export class CdkStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    let fn = new lambda.Function(this, 'SODemoFunction', {
      runtime: lambda.Runtime.NODEJS_10_X,
      code: lambda.Code.asset('./src'),
      handler: 'index.handler'
    });

    const topic = new sns.Topic(this, 'SODemoTopic', {
      displayName: 'StackOverflow Demo'
    });
    topic.addSubscription(new subs.LambdaSubscription(fn));

  }
}

Here is the JS for the Lambda funtion


exports.handler =  async function(event, context) {
    console.log("EVENT: \n" + JSON.stringify(event, null, 2));
    return event['Records'][0]['Sns']['Message']; 
}

Here is how I am sending the message :

$ aws sns publish --topic-arn arn:aws:sns:eu-west-1:012345678912:CdkStack-SODemoTopicD9C6180 --message "hello world"
{
    "MessageId": "b73b0141-e7d1-50f0-93ae-54f44cf8bb78"
}

and here is what I see in cloudwatch log

2019-07-27T01:29:13.981Z cc56486b-0a8f-4e7a-a880-1e09d7631b98 INFO EVENT:
{
    "Records": [
        {
            "EventSource": "aws:sns",
            "EventVersion": "1.0",
            "EventSubscriptionArn": "arn:aws:sns:eu-west-1:012345678912:CdkStack-SODemoTopicD9C61805:22d228db-9c3c-488d-84a3-cbdbf5e9d112",
            "Sns": {
                "Type": "Notification",
                "MessageId": "b73b0141-e7d1-50f0-93ae-54f44cf8bb78",
                "TopicArn": "arn:aws:sns:eu-west-1:012345678912:CdkStack-SODemoTopicD9C61805",
                "Subject": null,
                "Message": "hello world",
                "Timestamp": "2019-07-27T01:29:13.862Z",
                "SignatureVersion": "1",
                "Signature": "Xqy8DYPWu+ZFw0hU23C78CTuFB3DblDSrY+vY44sDFMLmuZjM/kaQNvTmHGlLEFcdG3MBQQYWtMc/VQjVXONeIuJr4S336IENPTWylwSNSKHi5kAD93EmDiLl2y3jW2CdsDN9/QwQ5aJQrIkIp91VnWmCx03kUqgzhMdvQ0bsz64EUN6vMpKDZ4oJ6Ug0zTPUwyvcEneMzYkaFISakZZr1SHZYfHp7bfqZVyc2fjOIHhFIyePbMOsGYpQC8CGgD8d2Yekv0f1wYQKn5At4aHWQ29ObyjdsnbYCwlAuej47n1qVwh9li7XKFsRqyqE562Ul7OdLwA1t8tZdYbYh6zjA==",
                "SigningCertUrl": "https://sns.eu-west-1.amazonaws.com/SimpleNotificationService-6aad65c2f9911b05cd53efda11f913f9.pem",
                "UnsubscribeUrl": "https://sns.eu-west-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:eu-west-1:012345678912:CdkStack-SODemoTopicD9C61805:22d228db-9c3c-488d-84a3-cbdbf5e9d112",
                "MessageAttributes": {}
            }
        }
    ]
}

Can you try on your side ? CDK Doc is here https://docs.aws.amazon.com/cdk/latest/guide/getting_started.html

like image 186
Sébastien Stormacq Avatar answered Nov 01 '22 14:11

Sébastien Stormacq