Welcome to the final day of our 12 Days of DigitalOcean series! We’ve come a long way, building an Email-Based Receipt Processing Service that extracts receipt details from Postmark using DigitalOcean’s GenAI Agent, securely stores attachments in DigitalOcean Spaces, and saves the extracted data in Google Sheets.
Today, we’ll add the final touch—sending confirmation emails back to the sender with the receipt details, attachment links, and a link to the Google Spreadsheet. This final step ties everything together, ensuring that users get immediate feedback that their receipts have been successfully processed.
By the end of this tutorial, you’ll know how to:
If you’d like to build along, we assume that you’ve followed Day 11: Save Receipt Data and Attachments in Google Sheets and already have:
If you’re just interested in learning how to integrate Resend for sending confirmation emails, you’ll need:
To send emails programmatically, we’ll use Resend, a developer-friendly API for sending transactional emails. It simplifies sending emails so you don’t have to wrestle with setting up an email server, managing SMTP configurations, or worrying about spam filters.
First, go to Resend and sign up for a free account. Once logged in, navigate to the API Keys section of the dashboard and generate a new API key.
Give your API key a descriptive name, like Receipt Processor App
, and set its permission to Full Access
.
Copy the API Key: Your API key will be shown only once—copy it and keep it safe. You’ll need it in the next step to authenticate your app with Resend.
Now that we have the Resend API key, let’s save it as an environment variable in DigitalOcean, just like we’ve been doing throughout this series.
For the Resend integration, we need to save two environment variables:
RESEND_API_KEY
: The API key you generated in Step 1, which authenticates your app with Resend.RESEND_EMAIL_FROM
: The sender email address you’ll use to send confirmation emails. This should be an address verified in your Resend account.To add these variables, follow these steps:
Head over to your DigitalOcean App Platform dashboard, find your Flask app, and navigate to the Settings tab. Under Environment Variables, add the two variables:
Key: RESEND_API_KEY
Key: RESEND_EMAIL_FROM
Save your changes to make the Resend API key available to your Flask app, which we will update next.
Next, we’ll install the Resend Python library to handle the API for us. It keeps your code clean and avoids dealing with raw HTTP requests. Run this in your terminal:
pip install resend
requirements.txt
Instead of editing requirements.txt
by hand, use pip freeze
to list all installed dependencies with exact versions. Run this:
pip freeze > requirements.txt
This updates requirements.txt
with everything your app needs, including resend
.
Now it’s time to add the logic for sending confirmation emails. Think of it like emailing a friend to let them know their package has arrived—only here, it’s for receipts.
We’ll write a send_confirmation_email
function that takes the recipient’s email, receipt details, attachment links, and Google Spreadsheet URL. Using Resend, it will format this into an email and send it. Here’s the function:
def send_confirmation_email(to_email, receipt_data, attachment_urls, spreadsheet_url):
"""
Send a confirmation email with receipt details and attachment URLs.
"""
email_from = os.getenv('RESEND_EMAIL_FROM') # Set this in your environment variables
subject = "Receipt Processed Successfully"
email_body = f"""
<h1>Receipt Confirmation</h1>
<p>Your receipt has been successfully processed. Here are the details:</p>
<ul>
<li><strong>Vendor:</strong> {receipt_data.get('vendor', 'N/A')}</li>
<li><strong>Amount:</strong> {receipt_data.get('amount', 'N/A')}</li>
<li><strong>Currency:</strong> {receipt_data.get('currency', 'N/A')}</li>
<li><strong>Date:</strong> {receipt_data.get('date', 'N/A')}</li>
</ul>
<p><strong>Attachments:</strong></p>
<ul>
{''.join(f'<li><a href="{url["url"]}">{url["file_name"]}</a></li>' for url in attachment_urls)}
</ul>
<p>You can view the processed data in the spreadsheet: <a href="{spreadsheet_url}">Google Spreadsheet</a></p>
"""
try:
resend.Emails.send({
"from": email_from,
"to": to_email,
"subject": subject,
"html": email_body
})
logging.info(f"Confirmation email sent to {to_email}.")
except Exception as e:
logging.error(f"Failed to send confirmation email: {e}")
To deploy the updated Flask app, follow the steps from Day 7: Building and Deploying the Email-Based Receipt Processor. Here’s a quick summary:
Push Your Updated Code to GitHub: After making the necessary changes to your Flask app, commit and push the updated code to GitHub. This will trigger an automatic deployment in DigitalOcean’s App Platform.
git add .
git commit -m "Add Resend integration for confirmation emails"
git push origin main
Monitor Deployment: You can track the progress in the Deployments section of your app’s dashboard.
Verify Your Deployment: After the deployment completes, navigate to your app’s public URL and test its functionality. You can also check the runtime logs in the dashboard to confirm that the app started successfully.
Check Runtime Logs: If something isn’t working as expected, use the Runtime Logs tab in the App Platform dashboard to debug runtime issues. Look for any errors related to the Resend API or other app components.
Now that your app is fully configured and ready, it’s time to test the entire workflow. We’ll ensure that the email body is processed, attachments are decoded and uploaded to DigitalOcean Spaces, receipt details and attachment URLs are saved in Google Sheets, and a confirmation email is sent to the sender.
Here’s how you can test step by step:
Send a Test Email: Send an email to Postmark with a text body and an attachment. If you’re unsure how to configure Postmark, check Day 8: Connecting Postmark to Your Flask App, where we walked through setting up Postmark to forward emails to your app.
Check Postmark Activity JSON: In the Postmark dashboard, navigate to the Activity tab. Locate the email you sent and ensure that the JSON payload includes the text body and Base64-encoded attachment data. This confirms Postmark is correctly forwarding the email data to your app, as we set up in Day 8.
Monitor the Logs: Check the runtime logs in your DigitalOcean App Platform dashboard to ensure the app processes the JSON payload. You should see logs showing that receipt details were extracted and attachments were uploaded to DigitalOcean Spaces. You can access the runtime logs in the Logs tab of the DigitalOcean App Platform dashboard. If you’re not familiar with DigitalOcean logs, we explored this during Day 9: Automating Receipt Parsing withDigitalOcean’s GenAI Agent.
Verify Spaces Upload: Visit your DigitalOcean Space to confirm that the files were uploaded successfully. You should see the attachments in your bucket as configured in Day 10: Storing Attachments in DigitalOcean Spaces. If everything went as expected, your attachment URLs will be accessible.
Check Google Sheets: Open your Google Sheet and confirm that a new row with receipt details and attachment URLs has been added, as we set up on Day 11: Saving Receipt Details in Google Sheets. The row should include:
Verify the Confirmation Email: Finally, check the inbox of the sender’s email address to ensure the confirmation email was received. This email should contain:
If the workflow doesn’t work as expected, here are a few troubleshooting steps to follow:
Check the Resend Emails Dashboard for Errors: Visit the Resend dashboard to see if any errors occurred while sending the confirmation email.
Verify Environment Variables: Make sure the API key (RESEND_API_KEY
) and sender email (RESEND_EMAIL_FROM
) are correctly configured in your environment variables on the DigitalOcean App Platform dashboard.
Inspect DigitalOcean Runtime Logs: Open the Runtime Logs tab in your DigitalOcean App Platform dashboard to check for errors while processing the email or uploading attachments. These logs can provide helpful insights, especially for interactions with Postmark or Resend.
Review Postmark Activity: In Postmark’s Activity tab, confirm that the test email was properly forwarded to your Flask app. If there are any issues, Postmark will display errors related to forwarding or configuration problems.
Congratulations! You’ve successfully completed the 12 Days of DigitalOcean series and built a fully functional Email-Based Receipt Processing Service.
Today, you:
By adding confirmation emails, you’ve wrapped up a project that processes emails, extracts details, stores attachments, and keeps everything organized in Google Sheets. It’s user-friendly, practical, and ready to solve real-world problems.
This marks the end of the 12 Days of DigitalOcean series. Over the past 12 days, we’ve built two real-world applications, one step at a time. Along the way, you’ve used tools like DigitalOcean’s Serverless Functions, App Platform, Spaces Object Storage, PostgreSQL, DigitalOcean GenAI, Twilio, Google Sheets API, Postmark, PaperTrail, and Resend. Each piece came together to form something greater than the sum of its parts.
Here’s a quick recap of what you’ve built:
This app tracks birthdays and sends SMS reminders automatically. It’s lightweight, serverless, and easy to maintain.
By Day 6, you have a fully automated service running in the cloud. It just works.
This app handles emailed receipts, extracts the needed details, and organizes everything in a database.
By Day 12, you’ve built a complete tool that handles receipts end-to-end.
This is just the beginning—what you’ve learned here can be applied to countless other projects. Here are a few ways to keep going:
If you follow along, I’d love to see what you create—feel free to share your progress or feedback with me on Twitter.
Keep it simple. Build something useful. Happy building! 🚀
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!