A Python job executed by Cloud Run and scheduled by Cloud Scheduler at the end of every month) which retrieves from Gmail the latest receipt of Spotify Family and notifies all family members within a Facebook Messenger group.
- Services:
- Gmail + Facebook account
- GCP account
- Authentification:
- Enabled GCP APIs:
- Cloud Run Admin API
- Cloud Scheduler API
- Secret Manager API
- Compute Engine API
- Gmail API
- Cloud Logging API
- Eventarc API
- Cloud Resource Manager API
- Identity and Access Management (IAM) API
- Cloud Billing API
- OAuth 2.0 Client IDs generated
- Enabled GCP APIs:
- Tools:
- Poetry >= 1.1.10
- Python >= 3.7.2
- Docker latest
- Terraform 1.0.11
With Terminal:
git clone [email protected]:doanhat/cron-send-receipt-spotify.git
cd cron-send-receipt-spotify/
With Pycharm:
Open
Pycharm
->GET FROM VCS
-> Copy and paste the git url in the fieldURL
Open Terminal (system or Pycharm), within the repository folder:
poetry install # install virtual environment and python packages
poetry export -f requirements.txt --output requirements.txt --without-hashes # generate requirements.txt
poetry.lock
file and retry the above command
-
Set up authentification:
- Google API credentials for Gmail readonly access:
- Create a new project in
Google Cloud Console
, for examplesend-facture-spotify
- In
APIs and Services
, enable Gmail API - In
APIs and Services/OAuth Consent Screen
, enter application name and add your email toTest users
- In
APIs and Services/Credentials
, create aOAuth 2.0 Client ID
and download the JSON file, save it toGoogle Secret Manager
asgmail_credentials
- Create a new project in
- Set up GCP service account:
- https://cloud.google.com/docs/authentication/getting-started
- Grant roles for the service account:
Cloud Run Admin
,Cloud Scheduler Admin
,Service Account user
,Secret Manager Accessor and Version Adder
- Set up remote credentials, perform these additional steps:
- In
Google Cloud Console/APIs and Services/Credentials
, add aService Account
for the project if not yet created - In
Google Cloud Console/Security/Secret Manager
, add this secret :- name:
facebook_login
, value:{ "FB_USER_EMAIL_ADDRESS":<fb_email>, "FB_USER_PASSWORD":<fb_password> }
- At this moment, two secrets have been created, which are
facebook_login
andgmail_credentials
, after the first run of Cloud Run, there will be alsofacebook_session
andgmail_token
generated, which will be reused for the next run
- name:
- In
- Google API credentials for Gmail readonly access:
-
Build image Docker:
- In Terminal (system or Pycharm), within the repository folder:
docker build -t cron-send-receipt-spotify:<version> -f docker/gcp_cloud_run/Dockerfile .
docker tag cron-send-receipt-spotify:<version> <gcp_region>/<gcp_project_name>/cron-send-receipt-spotify
docker push <gcp_region>/<gcp_project_name>/cron-send-receipt-spotify
- Deploy GCP resources with terraform:
-
Define environment variables in
terraform/main.tf
, inlocals
:locals { service_account = "service-send-facture-spotify@send-facture-spotify.iam.gserviceaccount.com" thread_id = "<messenger_group_id>" # messenger group id project_id = "send-facture-spotify" cre_secret_id = "gmail_credentials" tok_secret_id = "gmail_token" ses_secret_id = "facebook_session" log_secret_id = "facebook_login" gcp_region = "europe-west1" imap_url = "imap.gmail.com" ... }
ℹ️
<messenger_group_id>
example:6947468915279299
is the id of https://www.facebook.com/messages/t/6947468915279299 -
Verify the job
schedule
:resource "google_cloud_scheduler_job" "scheduler-send-receipt-spotify" { name = "monthly-report-spotify-receipt" description = "It will send monthly receipt to messenger group" schedule = "59 10 28-31 * *" time_zone = "CET" http_target { http_method = "GET" uri = "${google_cloud_run_service.run-send-receipt-spotify.status[0].url}/?sender=${local.email_sender}&subject=${local.email_subject}&key_words=${local.email_key_words}" oidc_token { service_account_email = local.service_account } } }
which means: At 10:59 on every day-of-month from 28 through 31, run the script
ℹ️ Check out crontab.guru for more cron schedule expressions
-
In Terminal (system or Pycharm), within the repository folder:
⚠️ ReplacePROJECT_NUMBER
with current gcp project number
make terraform-init
make terraform-plan
make terraform-apply
There's always enough rooms for improvement, we can take advantage of this project to learn :
- Using Airflow to schedule more complicated tasks
- Using CI/CD for more reliable deployment