Home > Net >  AWS CDK: Sending and SMS message once a lambda function detects changes in URL
AWS CDK: Sending and SMS message once a lambda function detects changes in URL

Time:09-22

I have a CDK app that uses a lambda function to check for changes to the content of a website. I want that SMS to be sent to a mobile number if the change is detected.

In my AWS CDK project, I created my stack, that builds the lambda function and the SNS

file: lib/lambda_query_website_aws_cdk-stack.ts

import * as cdk from '@aws-cdk/core';
import events = require('@aws-cdk/aws-events');
import targets = require('@aws-cdk/aws-events-targets');
import lambda = require('@aws-cdk/aws-lambda');
import * as sns from '@aws-cdk/aws-sns';
import * as subscriptions from '@aws-cdk/aws-sns-subscriptions';



import fs = require('fs')


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

    const lambdaFn = new lambda.Function(this, 'Singleton', {
      code: new lambda.InlineCode(fs.readFileSync('lambda-handler.py', { encoding: 'utf-8' })),
      handler: 'index.main',
      timeout: cdk.Duration.seconds(300),
      runtime: lambda.Runtime.PYTHON_3_6,
      environment: {
        'PREV_RESPONSE': ''
      }

    });

    // Runs every 30 minutes from 6:00 to 23:00
    // See https://docs.aws.amazon.com/lambda/latest/dg/tutorial-scheduled-events-schedule-expressions.html
    const rule = new events.Rule(this, 'Rule', {
      schedule: events.Schedule.expression('cron(0/30 6-23 * * ? *)')
    });
    
    rule.addTarget(new targets.LambdaFunction(lambdaFn));

    // Create an SNS Topic.
    // The producer or publisher is the lambda function ??
    //The subscriber or consumer is the sms phone number  15551231234
    const myTopic = new sns.Topic(this, 'MyTopic');
    myTopic.addSubscription(new subscriptions.SmsSubscription(' 15551231234'));

  }
}

Here is the lambda function

file lambda-handler.py

import os
import urllib.request

url= "https://mywebsite.com"

def main(event, context):
    print("I'm running!")
    response = urllib.request.urlopen(url)
    response_text = response.read()
    html = response_text.decode('utf-8')

    if os.getenv('PREV_RESPONSE',default="HTML_BODY") != html:
        print("There was a change on the web site")
        os.environ['PREV_RESPONSE'] = HTML
        # TODO:
        # Send the SMS notifying about the change

How do I make the SNS service know that the message needs to be sent?

BR

CodePudding user response:

Try something like this

export class LambdaQueryWebsiteAwsCdkStack extends cdk.Stack {
    constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
      super(scope, id, props);
  
      const myTopic = new sns.Topic(this, 'MyTopic');
      myTopic.addSubscription(new subscriptions.SmsSubscription(' 15551231234'));

      const lambdaFn = new lambda.Function(this, 'Singleton', {
        code: new lambda.InlineCode(fs.readFileSync('lambda-handler.py', { encoding: 'utf-8' })),
        handler: 'index.main',
        timeout: cdk.Duration.seconds(300),
        runtime: lambda.Runtime.PYTHON_3_6,
        environment: {
          'PREV_RESPONSE': '',
          'SNS_TOPIC_ARN': myTopic.topicArn  // Include topic ARN as environment variable
        }
      });
      
      myTopic.grantPublish(lambdaFn.role)  // Grant lambda function permission to publish to topic
  
      // Runs every 30 minutes from 6:00 to 23:00
      // See https://docs.aws.amazon.com/lambda/latest/dg/tutorial-scheduled-events-schedule-expressions.html
      const rule = new events.Rule(this, 'Rule', {
        schedule: events.Schedule.expression('cron(0/30 6-23 * * ? *)')
      });

      rule.addTarget(new targets.LambdaFunction(lambdaFn));
    }
  }

And in your python function

import os
import boto3
import urllib.request

url= "https://mywebsite.com"
client = boto3.client("sns")

SNS_TOPIC_ARN = os.getenv("SNS_TOPIC_ARN")

def main(event, context):
    print("I'm running!")
    response = urllib.request.urlopen(url)
    response_text = response.read()
    html = response_text.decode('utf-8')

    if os.getenv('PREV_RESPONSE',default="HTML_BODY") != html:
        os.environ['PREV_RESPONSE'] = html

        response = client.publish(
            TopicArn=SNS_TOPIC_ARN,
            Message='There was a change on the web site',
            Subject='Some change!'
        )
  • Related