Hey Coders! Today, I am excited to share a project that combines the power of AWS Lambda, Amazon SNS, and an external API to create a robust NBA Game Notifications Alert System. This system fetches real-time NBA game data and sends notifications about the games' status, scores, and other details directly to your email or any other subscribed endpoint.
In this blog, I will walk you through the entire process of setting up this notification system, from cloning the repository to deploying the Lambda function and configuring the necessary AWS services. Whether you are a sports enthusiast looking to stay updated with the latest NBA games or a developer interested in learning more about AWS services, this project has something for you.
Let's dive in and explore how to build this exciting notification system step-by-step!
Table of Contents
Prerequisites
- AWS Account
- Free Subscription in NBA API
Overview
The NBA Game Notifications Alert System fetches NBA game data from an external API and sends notifications about the games' status, scores, and other details via Amazon SNS.
Architecture Diagram
Setup
-
Clone the repository:
git clone <repository-url> cd Game-Notification-with-AWS-Lambda-Amazon-SNS-and-AmazonBridge
-
Create SNS Topic and Subscriber:
- In AWS, go to SNS and create a new topic named
gd_topic
. - Create a new subscription, choose email as the protocol, and select the ARN of the
gd_topic
.
- In AWS, go to SNS and create a new topic named
-
Create IAM Policy and Role:
-
In AWS, go to IAM and create a new policy with the following permissions:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "sns:Publish", "Resource": "arn:aws:sns:REGION:ACCOUNT_ID:TOPIC" } ] }
-
- Create a new role, select AWS Services, and assign the following policies:
- The SNS publish policy created above.
- Lambda Basic Execution Role.
- Name the role and create it.
-
Create Lambda Function:
- In AWS Lambda, create a new function from scratch.
- Enter a function name and assign the previously created role.
- Copy the code from
src/lambda_function.py
into the function. -
Add the following environment variables:
NBA_API_KEY=Your_API_Key SNS_TOPIC_ARN=Your_SNS_Topic_ARN
- Create the function.
-
Deploy and Test Your Lambda Function:
- Open the Lambda function and create a new test event.
- Run the function and check the logs in CloudWatch for any errors.
Lambda Function
The main logic of the project is implemented in the lambda_function.py
file located in the src directory. Here is a brief overview of the key components:
-
Imports:
import os import json import urllib.request import boto3 from datetime import datetime, timedelta, timezone
-
Function to Format Game Data:
def format_game_data(game): # Get environment variables api_key = os.getenv("NBA_API_KEY") sns_topic_arn = os.getenv("SNS_TOPIC_ARN") sns_client = boto3.client("sns") # Adjust for Central Time (UTC-6) utc_now = datetime.now(timezone.utc) central_time = utc_now - timedelta(hours=6) # Central Time is UTC-6 today_date = central_time.strftime("%Y-%m-%d") print(f"Fetching games for date: {today_date}") # Fetch data from the API api_url = f"https://api.sportsdata.io/v3/nba/scores/json/GamesByDate/{today_date}?key={api_key}" print(today_date) try: with urllib.request.urlopen(api_url) as response: data = json.loads(response.read().decode()) print(json.dumps(data, indent=4)) # Debugging: log the raw data except Exception as e: print(f"Error fetching data from API: {e}") return {"statusCode": 500, "body": "Error fetching data"} # Include all games (final, in-progress, and scheduled) messages = [format_game_data(game) for game in data] final_message = "\n---\n".join(messages) if messages else "No games available for today." # Publish to SNS try: sns_client.publish( TopicArn=sns_topic_arn, Message=final_message, Subject="NBA Game Updates" ) print("Message published to SNS successfully.") except Exception as e: print(f"Error publishing to SNS: {e}") return {"statusCode": 500, "body": "Error publishing to SNS"} return {"statusCode": 200, "body": "Data processed and sent to SNS"}
-
Lambda Handler Function:
def lambda_handler(event, context): status = game.get("Status", "Unknown") away_team = game.get("AwayTeam", "Unknown") home_team = game.get("HomeTeam", "Unknown") final_score = f"{game.get('AwayTeamScore', 'N/A')}-{game.get('HomeTeamScore', 'N/A')}" start_time = game.get("DateTime", "Unknown") channel = game.get("Channel", "Unknown") # Format quarters quarters = game.get("Quarters", []) quarter_scores = ', '.join([f"Q{q['Number']}: {q.get('AwayScore', 'N/A')}-{q.get('HomeScore', 'N/A')}" for q in quarters]) if status == "Final": return ( f"Game Status: {status}\n" f"{away_team} vs {home_team}\n" f"Final Score: {final_score}\n" f"Start Time: {start_time}\n" f"Channel: {channel}\n" f"Quarter Scores: {quarter_scores}\n" ) elif status == "InProgress": last_play = game.get("LastPlay", "N/A") return ( f"Game Status: {status}\n" f"{away_team} vs {home_team}\n" f"Current Score: {final_score}\n" f"Last Play: {last_play}\n" f"Channel: {channel}\n" ) elif status == "Scheduled": return ( f"Game Status: {status}\n" f"{away_team} vs {home_team}\n" f"Start Time: {start_time}\n" f"Channel: {channel}\n" ) else: return ( f"Game Status: {status}\n" f"{away_team} vs {home_team}\n" f"Details are unavailable at the moment.\n" )
The lambda_handler
function performs the following steps:
- Retrieves environment variables.
- Adjusts the current time to Central Time (UTC-6).
- Fetches NBA game data from the external API.
- Formats the game data.
- Publishes the formatted data to the specified SNS topic.
Top comments (0)