├── .do └── deployment.template.yaml ├── .gitignore ├── README.md ├── packages └── sample │ └── emails │ ├── .env │ ├── __main__.py │ ├── build.sh │ └── requirements.txt └── project.yml /.do/deployment.template.yaml: -------------------------------------------------------------------------------- 1 | alerts: 2 | - rule: DEPLOYMENT_FAILED 3 | - rule: DOMAIN_FAILED 4 | functions: 5 | - github: 6 | branch: main 7 | deploy_on_push: true 8 | repo: digitalocean/sample-functions-python-sendgrid-email 9 | name: emails-api 10 | routes: 11 | - path: / 12 | source_dir: / 13 | name: emails -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | __pycache__/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Sample Function: Python "Sendgrid Emails" 2 | 3 | ## Introduction 4 | 5 | This repository contains a sample Sendgrid Email function written in Python. You are able to send an email using Sendgrid's API to email addresses with or without DMARCS. You can deploy it on DigitalOcean's App Platform as a Serverless Function component. 6 | Documentation is available at https://docs.digitalocean.com/products/functions. 7 | 8 | ### Requirements 9 | 10 | * You need a DigitalOcean account. If you don't already have one, you can sign up at [https://cloud.digitalocean.com/registrations/new](https://cloud.digitalocean.com/registrations/new). 11 | * You need a SendGrid account. If you don't already have one, you can sign up at https://signup.sendgrid.com/. 12 | * You need to create a SendGrid API key with Full Access to connect to your sendgrid account. You can learn more about it at https://docs.sendgrid.com/ui/account-and-settings/api-keys. 13 | * You need to add your `API_KEY` to the `.env` file to connect to the SendGrid API. 14 | * To send emails with valid email addresses, you have to set up sender authentication. You can learn more at https://docs.sendgrid.com/glossary/sender-authentication. 15 | * To send emails to email address with DMARCS, you have to set up domain authentication. You can learn more at https://docs.sendgrid.com/ui/account-and-settings/how-to-set-up-domain-authentication. 16 | * To deploy from the command line, you will need the [DigitalOcean `doctl` CLI](https://github.com/digitalocean/doctl/releases). 17 | 18 | 19 | ## Deploying the Function 20 | 21 | ```bash 22 | # clone this repo 23 | git clone git@github.com:digitalocean/sample-functions-python-sendgrid-email.git 24 | ``` 25 | 26 | ``` 27 | # deploy the project, using a remote build so that compiled executable matched runtime environment 28 | > doctl serverless deploy sample-functions-python-sendgrid-email --remote-build 29 | Deploying 'sample-functions-python-sendgrid-email' 30 | to namespace 'fn-...' 31 | on host 'https://faas-...' 32 | Submitted action 'emails' for remote building and deployment in runtime python:default (id: ...) 33 | 34 | Deployed functions ('doctl sls fn get --url' for URL): 35 | - sample/emails 36 | ``` 37 | 38 | ## Using the Function 39 | 40 | ```bash 41 | doctl serverless functions invoke sample/emails -p from:user@do.com to:user@gmail.com subject:Sammy content:Good Morning from Sammy. 42 | ``` 43 | ```json 44 | { 45 | "body": "email sent" 46 | } 47 | ``` 48 | 49 | ### To send an email using curl: 50 | ``` 51 | curl -X PUT -H 'Content-Type: application/json' {your-DO-app-url} -d '{"from":"user@do.com", "to":"user@gmail.com", "subject": "Sammy", "content":"Good Morning from Sammy!"}' 52 | ``` 53 | 54 | ### Learn More 55 | 56 | You can learn more about Functions and App Platform integration in [the official App Platform Documentation](https://www.digitalocean.com/docs/app-platform/). -------------------------------------------------------------------------------- /packages/sample/emails/.env: -------------------------------------------------------------------------------- 1 | API_KEY="" -------------------------------------------------------------------------------- /packages/sample/emails/__main__.py: -------------------------------------------------------------------------------- 1 | from http import HTTPStatus 2 | import os 3 | from sendgrid import SendGridAPIClient 4 | from sendgrid.helpers.mail import Mail 5 | 6 | def main(args): 7 | ''' 8 | Takes in the email address, subject, and message to send an email using SendGrid, 9 | returns a json response letting the user know if the email sent or failed to send. 10 | 11 | Parameters: 12 | args: Contains the from email address, to email address, subject and message to send 13 | 14 | Returns: 15 | json body: Json response if the email sent successfully or if an error happened 16 | ''' 17 | key = os.getenv('API_KEY') 18 | user_from = args.get("from") 19 | user_to = args.get("to") 20 | user_subject = args.get("subject") 21 | content = args.get("content") 22 | 23 | if not user_from: 24 | return { 25 | "statusCode" : HTTPStatus.BAD_REQUEST, 26 | "body" : "no user email provided" 27 | } 28 | if not user_to: 29 | return { 30 | "statusCode" : HTTPStatus.BAD_REQUEST, 31 | "body" : "no receiver email provided" 32 | } 33 | if not user_subject: 34 | return { 35 | "statusCode" : HTTPStatus.BAD_REQUEST, 36 | "body" : "no subject provided" 37 | } 38 | if not content: 39 | return { 40 | "statusCode" : HTTPStatus.BAD_REQUEST, 41 | "body" : "no content provided" 42 | } 43 | 44 | sg = SendGridAPIClient(key) 45 | message = Mail( 46 | from_email = user_from, 47 | to_emails = user_to, 48 | subject = user_subject, 49 | html_content = content) 50 | response = sg.send(message) 51 | 52 | if response.status_code != 202: 53 | return { 54 | "statusCode" : response.status_code, 55 | "body" : "email failed to send" 56 | } 57 | return { 58 | "statusCode" : HTTPStatus.ACCEPTED, 59 | "body" : "success" 60 | } -------------------------------------------------------------------------------- /packages/sample/emails/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | virtualenv virtualenv 6 | source virtualenv/bin/activate 7 | pip install -r requirements.txt 8 | deactivate -------------------------------------------------------------------------------- /packages/sample/emails/requirements.txt: -------------------------------------------------------------------------------- 1 | sendgrid==6.4.6 -------------------------------------------------------------------------------- /project.yml: -------------------------------------------------------------------------------- 1 | environment: 2 | API_KEY: ${API_KEY} 3 | packages: 4 | - name: sample 5 | actions: 6 | - name: emails 7 | runtime: 'python:default' --------------------------------------------------------------------------------