Write an Express server to send email
Tags: node, googlecloud, express
Published: 2021-12-12 00:30:15

> In this article, I would like to share how to write a Node.js program to send email via Gmail SMTP server using a Google account, and then deploy the program to Google Cloud.

<!-- TABLE OF CONTENTS -->
<details>
  <summary>Table of Contents</summary>
  <ul>
    <li>
      <a href="#generate-app-password">Generate App Password</a>
    </li>
    <li><a href="#write-express-js-program">Write Express.js Program</a></li>
    <li><a href="#deploy-to-google-cloud">Deploy to Google Cloud</a></li>
  </ul>
</details>

## Generate App Password
First of all, create App Password to be used in the program.  Due to security reason, Google does not allow non Google-app to sign in.  It is required to explicitly generate an App Password to use.

In order to generate App Password:
1. Go to your Google Account.
2. Select Security.
3. Under "Signing in to Google," turn on 2-Step Verification.
4. Under "Signing in to Google," select App Passwords.
5. At the bottom,
   * choose "Mail" from "Select app"
   * choose "Other (Custom name)" from "Select device"
     A textbox will then be shown.  Enter meaning description like "Send Email from application".
6. Follow the instructions to enter the App Password. The App Password is the 16-character code in the yellow bar on your device.
7. Tap Done.

Reference: [Sign in with App Passwords](https://support.google.com/accounts/answer/185833?hl=en)

## Write Express.js Program

* Create package.json.

   ```json
   {
     "name": "contact-form-server",
     "description": "This script serves as a server to accept and process request from a Contact Form, and then send to data to a destination email",
     "scripts": {
       "start": "node contact_form_server.js"
     },
     "version": "0.0.1",
     "dependencies": {
       "cors": "^2.8.5",
       "express": "^4.17.1",
       "nodemailer": "^6.7.1"
     }
   }
   ```

* Create [contact_form_server.js](https://gist.github.com/adafycheng/d227436f4e8ae2d8e2a8d282efe21e6a) (you can have another js script filename, but make sure to change the script name of the "scripts:start" entry in package.json) as the Node.js script.
   - express package is used for running a server.
   - nodemailer package is used for sending email.
   - cors package is used to allow Cross-Origin Resource Sharing.

* Start the program locally for testing.
   ```bash
   npm start
   ```

* Create a [HTML form](https://gist.github.com/adafycheng/d0f17a2f2d22f83d05702ec1c1b5f5e0) for testing.

## Deploy to Google Cloud
* In Google Cloud Console, create App Engine in standard environment using Node.js. The [main advantage](https://cloud.google.com/appengine/docs/nodejs) of running in Standard Environment is that *"Application can scale to 0 instances when there is no traffic. Most cost-effective for applications that have significant periods where they are not serving traffic"*.
* Create app.yaml for Google Cloud deployment.

   ```yaml
   runtime: nodejs14
   ```

* Enable Cloud Build API.  Set the appropriate credential.
* Deploy to Google Cloud.
   ```bash
   gcloud app deploy
   ```
* Change the url value in the javascript in [HTML form](https://gist.github.com/adafycheng/d0f17a2f2d22f83d05702ec1c1b5f5e0) and test.