Introduction
In today’s digital age, sports enthusiasts want real-time updates on their favorite teams and games. Leveraging AWS serverless services, we developed an automated Game Day Notification Solution that retrieves NBA game updates from the sportdata.io API, processes the data in AWS Lambda, and notifies users through Amazon SNS. The entire system is orchestrated using Amazon EventBridge to ensure scheduled execution. This article walks through the implementation details, key technologies, and the necessary configurations to build this solution.
Architecture Overview
The architecture of the Game Day Notification Solution is built using the following AWS services:
- AWS Lambda – Fetches NBA game data, processes it, and publishes notifications.
- Amazon SNS – Sends notifications to subscribed users via email.
- Amazon EventBridge – Triggers the Lambda function at scheduled intervals.
- AWS Identity and Access Management (IAM) – Provides necessary permissions for Lambda to interact with SNS and CloudWatch.
- Amazon CloudWatch Logs – Monitors Lambda invocations and logs execution details.
Step 1: Setting Up IAM Permissions
To allow the Lambda function to publish messages to Amazon SNS, we created an IAM policy with the following JSON configuration:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sns:Publish",
"Resource": "arn:aws:sns:us-east-1:012345678910:GameDay_Topic"
}
]
}
Additionally, we attached the AWSLambdaBasicExecutionRole managed policy to enable logging to CloudWatch and event processing via EventBridge.
Step 2: Creating the Lambda Function
The gameDayLambdaFunctionNotification Lambda function is implemented in Python 3.13 and retrieves NBA game updates using the sportdata.io API. For security best practices, the API key and SNS topic ARN are stored as environment variables instead of being hardcoded in the function.
Lambda Code Implementation
import os
import json
import urllib.request
import boto3
from datetime import datetime, timedelta, timezone
def format_game_data(game):
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"
)
def lambda_handler(event, context):
# 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 West Africa Time (UTC+1)
utc_now = datetime.now(timezone.utc)
west_africa_time = utc_now + timedelta(hours=1) # WAT is UTC+1
today_date = west_africa_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"}
Step 3: Configuring Amazon EventBridge
To automate the execution of our Lambda function, we set up an EventBridge Rule using a cron expression to specify the execution time.
Creating an EventBridge Rule (CLI Command)
aws events put-rule --schedule-expression "cron(0 18 * * ? *)" --name "GameDayScheduleRule"
Setting Lambda as the EventBridge Target
aws events put-targets --rule "GameDayScheduleRule" --targets "Id"="1","Arn"="arn:aws:lambda:us-east-1:012345678910:function:gameDayLambdaFunctionNotification"
This ensures that our Lambda function executes at the specified time, fetching game updates and sending notifications automatically.
Step 4: Monitoring Lambda with CloudWatch Logs
Amazon CloudWatch Logs allows us to monitor Lambda invocations, view execution logs, and troubleshoot any potential issues.
Viewing Lambda Logs
aws logs describe-log-groups
aws logs tail /aws/lambda/gameDayLambdaFunctionNotification --follow
This provides real-time logs and insights into the execution of the Lambda function.
Conclusion
By leveraging AWS serverless services, we successfully built an automated Game Day Notification Solution that provides real-time NBA game updates via email. This solution is cost-effective, scalable, and highly efficient, allowing sports enthusiasts to stay updated effortlessly.
Key Benefits of This Solution:
- Fully Automated: No manual intervention required once deployed.
- Cost-Effective: Uses AWS Lambda’s pay-as-you-go model.
- Secure: API keys stored as environment variables.
- Scalable: Can be extended to multiple sports or different notification channels.
- Monitorable: CloudWatch Logs enable tracking and troubleshooting.
With this approach, businesses and sports enthusiasts alike can enjoy seamless, real-time game notifications.
**_
NB: Future improvements may include integrating push notifications, chatbots, or a web dashboard for enhanced user interaction.
_**
Top comments (0)