This repository contains the code for an AWS Lambda function that automatically updates a Spotify playlist based on the most recently listened-to tracks. The function is built and deployed using the AWS Serverless Application Model (SAM) and interacts with the Spotify API.
- Introduction
- Features
- Architecture
- Prerequisites
- Setup and Deployment
- Local Testing
- Project Structure
- Usage
- Troubleshooting
- Contributing
- License
This project automates the process of updating a Spotify playlist with the latest top tracks. It uses AWS Lambda for serverless execution and is scheduled to run every other day using Amazon EventBridge (formerly CloudWatch Events).
- Automated Playlist Updates: Refreshes your Spotify playlist with new tracks every other day.
- Serverless Architecture: Built using AWS Lambda and AWS SAM for scalable and cost-effective deployment.
- Secure Credential Management: Uses AWS Systems Manager Parameter Store (SecureString) to securely store and access Spotify API credentials at no additional cost.
- Configurable Schedule: The update frequency can be adjusted via the AWS SAM template.
- AWS Lambda Function: Executes the Python script to update the Spotify playlist.
- Amazon EventBridge: Triggers the Lambda function based on a specified cron schedule.
- AWS Systems Manager Parameter Store: Securely stores Spotify API credentials as a SecureString.
- Spotify API: The Lambda function interacts with Spotify's API to update the playlist.
- AWS Account: An active AWS account with permissions to create Lambda functions, EventBridge rules, and access Secrets Manager.
- AWS CLI: Installed and configured with your AWS credentials.
- AWS SAM CLI: Installed on your local machine. Install the AWS SAM CLI
- Docker: Installed and running for local testing. Get Docker
- Spotify Account: A Spotify account with the necessary permissions to create and modify playlists.
- Spotify Developer Application: Created in the Spotify Developer Dashboard to obtain API credentials.
git clone https://github.com/davidsmv/SpotifyUpdater.git
cd SpotifyUpdaterInstall the required Python packages:
pip install -r requirements.txtEnsure your AWS CLI is configured with the necessary credentials:
aws configure- AWS Access Key ID
- AWS Secret Access Key
- Default region name: e.g.,
us-east-1
You need to have the following Spotify API credentials:
SPOTIPY_CLIENT_IDSPOTIPY_CLIENT_SECRETSPOTIPY_REFRESH_TOKENSPOTIFY_PLAYLIST_ID
- Log in to the Spotify Developer Dashboard.
- Create a new application to obtain the Client ID and Client Secret.
- You can generate the
SPOTIPY_REFRESH_TOKENusing theapp/service/get_refresh_token.pyscript provided in this repository.
Create a SecureString parameter with a JSON payload containing the following key-value pairs:
- SPOTIPY_CLIENT_ID: Your Spotify Client ID.
- SPOTIPY_CLIENT_SECRET: Your Spotify Client Secret.
- SPOTIPY_REFRESH_TOKEN: Your Spotify Refresh Token.
- SPOTIFY_PLAYLIST_ID: The ID of the Spotify playlist you want to update.
AWS CLI Command to Create the Parameter:
aws ssm put-parameter \
--name /spotify/credentials \
--type SecureString \
--value '{"SPOTIPY_CLIENT_ID":"your-client-id","SPOTIPY_CLIENT_SECRET":"your-client-secret","SPOTIPY_REFRESH_TOKEN":"your-refresh-token","SPOTIFY_PLAYLIST_ID":"your-playlist-id"}' \
--region us-east-1Standard SecureString parameters are free (no per-parameter monthly fee, unlike Secrets Manager).
sam buildUse the guided deployment to configure parameters:
sam deploy --guidedDuring the guided deployment:
- Stack Name:
spotify-playlist-updater-stack(or your preferred name) - AWS Region:
us-east-1(ensure it matches where your secret is stored) - Parameter ParameterName:
/spotify/credentials(the name of your SSM parameter) - Confirm changes before deploy:
N - Allow SAM CLI IAM role creation:
Y - Save arguments to samconfig.toml:
Y
To test the function locally before deployment:
-
Create a Test Event File
Create
event.jsonwith the following content:{} -
Invoke the Function Locally
sam local invoke SpotifyUpdateFunction -e event.jsonEnsure Docker is running, as SAM CLI uses it to simulate the Lambda environment.
SpotifyUpdater/
├── app/
│ ├── handlers/
│ │ ├── spotify_handler.py
│ |── service/
│ │ │── get_refresh_token.py
│ │ │── spotify_updater.py
│ ├── __init__.py
├── template.yaml
├── requirements.txt
├── README.md
├── .gitignore
- app/: Contains the Lambda function code and dependencies.
- handlers/: Contains the
spotify_handler.pyscript with thelambda_handlerfuntion. - service/: Contains the
get_refresh_token.pyto get the refresh token neccesary to update the playlist andspotify_updater.pyclass that handles the entire process, called bylambda_handler - template.yaml: AWS SAM template defining the serverless application.
- requirements.txt: Lists Python dependencies.
- README.md: Project documentation.
- .gitignore: Specifies files and directories to ignore in version control.
Once deployed, the Lambda function will automatically run every other day at midnight (Bogota, Colombia time) to update your Spotify playlist.
-
Deployment Errors: Ensure your AWS credentials have the necessary permissions and that all parameters are correctly specified during deployment.
-
Access Denied Errors: Verify that the IAM role associated with your Lambda function has the required permissions to access AWS Systems Manager Parameter Store (
ssm:GetParameter). -
Invalid Spotify Credentials: Double-check the credentials stored in the SSM parameter for accuracy.
-
Function Not Triggering: Confirm that the EventBridge rule is correctly configured and enabled.
-
SpotifyOauthError: invalid_grant, Refresh token revoked: Spotify invalidated the stored refresh token (happens after long inactivity, revoking app access from your Spotify account, or regenerating the Client Secret). Fix it by generating a new refresh token and updating the parameter:- Activate the venv and run the token generator locally (it reuses a cached login if available, otherwise it opens a browser to authorize):
python app/service/get_refresh_token.py
- Copy the printed
Refresh Tokenvalue. - Update only the
SPOTIPY_REFRESH_TOKENfield in the SSM parameter, keeping the other fields intact:python -c " import boto3, json client = boto3.client('ssm', region_name='us-east-1') secret = json.loads(client.get_parameter(Name='/spotify/credentials', WithDecryption=True)['Parameter']['Value']) secret['SPOTIPY_REFRESH_TOKEN'] = 'PASTE_NEW_REFRESH_TOKEN_HERE' client.put_parameter(Name='/spotify/credentials', Value=json.dumps(secret), Type='SecureString', Overwrite=True) "
- (Optional) Update
SPOTIPY_REFRESH_TOKENin your local.envtoo, so it matches. - Verify it works by invoking the handler directly, without needing Docker/SAM:
A successful run returns
$env:PARAMETER_NAME='/spotify/credentials'; $env:AWS_REGION='us-east-1'; python -c "from app.handlers.spotify_handler import lambda_handler; print(lambda_handler({}, None))"
{'statusCode': 200, 'body': '"Playlist updated successfully!"'}. No redeploy is needed since the parameter is read at runtime.
- Activate the venv and run the token generator locally (it reuses a cached login if available, otherwise it opens a browser to authorize):
Contributions are welcome! Please open an issue or submit a pull request for any improvements or bug fixes.
This project is licensed under the MIT License.