Amazon’s Simple Notification Service – SNS – is more commonly associated with it’s primary role as a pub/sub service to publish messages to topics and define subscriptions against those topics. It is also possible to use SNS as a very low cost option to send text messages. This post will focus on how to do that using a Python Lambda with the the boto3 SDK – this is very simple to use as we will demonstrate. We will define a cloudformation template for our lambda – just a design philosophy this blog adheres to for even the simplest components. And this lambda can be used as a base for more complex serverless systems.
Some points to note before we dive in, AWS allows you to get started with testing out text messaging with SNS very quickly, in fact with no setup at all! Unlike if you were to use some other SMS provider like Twilio. However, it will be in a sandbox state until you request AWS to move it to a production state. While in a sandbox state, you can only send texts to verified numbers – which can be added in the SNS console.
The other thing to note is that you will not get a dedicated “From” number or short code – AWS will send your texts using random short codes. Dedicated “From” numbers and short codes that can be uniquely identified by your recipients have to be requested from Amazon Pinpoint. We will not cover this for this tutorial which will be only to demonstrate how to use the boto3 SDK to send messages.
Setting up the Cloudformation yaml for the Lambda
This topic is covered in more detail in this post. We are going to define the cloudformation template for our Lambda first – skip ahead to the next section for the Python code but note that IAM permissions to use SNS need to be setup for the Lambda to be able to send SMS texts via that service. We are using a predefined policy granting full SNS access. Specific applications may require more restrictive access, but we are going with the full IAM SNS permissions for this guide. This is all defined as shown below.
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: Sending SMS Texts with SNS & Lambda Resources: SNSLambda: Type: AWS::Serverless::Function Properties: Architectures: - arm64 Runtime: python3.9 CodeUri: ./sns-lambda/ Handler: sns-lambda.event_handler Description: Send sms text messages via SNS using boto3 FunctionName: sns-lambda Policies: - AmazonSNSFullAccess
Coding the Lambda with boto3
The boto3 SDK is Amazon’s python library for using all of it’s various services. It is up to date and actually well documented if a bit difficult to easily read through. Lets code our lambda to accept a “to” destination number and a message which we will send using sns.
import boto3 from botocore.exceptions import ClientError sns = boto3.resource('sns') def event_handler(event, context): to_phone_number = event("to_phone_number") sms_text_message = event("sms_text_message") try: response = sns.publish( PhoneNumber=to_phone_number, Message=sms_text_message ) message_id = response["MessageId"] print(message_id) except ClientError as error: print(error.response["Error"]["Code"]) print(error.response["Error"]["Message"])
As easy as that. The only reminder as mentioned earlier, if your AWS account is in a sandbox state, ensure you only test with verified numbers.
This is a simple lambda but can be used as the basis for more complex plumbing with notifications and saving records in a dynamo table and all that stuff. For an example of a serverless text messaging application using AppsSync, check out this post. The main difference is the example uses Twilio – which can be swapped out with SNS – the basis for which is the code and yaml template defined above.