Sends emails using Gmail SMTP with Google OAuth2 or username/pw.
- Requirements
- Quickstart
- Installation
- Usage
- Alternate Usage
- Code Samples
- Available Scripts
- Docker Scripts
Click to expand the list of requirements
- Windows 11/Linux OS
- NodeJS LTS v22 or higher
Recommended: node: 22.14.0 npm: 10.9.2 - Gmail Account
- Gmail email/password
- Optional:
- Google Cloud Platform project configured with OAuth2 settings and credentials
- Read on the Google Gmail, SMTP and OAuth2 Setup sections for more information
(Installed via npm)
- googleapis
v162.0.0 - nodemailer
v7.0.9 - typescript
v5.9.3- Compile-time error checker - vite-node
v3.2.4- Runs TS files in development mode - vitest
v3.2.4- Runs tests - commander
v14.0.1- CLI library - sanitize-html
v2.17.0- Sanitizes WYSIWYG HTML input
-
Create a
.envfile in the/appdirectory, replacing the contents of the.env.examplefile with actual values.- See Installation # 4 for more information about these environment variables.
-
Install dependencies.
npm install
-
Transpile to JavaScript.
npm run transpile
-
Send a text email using the CLI, eg. using Bash:
npm run send-email -- text \ -s "You are Invited" \ -c "Birthday party in December" \ -r [email protected],[email protected],[email protected]
💡 TIP: Use
send-email:devto work on development mode without needing to run"npm run transpile" -
Send a styled HTML email using the CLI, eg. using Bash:
npm run send-email -- html \ -s "Reading Materials" \ -c "Lorem ipsum dolor sit amet" "this is paragraph 1" "this is paragraph 2" \ -r [email protected],[email protected],[email protected]
💡 TIP: Use
send-email:devto work on development mode without needing to run"npm run transpile"
-
Clone the repository.
git clone https://github.com/weaponsforge/send-email.git -
Install dependencies.
npm install -
Configure OAuth2. Get a refresh token from the Google OAuth 2 Playground.
- Read on Using the OAuth 2.0 Playground for more information about generating a refresh token using the Google OAuth Playground.
- INFO: This is an older note, some steps may vary this 2025)
-
Set up the environment variables. Create a
.envfile inside the /app directory with reference to the.env.examplefile.Variable Name Description GOOGLE_USER_EMAIL Your google email that you've configured for Gmail SMTP and Google OAuth2 GOOGLE_CLIENT_ID Google Developer Project ID associated with your email GOOGLE_CLIENT_SECRET Client secret for the Google Developer Project CLIENT_ID GOOGLE_REDIRECT_URI Allowed Google API redirect URI. Its value is https://developers.google.com/oauthplaygroundby default.GOOGLE_REFRESH_TOKEN The initial (or any) refresh token obtained from OAuthPlayground. - Read on Using the OAuth 2.0 Playground for more information about generating a refresh token using the Google OAuth Playground.
(INFO: This is an older note, some steps may vary this 2025)
Using Node
-
Run a non-test TypeScript file inside the /app/src directory from the project's "root directory". For example:
cd app npx vite-node src/utils/sample.ts -
Run compiled JavaScript code from the TypeScript files. For example:
cd app npm run transpile node dist/utils/sample.js -
See the Available Scripts section for more information.
Using Docker
-
Build the image (Run only once)
docker compose build
-
Run the container (Run only once)
docker compose up
-
Run an NPM script using Docker compose
Ensure the Docker container is running (see Run the container)docker exec -it weaponsforge-sendemail-dev <AVAILABLE_SCRIPT_OR_DOCKER_SCRIPT>
-
Run an NPM script using only Docker
Ensure the Docker container is running (see Run the container)docker run -it -v ${pwd}/app:/opt/app -v /opt/app/node_modules --rm weaponsforge/sendemail:dev <AVAILABLE_SCRIPT_OR_DOCKER_SCRIPT>
-
Run a non-test TS file using Vite
(requires Run an NPM script using Docker compose)docker exec -it weaponsforge-sendemail-dev npx vite-node /opt/app/src/<PATH_TO_TS_FILE>.ts
-
See the Available Scripts and Docker Scripts sections for more information.
app/src/demo/sendEmail.ts
import { send } from '@/lib/index.js'
const main = async () => {
await send({
recipient: '[email protected]',
subject: 'Test Message',
content: 'How are you?'
})
}
main()app/src/demo/sendHtml.ts
import { send } from '@/lib/index.js'
import { buildHtml } from '@/lib/index.js'
const recipients = ['[email protected]', '[email protected]']
const main = async () => {
// Build the HTML email content
const emailContent = await buildHtml({
content: ['Lorem ipsum dolor sit amet...'],
recipients,
sender: process.env.GOOGLE_USER_EMAIL
})
// Send the email
await send({
subject: 'Welcome Aboard!',
content: emailContent,
recipients,
isHtml: true
})
}
main()These scripts, compatible with running in Node and Docker, run various TypeScript scripts and tests.
Click to expand the list of available scripts
Runs vitest in watch mode, watching file changes and errors to files linked with *.test.ts files.
Watches file changes in .ts files using the tsc --watch option.
Builds JavaScript, .d.ts declaration files, and map files from the TypeScript source files in the /src directory.
Runs type-checking without generating the JavaScript or declaration files from the TypeScript files in the /src and __tests__ directories.
Lints TypeScript source codes.
Fixes lint errors in TypeScript files.
- Runs test scripts defined in
*.test.tsfiles with coverage. - Generates a vitest test report into the /html directory.
- Run
npm run report:viewto preview the generated report.
- Runs test scripts defined in
*.test.tsfiles with coverage. - Spawns a local report-like website showing each test's real-time status and coverage using vitest-ui
- This script is similar to the vitest
npm run devscript that watches for changes in the*.test.tsfiles but displays the result logs and coverage details in the local website rather than the command line.
NOTE: This script requires running
npm testfirst to generate a test report into the /html directory
- Spins up a local web server accessible at
http://localhost:4174/ - Serves the website contents of a test report from the /html directory
Copies the EJS email template into the /dist/templates directory.
This script runs automatically after "npm run transpile", copying the "/app/src/templates/email.ejs" to the "/dist/templates" directory.
Sends text and HTML emails using the command line interface (CLI) with transpiled JavaScript.
💡 IMPORTANT:
- This script requires running the
"npm run transpile"script before usage.- If you want to run these without transpiling, append a
:devafter the NPM script:"npm run send-email:dev"
-
To view the list of available commands:
npm run send-email helpUsage: send-email [options] [command] CLI for sending an email using Gmail SMTP and Google OAuth2 Options: -V, --version output the version number -h, --help display help for command Commands: text [options] Send raw text email to one or multiple recipient/s html [options] Send paragraphs of text or WYSIWYG content as styled HTML email to one or multiple recipient/s. help [command] display help for command -
Append a double dash
--to pass arguments to the CLI commands eg., (using Bash)npm run send-email -- text \ -s "You are Invited" \ -c "Birthday party in December" \ -r [email protected],[email protected],[email protected]
-
View available options for the send-email text [options] command.
# Usage options for the send "text" email command npm run send-email help text
Usage: send-email text [options] Send raw text email to one or multiple recipient/s Options: -s, --subject <title> email subject or title enclosed in double-quotes -c, --content <text> email text content enclosed in double-quotes -e, --env <path> path to .env file (optional) -r, --recipients <emails> comma-separated list of email addresses -h, --help display help for command -
View available options for the send-email html [options] command.
# Usage options for the send "html" email command npm run send-email help html
Usage: send-email html [options] Send paragraphs of text or WYSIWYG content as styled HTML email to one or multiple recipient/s. Options: -s, --subject <title> email subject or title enclosed in double-quotes -r, --recipients <emails> comma-separated list of email addresses -c, --content <text...> whitespace-delimited list containing text/paragraphs enclosed in double-quotes -w, --wysiwyg [html] optional HTML tags that form a WYSIWYG layout enclosed in double-quotes -e, --env <path> path to .env file (optional) -h, --help display help for command
- Sends an email using the command line interface (CLI) in development mode using TypeScript.
- Append a double dash
--to pass arguments to the CLI commands. - Usage: view the
"npm run send-email"script for more information. They share similar usage.-
💡 NOTE: Append
:devin the script eg.,npm run send-email:dev
-
These scripts allow optional Docker-related processes, such as enabling file watching in Docker containers running in Windows WSL2 and others.
Tip
Scripts with a ":win" suffix indicate compatibility for Windows Docker running in WSL2.
Click to expand the list of available scripts
Run the Docker containers first using options A or B.
A. Using Docker compose
docker compose build
docker compose upUse the template:
docker exec -it weaponsforge-sendemail-dev <AVAILABLE_DOCKER_SCRIPT>B. Using Only Docker (PowerShell)
docker run -it -v ${pwd}/app:/opt/app -v /opt/app/node_modules --rm weaponsforge/sendemail:dev <AVAILABLE_DOCKER_SCRIPT>
- Runs the
"/src/utils/sample/sample.ts"script in containers with debugging enabled in VSCode by default. - Replace the
"/src/utils/sample/sample.ts"file path in the package.json file's"docker:debug"script with a target TypeScript file for debugging. - Map port
9229to enable debugging VSCode while running in Docker (PowerShell).- (A. Using Docker compose):
docker exec -it weaponsforge-sendemail-dev npm run docker:debug - (B. Using Only Docker (PowerShell))
docker run -it -v ${pwd}/app:/opt/app -v /opt/app/node_modules -p 9229:9229 --rm weaponsforge/sendemail:dev npm run docker:debug
- (A. Using Docker compose):
- Launch the VSCode debugger using the following configuration:
{ "version": "0.2.0", "configurations": [ { "type": "node", "request": "attach", "name": "Attach to Docker", "address": "localhost", "port": 9229, "restart": true, "skipFiles": ["<node_internals>/**"], "localRoot": "${workspaceFolder}/app", "remoteRoot": "/opt/app" } ] }
- Docker command counterpart of the
npm run test:uiscript, compatible with containers running in Linux OS. - Runs test scripts defined in
*.test.tsfiles in watch mode with coverage from a container. - Spawns a local report-like website showing each test's real-time status and coverage using vitest-ui accessible at
http://localhost:51204/__vitest__/.
NOTE: This script requires running
npm testfirst to generate a test report into the /html directory
- Docker command counterpart of the
npm run report:viewscript. - Spins up a local web server accessible at
http://localhost:4174/ - Serves the website contents of a test report from the host's /html directory
Watches file changes in .ts files using the tsc --watch option with dynamicPriorityPolling in Docker containers running in Windows WSL2.
- Sets and exports the environment variables:
CHOKIDAR_USEPOLLING=1andCHOKIDAR_INTERVAL=1000 - Runs
vitestin watch mode inside Docker containers running in Windows WSL2, watching file changes and errors to files linked with*.test.tsfiles.
- Sets and exports the environment variables:
CHOKIDAR_USEPOLLING=1andCHOKIDAR_INTERVAL=1000 - Runs test scripts defined in
*.test.tsfiles in watch mode with coverage inside Docker containers running in Windows WSL2. - Spawns a local report-like website showing each test's real-time status and coverage using vitest-ui accessible at
http://localhost:51204/__vitest__/.
@weaponsforge
20250323