-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Abstract sending email, to allow for other email services #11
base: master
Are you sure you want to change the base?
Changes from all commits
744745f
8915ff7
cbbf38c
f4ea28b
18a8974
6641796
72e49ac
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
MAIL_API_KEY= | ||
MAIL_DOMAIN= | ||
MAIL_FROM= | ||
MAIL_SERVICE= # "sendgrid" or "mailgun" | ||
MAIL_HOST_URL= | ||
|
||
APP_ROOT_URL= | ||
API_ROOT_URL= | ||
|
||
MONGODB_URI= | ||
DB_NAME= |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,8 +6,8 @@ | |
"author": "Eli <[email protected]>", | ||
"license": "MIT", | ||
"scripts": { | ||
"dev": "yarn start", | ||
"start": "now dev", | ||
"start:remote": "now dev", | ||
"start": "next dev", | ||
"build": "next build", | ||
"serve": "next start", | ||
"test": "jest", | ||
|
@@ -46,9 +46,11 @@ | |
"emotion": "^10.0.27", | ||
"emotion-theming": "^10.0.27", | ||
"express": "^4.17.1", | ||
"form-data": "^4.0.0", | ||
"formik": "^2.1.4", | ||
"isomorphic-unfetch": "^3.0.0", | ||
"lodash.uniq": "^4.5.0", | ||
"mailgun.js": "^3.5.5", | ||
"mobx": "^5.15.4", | ||
"mobx-react-lite": "^2.0.7", | ||
"moment": "^2.27.0", | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import sgMail from "@sendgrid/mail"; | ||
import Mailgun from "mailgun.js"; | ||
import formData from "form-data"; | ||
|
||
/** | ||
* | ||
* @param {sgMail.MailDataRequired|{ html: string }} options | ||
* @returns | ||
*/ | ||
export const sendEmail = async (options) => { | ||
const service = process.env.MAIL_SERVICE; | ||
const apiKey = process.env.MAIL_API_KEY; | ||
const domain = process.env.MAIL_DOMAIN; | ||
const emailFrom = process.env.MAIL_FROM; | ||
const url = process.env.MAIL_HOST_URL; | ||
|
||
const ignore = async () => { | ||
console.warn("Unrecognized mail service", service); | ||
}; | ||
return ( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Newline between fns |
||
{ | ||
mailgun: async () => { | ||
const mg = new Mailgun(formData); | ||
const mailgun = mg.client({ | ||
key: apiKey, | ||
username: "api", | ||
...(url ? { url } : {}), | ||
}); | ||
const params = { | ||
from: emailFrom, | ||
...options, | ||
...(options.dynamic_template_data | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I personally find this destructuring ternary pattern quite unreadable |
||
? { | ||
dynamic_template_data: JSON.stringify( | ||
options.dynamic_template_data | ||
), | ||
} | ||
: {}), | ||
}; | ||
return mailgun.messages.create(domain, params); | ||
}, | ||
sendgrid: () => { | ||
sgMail.setApiKey(apiKey); | ||
return sgMail.send({ from: emailFrom, ...options }); | ||
}, | ||
}[service && service.toLowerCase()] || ignore | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is going on in this line? |
||
)().catch(console.error); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,7 @@ | ||
import sgMail from '@sendgrid/mail'; | ||
import crypto from 'crypto'; | ||
import { hoursFromNow } from '@helpers/apiHelpers'; | ||
import normalizeEmail from 'validator/lib/normalizeEmail'; | ||
|
||
sgMail.setApiKey(process.env.SENDGRID_API_KEY); | ||
import { sendEmail } from './sendEmail'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use absolute imports |
||
|
||
export default async (req, res, { email }) => { | ||
try { | ||
|
@@ -33,7 +31,6 @@ export default async (req, res, { email }) => { | |
|
||
const msg = { | ||
to: user.email, | ||
from: process.env.EMAIL_FROM, | ||
templateId: 'd-3c6627053fd34c9d94876e55d8411a7c', | ||
|
||
dynamic_template_data: { | ||
|
@@ -45,9 +42,15 @@ export default async (req, res, { email }) => { | |
actionButton: 'Activate Account', | ||
appRootUrl: `${process.env.APP_ROOT_URL}`, | ||
}, | ||
html: `Hey ${user.name}, welcome! To finish activating your account, please click the link below. | ||
<div> | ||
<a href='${process.env.APP_ROOT_URL}/verify-email/${token}'> | ||
Activate Account | ||
</a> | ||
</div>`, | ||
}; | ||
|
||
await sgMail.send(msg); | ||
await sendEmail(msg); | ||
|
||
return { | ||
ok: true, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,9 @@ | ||
import sgMail from '@sendgrid/mail'; | ||
import crypto from 'crypto'; | ||
import nextConnect from 'next-connect'; | ||
|
||
import database from '@middleware/database'; | ||
import { minutesFromNow } from '@helpers/apiHelpers'; | ||
|
||
sgMail.setApiKey(process.env.SENDGRID_API_KEY); | ||
import { sendEmail } from '../../../../helpers/apiHelpers/sendEmail'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use absolute imports |
||
|
||
const handler = nextConnect(); | ||
|
||
|
@@ -34,12 +32,11 @@ handler.post(async (req, res) => { | |
|
||
const msg = { | ||
to: user.email, | ||
from: process.env.EMAIL_FROM, | ||
subject: '[feeels] Resetting your password', | ||
html: `Hey ${user.name}, <a href=${process.env.API_ROOT_URL}/forgot-password/${token}>here</a> is a link to reset your password.`, | ||
}; | ||
|
||
await sgMail.send(msg); | ||
await sendEmail(msg); | ||
|
||
return res.status(200); | ||
} catch ({ status, message }) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3371,6 +3371,13 @@ abab@^2.0.3: | |
resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.3.tgz#623e2075e02eb2d3f2475e49f99c91846467907a" | ||
integrity sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg== | ||
|
||
abort-controller@^3.0.0: | ||
version "3.0.0" | ||
resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" | ||
integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== | ||
dependencies: | ||
event-target-shim "^5.0.0" | ||
|
||
accepts@~1.3.7: | ||
version "1.3.7" | ||
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" | ||
|
@@ -3806,6 +3813,11 @@ balanced-match@^1.0.0: | |
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" | ||
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= | ||
|
||
base-64@^1.0.0: | ||
version "1.0.0" | ||
resolved "https://registry.yarnpkg.com/base-64/-/base-64-1.0.0.tgz#09d0f2084e32a3fd08c2475b973788eee6ae8f4a" | ||
integrity sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg== | ||
|
||
base64-js@^1.0.2: | ||
version "1.3.1" | ||
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" | ||
|
@@ -3866,7 +3878,7 @@ bl@^2.2.0: | |
readable-stream "^2.3.5" | ||
safe-buffer "^5.1.1" | ||
|
||
[email protected], bluebird@^3.5.5: | ||
[email protected], bluebird@^3.5.5, bluebird@^3.7.2: | ||
version "3.7.2" | ||
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" | ||
integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== | ||
|
@@ -4510,7 +4522,7 @@ colors@^1.1.2: | |
resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" | ||
integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== | ||
|
||
combined-stream@^1.0.6, combined-stream@~1.0.6: | ||
combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: | ||
version "1.0.8" | ||
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" | ||
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== | ||
|
@@ -5194,6 +5206,11 @@ dashdash@^1.12.0: | |
dependencies: | ||
assert-plus "^1.0.0" | ||
|
||
data-uri-to-buffer@^3.0.1: | ||
version "3.0.1" | ||
resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz#594b8973938c5bc2c33046535785341abc4f3636" | ||
integrity sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og== | ||
|
||
data-urls@^2.0.0: | ||
version "2.0.0" | ||
resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" | ||
|
@@ -5869,6 +5886,11 @@ etag@~1.8.1: | |
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" | ||
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= | ||
|
||
event-target-shim@^5.0.0: | ||
version "5.0.1" | ||
resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" | ||
integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== | ||
|
||
[email protected]: | ||
version "6.4.2" | ||
resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-6.4.2.tgz#f31f8b99d45245f0edbc5b00797830ff3b388970" | ||
|
@@ -6124,6 +6146,11 @@ fd-slicer@~1.1.0: | |
dependencies: | ||
pend "~1.2.0" | ||
|
||
fetch-blob@^2.1.1: | ||
version "2.1.2" | ||
resolved "https://registry.yarnpkg.com/fetch-blob/-/fetch-blob-2.1.2.tgz#a7805db1361bd44c1ef62bb57fb5fe8ea173ef3c" | ||
integrity sha512-YKqtUDwqLyfyMnmbw8XD6Q8j9i/HggKtPEI+pZ1+8bvheBu78biSmNaXWusx1TauGqtUUGx/cBb1mKdq2rLYow== | ||
|
||
figgy-pudding@^3.5.1: | ||
version "3.5.2" | ||
resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" | ||
|
@@ -6313,6 +6340,15 @@ [email protected]: | |
tapable "^1.0.0" | ||
worker-rpc "^0.1.0" | ||
|
||
form-data@^4.0.0: | ||
version "4.0.0" | ||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" | ||
integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== | ||
dependencies: | ||
asynckit "^0.4.0" | ||
combined-stream "^1.0.8" | ||
mime-types "^2.1.12" | ||
|
||
form-data@~2.3.2: | ||
version "2.3.3" | ||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" | ||
|
@@ -7918,6 +7954,19 @@ kleur@^3.0.3: | |
resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" | ||
integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== | ||
|
||
ky-universal@^0.8.2: | ||
version "0.8.2" | ||
resolved "https://registry.yarnpkg.com/ky-universal/-/ky-universal-0.8.2.tgz#edc398d54cf495d7d6830aa1ab69559a3cc7f824" | ||
integrity sha512-xe0JaOH9QeYxdyGLnzUOVGK4Z6FGvDVzcXFTdrYA1f33MZdEa45sUDaMBy98xQMcsd2XIBrTXRrRYnegcSdgVQ== | ||
dependencies: | ||
abort-controller "^3.0.0" | ||
node-fetch "3.0.0-beta.9" | ||
|
||
ky@^0.25.1: | ||
version "0.25.1" | ||
resolved "https://registry.yarnpkg.com/ky/-/ky-0.25.1.tgz#0df0bd872a9cc57e31acd5dbc1443547c881bfbc" | ||
integrity sha512-PjpCEWlIU7VpiMVrTwssahkYXX1by6NCT0fhTUX34F3DTinARlgMpriuroolugFPcMgpPWrOW4mTb984Qm1RXA== | ||
|
||
latest-version@^5.0.0: | ||
version "5.1.0" | ||
resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-5.1.0.tgz#119dfe908fe38d15dfa43ecd13fa12ec8832face" | ||
|
@@ -8151,6 +8200,20 @@ lru-cache@^5.1.1: | |
dependencies: | ||
yallist "^3.0.2" | ||
|
||
mailgun.js@^3.5.5: | ||
version "3.5.5" | ||
resolved "https://registry.yarnpkg.com/mailgun.js/-/mailgun.js-3.5.5.tgz#736e0a0f4a447a2dce6f8aff36917536470ec32e" | ||
integrity sha512-D7wvK7K3BfqNtpDnwadEcXW5xbUZsNuykIx/HZusd+UfXzKRRsj3k4b4SrRzM4waN0G940CMOYNCv02jfTZ6cg== | ||
dependencies: | ||
base-64 "^1.0.0" | ||
bluebird "^3.7.2" | ||
ky "^0.25.1" | ||
ky-universal "^0.8.2" | ||
url "^0.11.0" | ||
url-join "0.0.1" | ||
web-streams-polyfill "^3.0.1" | ||
webpack-merge "^5.4.0" | ||
|
||
make-dir@^2.0.0: | ||
version "2.1.0" | ||
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" | ||
|
@@ -8630,6 +8693,14 @@ [email protected], node-fetch@^2.2.0: | |
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd" | ||
integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA== | ||
|
||
[email protected]: | ||
version "3.0.0-beta.9" | ||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.0.0-beta.9.tgz#0a7554cfb824380dd6812864389923c783c80d9b" | ||
integrity sha512-RdbZCEynH2tH46+tj0ua9caUHVWrd/RHnRfvly2EVdqGmI3ndS1Vn/xjm5KuGejDt2RNDQsVRLPNd2QPwcewVg== | ||
dependencies: | ||
data-uri-to-buffer "^3.0.1" | ||
fetch-blob "^2.1.1" | ||
|
||
node-int64@^0.4.0: | ||
version "0.4.0" | ||
resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" | ||
|
@@ -11702,6 +11773,11 @@ urix@^0.1.0: | |
resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" | ||
integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= | ||
|
||
[email protected]: | ||
version "0.0.1" | ||
resolved "https://registry.yarnpkg.com/url-join/-/url-join-0.0.1.tgz#1db48ad422d3402469a87f7d97bdebfe4fb1e3c8" | ||
integrity sha1-HbSK1CLTQCRpqH99l73r/k+x48g= | ||
|
||
url-parse-lax@^3.0.0: | ||
version "3.0.0" | ||
resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" | ||
|
@@ -11895,6 +11971,11 @@ watchpack@^1.6.1: | |
graceful-fs "^4.1.2" | ||
neo-async "^2.5.0" | ||
|
||
web-streams-polyfill@^3.0.1: | ||
version "3.1.0" | ||
resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.1.0.tgz#86f983b4f44745502b0d8563d9ef3afc609d4465" | ||
integrity sha512-wO9r1YnYe7kFBLHyyVEhV1H8VRWoNiNnuP+v/HUUmSTaRF8F93Kmd3JMrETx0f11GXxRek6OcL2QtjFIdc5WYw== | ||
|
||
webidl-conversions@^5.0.0: | ||
version "5.0.0" | ||
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" | ||
|
@@ -11905,6 +11986,14 @@ webidl-conversions@^6.0.0: | |
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514" | ||
integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== | ||
|
||
webpack-merge@^5.4.0: | ||
version "5.8.0" | ||
resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.8.0.tgz#2b39dbf22af87776ad744c390223731d30a68f61" | ||
integrity sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q== | ||
dependencies: | ||
clone-deep "^4.0.1" | ||
wildcard "^2.0.0" | ||
|
||
[email protected], webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1: | ||
version "1.4.3" | ||
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" | ||
|
@@ -11994,6 +12083,11 @@ widest-line@^3.1.0: | |
dependencies: | ||
string-width "^4.0.0" | ||
|
||
wildcard@^2.0.0: | ||
version "2.0.0" | ||
resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec" | ||
integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw== | ||
|
||
word-wrap@~1.2.3: | ||
version "1.2.3" | ||
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This fn does not need to be async