working-group-two / wgtwo.com

6 stars 15 forks source link

Question: Can our contact forms trigger an immediate email? #245

Open torotimes opened 1 year ago

torotimes commented 1 year ago

Hey @Prid13

Question for ya:

Today our contact forms (like https://www.wgtwo.com/contact/ ) trigger a slack notification on our end. That's nice and works fine.

What I'm wondering is whether it could ALSO trigger an automatic email response to the person who submitted the form?

We could use something like "sales@wgtwo.com" as sender, with a message that thanks for them for getting in touch and say a few words about what will happen next. I can write that email, but wanted to find out if we can make the process work first.

Prid13 commented 1 year ago

Hey :D

This is indeed possible. What email provider is sales@wgtwo using? I need to see if the email provider (Gmail, Outlook, etc.) has an API for sending emails on behalf of an email account, or if this requires extra code to be written server-side. :)

torotimes commented 1 year ago

Hi @Prid13

We use Gmail / Google email as our provider.

@jonny-wg2 - perhaps you have some insight here?

jonny-wg2 commented 1 year ago

Perhaps leveraging sendgrid API we could do this?

If we need to do something wervside netlify functions would be a good option - as we are hosting the dev website with them today.

torotimes commented 1 year ago

Did you get a chance to look further into this one, @Prid13 ?

Prid13 commented 1 year ago

Wanted to research this thorougly, but have been a bit busy so haven't had the chance yet. But will do it as soon as I get the chance :)

torotimes commented 1 year ago

Great, let us know when you might have a chance to look at it!

Prid13 commented 1 year ago

Sorry it's taking so long :( Will have my proposed solution posted within the day 😇 Thanks for the patience ⭐

torotimes commented 1 year ago

Ok, no problem!

Prid13 commented 1 year ago

After doing proper research, I've come to the conclusion that we can leverage Gmail's SMTP mail servers to send an email on behalf of a Gmail account. This will require some backend code to be run, which, as @jonny-wg2 so thoughfully suggested, can be run via Netlify Functions. Here's the excellent tutorial I found: https://www.labnol.org/gmail-smtp-send-emails-220530

We'll need to create a new "Google Cloud Project", which will essentially be used to get some valid API and authentication tokens that can be used to send those emails, and then write some simple Node.js backend code to deliver those emails :)

I'll need access to the Gmail account to set up the "Cloud Project" system and get those tokens, and I'm also going to need access to Netlify for deploying the serverless backend code :)

I think the only "restriction" is that up to 100 mails can be sent a day, but I gather that won't be a problem for quite a while 😅

jonny-wg2 commented 1 year ago

Hey @Prid13 recently WG2 has moved to leverage sendgrid for sending all emails for applications and am hesitant to setup this via google API. A couple cons are, we might need to create a dedicated google user for sending these emails? And second - this isn't used by any other projects today.

Looking at sendgrid and netlify - what are your thoughts on this tutorial? https://slawinski.dev/blog/start-sending-emails-using-netlify-lambda-functions-and-sendgrid/

Note, we will need to also think about abuse here and come up with a solution to limit bots from sending a bunch of emails from our email. Perhaps recaptcha would be a reasonable solution https://www.npmjs.com/package/react-google-recaptcha-v3

Prid13 commented 1 year ago

Oh, cool, didn't know about that 😅 Then we should definitely go with SendGrid :)

That tutorial looks like a good starting point for getting this off the ground ⭐

About the abuse part, is wgtwo getting any sizeable amount of traffic from bots -- is there any data on this? Taking precautions is always a plus, but personally speaking, a captcha solution would only get in the way and add more friction to the form filling out process for the end user, so perhaps a "less secure" way could be implemented for now that doesn't bother the user, or? I was thinking perhaps checking for the IP address in Netlify Functions and terminating the code execution if the same IP is used multiple times in a short period of time. What do you think? Is this necessary at this stage? :)

jonny-wg2 commented 1 year ago

+2 on the captcha and friction. Ok let's hold off on this for now. We see probably 1 spam message a week. The regex filtering that you added before really helped cut down the spam. It might be difficult to to check IP as we won't have a storage with the netlify functions.

Checking now though - I see netlify functions cost money... $20 a month. I see that cloudflare works are however free.. Here is a good tutorial here on how to use this with sendgrid and cloudflare workers https://blog.amanbhargava.com/send-email-using-cloudflare-worker

@torotimes note about ^

If we do this, we probably also need to build out a template in sendgrid on what to send as part of the email.

Prid13 commented 1 year ago

Thanks for helping me discover Cloudflare Workers -- what a steal! Never knew they offered such a great, gratis service -- as if they weren't generous already 😇

But are we looking at the same page for the Netlify Functions pricing? Pro tier costs $20/mo, but the Functions page does state the Free tier including 125,000 free requests per month:

image

🤔

jonny-wg2 commented 1 year ago

Ahh perfect, I was dupped by netlify's pricing page and the "background functions" offering.

But ok then sweet, let's go forward with netlify as this integrates nicely with our existing dev setup. @Prid13 I sent you an email with some extra details on getting started for testing.

torotimes commented 1 year ago

Hi @Prid13 did you have a closer look at this?

torotimes commented 1 year ago

Hi @Prid13 what's the status on this one?

Prid13 commented 1 year ago

Sorry @torotimes, jonny sent me some keys before his trip and the total mess of an organizer I am I completely forgot to fetch those keys before they "expired". So this is on hold till he returns 😅 sorry :/

Prid13 commented 1 year ago

@jonny-wg2 Hey, I need a little help with this :) Have uploaded a netlify/functions folder to the dev-pages branch, but the function itself isn't working/being called when going to the correct url: https://wgtwo-dev.netlify.app/netlify/functions/sendmail

Here's the folder in the branch: https://github.com/working-group-two/wgtwo.com/tree/dev-pages/netlify/functions/sendmail

What am I doing wrong? Thanks 😇

jonny-wg2 commented 1 year ago

Hey! Just checked netlify and looks like a build error

10:40:43 PM: Build ready to start
10:40:47 PM: build-image version: 4b067841aaa59ef71931d3505b98c2bc3e63f36f (focal)
10:40:47 PM: buildbot version: 95607d5b2e5c357f5913e8858aa45191134e0a8f
10:40:47 PM: Fetching cached dependencies
10:40:47 PM: Starting to download cache of 616.4MB
10:40:52 PM: Finished downloading cache in 4.372s
10:40:52 PM: Starting to extract cache
10:40:52 PM: Finished extracting cache in 730ms
10:40:52 PM: Finished fetching cache in 5.199s
10:40:52 PM: Starting to prepare the repo for build
10:40:53 PM: Preparing Git Reference refs/heads/dev-pages
10:40:55 PM: Parsing package.json dependencies
10:40:56 PM: Different functions path detected, going to use the one specified in the Netlify configuration file: 'netlify/functions' versus '' in the Netlify UI
10:40:56 PM: Starting to install dependencies
10:40:56 PM: Python version set to 3.8
10:40:56 PM: Attempting Ruby version 2.7.2, read from environment
10:40:57 PM: Using Ruby version 2.7.2
10:40:58 PM: Started restoring cached go cache
10:40:58 PM: Finished restoring cached go cache
10:40:58 PM: Installing Go version 1.17 (requested 1.17)
10:41:05 PM: go version go1.17 linux/amd64
10:41:05 PM: Using PHP version 8.0
10:41:06 PM: v16.20.0 is already installed.
10:41:06 PM: Now using node v16.20.0 (npm v8.19.4)
10:41:06 PM: Enabling Node.js Corepack
10:41:06 PM: Started restoring cached build plugins
10:41:06 PM: Finished restoring cached build plugins
10:41:06 PM: Install dependencies script success
10:41:06 PM: Starting build script
10:41:07 PM: Detected 0 framework(s)
10:41:07 PM: Section completed: initializing
10:41:09 PM: ​
10:41:09 PM: Netlify Build                                                 
10:41:09 PM: ────────────────────────────────────────────────────────────────
10:41:09 PM: ​
10:41:09 PM: ❯ Version
10:41:09 PM:   @netlify/build 29.11.5
10:41:09 PM: ​
10:41:09 PM: ❯ Flags
10:41:09 PM:   baseRelDir: true
10:41:09 PM:   buildId: 646bd34b7825e20008b789a4
10:41:09 PM:   deployId: 646bd34b7825e20008b789a6
10:41:09 PM: ​
10:41:09 PM: ❯ Current directory
10:41:09 PM:   /opt/build/repo
10:41:09 PM: ​
10:41:09 PM: ❯ Config file
10:41:09 PM:   No config file was defined: using default values.
10:41:09 PM: ​
10:41:09 PM: ❯ Context
10:41:09 PM:   production
10:41:09 PM: ​
10:41:09 PM: Functions bundling                                            
10:41:09 PM: ────────────────────────────────────────────────────────────────
10:41:09 PM: ​
10:41:09 PM: Packaging Functions from netlify/functions directory:
10:41:09 PM:  - sendmail/sendmail.js
10:41:09 PM: ​
10:41:09 PM: ​
10:41:09 PM: Dependencies installation error                               
10:41:09 PM: ────────────────────────────────────────────────────────────────
10:41:09 PM: ​
10:41:09 PM:   Error message
10:41:09 PM:   A Netlify Function is using "@sendgrid/mail" but that dependency has not been installed yet.
10:41:09 PM: ​
10:41:09 PM:   By default, dependencies inside a Netlify Function's "package.json" are not automatically installed.
  There are several ways to fix this problem:
10:41:09 PM:     - Removing your Function's "package.json" and adding the dependencies to the project's top-level "package.json" instead. This is the fastest and safest solution.
10:41:09 PM:     - Running "npm install" or "yarn" inside your Netlify Function in your build command.
10:41:09 PM:     - Adding the following plugin to your "netlify.toml":
10:41:09 PM: ​
10:41:09 PM:   [[plugins]]
10:41:09 PM:   package = "@netlify/plugin-functions-install-core"
10:41:09 PM: ​​
10:41:09 PM:   In file "/opt/build/repo/netlify/functions/sendmail/sendmail.js"
10:41:09 PM:   Cannot find module '@sendgrid/mail'
10:41:09 PM:   Require stack:
10:41:09 PM:   - /opt/buildhome/node-deps/node_modules/@netlify/zip-it-and-ship-it/dist/runtimes/node/bundlers/zisi/resolve.js
10:41:09 PM: ​
10:41:09 PM:   Resolved config
10:41:09 PM:   build:
10:41:09 PM:     environment:
10:41:09 PM:       - SENDGRID_APIKEY
10:41:09 PM:     publish: /opt/build/repo
10:41:09 PM:     publishOrigin: ui
10:41:09 PM:   functionsDirectory: /opt/build/repo/netlify/functions
10:41:10 PM: Caching artifacts
10:41:10 PM: Started saving build plugins
10:41:10 PM: Finished saving build plugins
10:41:10 PM: Started saving pip cache
10:41:10 PM: Finished saving pip cache
10:41:10 PM: Started saving emacs cask dependencies
10:41:11 PM: Failed during stage 'building site': Build script returned non-zero exit code: 2 (https://ntl.fyi/exit-code-2)
10:41:10 PM: Finished saving emacs cask dependencies
10:41:10 PM: Started saving maven dependencies
10:41:10 PM: Finished saving maven dependencies
10:41:10 PM: Started saving boot dependencies
10:41:10 PM: Finished saving boot dependencies
10:41:10 PM: Started saving rust rustup cache
10:41:10 PM: Finished saving rust rustup cache
10:41:10 PM: Started saving go dependencies
10:41:10 PM: Finished saving go dependencies
10:41:11 PM: Build failed due to a user error: Build script returned non-zero exit code: 2
10:41:11 PM: Failing build: Failed to build site
10:41:12 PM: Finished processing build request in 24.885s
Prid13 commented 1 year ago

Finally done: https://github.com/working-group-two/wgtwo.com/pull/400

I am deeply sorry that this took so long. Truly appreciate the patience ⭐