Quantcast
Channel: CodeSection,代码区,Python开发技术文章_教程 - CodeSec
Viewing all articles
Browse latest Browse all 9596

Using Twilio to Build a Serverless SMS Raffle in Python

$
0
0

Using Twilio to Build a Serverless SMS Raffle in Python

If you’re like me, you drool just a little bit over serverless architectures. When Rackspace and AWS EC2 made cloud-based computing a mainstream reality, that was awesome enough. But you still had to spin up and maintain your own virtual servers.

With the introduction of things likeTwilio Functionsor Lambda for truly serverless function execution, DynamoDB for cached state, and API Gateway for click-and-deploy routing―just to name a few―it’s become deliciously easy to build and deploy powerful (and fun) services in minutes. Seriously, the IoT possibilities are endless!

With that in mind, let’s build something fun with python a Serverless SMS Raffle . What if users could text a word to a phone number and were entered in to a raffle? Then when we were ready to choose a winner, we could execute a Lambda to choose some number of winners at random and close the raffle?


Using Twilio to Build a Serverless SMS Raffle in Python

To do this, we’re going to need accounts on two platforms I’ve already mentioned:Twilioand AWS . Don’t worry, they’re both free, and when all is said and done, running this raffle will cost us just pennies.

So, let’s get started. First things first, we need to setup an endpoint in AWS for Twilio to use when a text is received. We’ll setup this endpoint using API Gateway, which will in turn execute a Lambda function that process entries into the raffle. Easy peasy.

Configure an AWS Role

AWS Roles give us a set of permissions to work with. Before we can do anything, we need to create a Role that allows our raffle Lambdas to create logs in CloudWatch and manage tables in DynamoDB.

In the AWS Console, under "My Security Credentials", create a new Role . Choose the "Lambda" service, then create a new Policy.

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents", "dynamodb:CreateTable", "dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:UpdateItem", "dynamodb:DescribeTable", "dynamodb:GetShardIterator", "dynamodb:GetRecords", "dynamodb:ListStreams", "dynamodb:Query", "dynamodb:Scan" ], "Resource": "*" } ] }

Name this new Policy "AWSLambdaDynamo", then attach it to your new Role and name it the same.

Great, now let's make some Lambdas using this Role!

Create the AWS Lambda Functions

Actually, before we create our Lambdas, let's give them a place to store the raffle data. Create a DynamoDB table with a partition key of PartitionKey .


Using Twilio to Build a Serverless SMS Raffle in Python

Alright, now let's make two Lambdas. The first one we'll attach to an API Gateway for receiving an inbound text message―this one will let people enter the raffle and manage all the housekeeping there. The second one will be a Lambda we manually execute―it will close the raffle and choose the winners.

Inbound Message Lambda

Go ahead and create a new Lambda function from scratch , naming it "Raffle_POST" and choosing "Python 3.6" for the runtime. When inbound text messages are sent to our API Gateway (which we'll setup next), they will be processed by this Lambda, and it'll store the sender's phone number in our DyanmoDB table.


Using Twilio to Build a Serverless SMS Raffle in Python

Before we plop a bunch of code in there, let's define some environment variables for the function.

SUPER_SECRET_PASSPHRASE (some phrase people must text in order to be entered in to the raffle) BANNED_NUMBERS (JSON list of phone numbers formatted ["+15555555555","+15555555556"] ) DYNAMODB_REGION (like us-east-1 ) DYNAMODB_ENDPOINT (like https://dynamodb.us-east-1.amazonaws.com ) DYNAMODB_TABLE

Now that we have our environment variables defined, let's write some code in the Lambda.

First though: some housekeeping. Let's declare the imports we'll need and bring in those environment variables for easy access.

import os import json import logging import boto3 from urllib.parse import parse_qs SUPER_SECRET_PASSPHRASE = os.environ.get("SUPER_SECRET_PASSPHRASE", "Ahoy") BANNED_NUMBERS = json.loads(os.environ.get("BANNED_NUMBERS", "[]")) DYNAMODB_REGION = os.environ.get("DYNAMODB_REGION") DYNAMODB_ENDPOINT = os.environ.get("DYNAMODB_ENDPOINT") DYNAMODB_TABLE = os.environ.get("DYNAMODB_TABLE") logger = logging.getLogger() logger.setLevel(logging.INFO) dynamodb = boto3.resource("dynamodb", region_name=DYNAMODB_REGION, endpoint_url=DYNAMODB_ENDPOINT) table = dynamodb.Table(DYNAMODB_TABLE) def lambda_handler(event, context): # TODO implement return { 'statusCode': 200, 'body': json.dumps('Hello from Lambda!') }

Awesome. Now let's write some helper functions to determine if a raffle is closed (we know it's closed if any rows in the table have been marked a winner), and determine if the person texting us is Karen ― Karen is, of course, banned from entering the raffle.

def _is_raffle_closed(table): winner_response = table.scan( FilterExpression=boto3.dynamodb.conditions.Attr("Winner").exists() ) return winner_response["Count"] > 0 def _is_karen(phone_number): return phone_number in BANNED_NUMBERS

Let's also write a helper function that conveniently builds a properTwiML response for us.

Why does this matter? Because whatever response our Lambda gives will be passed back to Twilio. If it's validTwiML XML, we can task Twilio with an action in our response, in this case, sending a text message back to the sender.

def _get_response(msg): xml_response = "<?xml version='1.0' encoding='UTF-8'?><Response><Message>{}</Message></Response>".format(msg) logger.info("XML response: {}".format(xml_response)) return {"body": xml_response}

Great. Now we're ready to write the lambda_handler .

We need to check the incoming text message for the super secret word before entering the sender in to the raffle. Then we'll respond with TwiML to let the sender know they were successfully entered (or shame them accordingly, if they try entering multiple times. Or if they're Karen.).


Using Twilio to Build a Serverless SMS Raffle in Python

Viewing all articles
Browse latest Browse all 9596

Trending Articles