Attempt to improve unsent mail

This commit is contained in:
Thomas Ruoff
2022-06-23 17:39:30 +02:00
committed by Thomas Ruoff
parent a462cd1c14
commit 942066bc7a
4 changed files with 119 additions and 97 deletions

View File

@@ -2,12 +2,11 @@ import { Booking } from '../db/booking'
import { getBaseURL } from '../helpers/url' import { getBaseURL } from '../helpers/url'
import { daysFormatFrontend } from './date' import { daysFormatFrontend } from './date'
import { generateCalendarEntry } from './ical' import { generateCalendarEntry } from './ical'
import { retryWithDelay } from './retryWithDelay' import sgMail from '@sendgrid/mail'
const SENDGRID_API_KEY = process.env.SENDGRID_API_KEY const SENDGRID_API_KEY = process.env.SENDGRID_API_KEY
const ADMIN_EMAIL = process.env.ADMIN_EMAIL const ADMIN_EMAIL = process.env.ADMIN_EMAIL
const FROM_EMAIL = process.env.FROM_EMAIL const FROM_EMAIL = process.env.FROM_EMAIL
const SENDGRID_URL = 'https://api.sendgrid.com/v3/mail/send'
if (!SENDGRID_API_KEY) { if (!SENDGRID_API_KEY) {
throw new Error('NO SENDGRID_API_KEY set!') throw new Error('NO SENDGRID_API_KEY set!')
@@ -21,6 +20,8 @@ if (!FROM_EMAIL) {
throw new Error('No FROM_EMAIL set!') throw new Error('No FROM_EMAIL set!')
} }
sgMail.setApiKey(SENDGRID_API_KEY)
const footer = ` const footer = `
Viele Grüße Viele Grüße
@@ -29,6 +30,7 @@ Thomas Ruoff
Pfadi Bussle Wart Pfadi Bussle Wart
Tel. 0151/212 253 62 Tel. 0151/212 253 62
${getBaseURL()}
` `
function getReceivedBookingBookerText(booking: Booking): string { function getReceivedBookingBookerText(booking: Booking): string {
@@ -210,36 +212,22 @@ async function sendMail({
}[] }[]
}): Promise<void> { }): Promise<void> {
const data = { const data = {
personalizations: [ to,
{
to,
},
],
from, from,
subject, subject,
content: [{ type: 'text/plain', value: textPlainContent }], text: textPlainContent,
attachments, attachments,
} }
const fetchOptions = { try {
method: 'POST', await sgMail.send(data)
headers: { } catch (error) {
'Content-Type': 'application/json', console.error(error)
Authorization: `Bearer ${SENDGRID_API_KEY}`,
}, if (error.response) {
body: JSON.stringify(data), console.error(error.response.body)
}
// TODO: stuff into DB if failed and retry later
} }
return retryWithDelay({
run: async () => {
const resp = await fetch(SENDGRID_URL, fetchOptions)
const bodyText = await resp.text()
if (!resp.ok) {
throw new Error(
`Failed to send mail with status ${resp.status}: ${bodyText}`
)
}
},
})
} }

View File

@@ -1,20 +0,0 @@
import pRetry from 'p-retry'
export function retryWithDelay<T>({
run,
delay = 1000,
}: {
run: () => Promise<T>
delay?: number
}) {
return pRetry(run, {
retries: 2,
onFailedAttempt: (error) => {
console.info(
`Attempt ${error.attemptNumber}: ${error.message}. ${error.retriesLeft} retries left`
)
return new Promise((resolve) => setTimeout(resolve, delay))
},
})
}

150
package-lock.json generated
View File

@@ -9,6 +9,7 @@
"version": "0.1.0", "version": "0.1.0",
"dependencies": { "dependencies": {
"@next-auth/mongodb-adapter": "1.0.3", "@next-auth/mongodb-adapter": "1.0.3",
"@sendgrid/mail": "^7.7.0",
"autoprefixer": "10.4.7", "autoprefixer": "10.4.7",
"classnames": "2.3.1", "classnames": "2.3.1",
"date-fns": "2.28.0", "date-fns": "2.28.0",
@@ -20,7 +21,6 @@
"next-auth": "4.6.1", "next-auth": "4.6.1",
"next-mdx-remote": "4.0.3", "next-mdx-remote": "4.0.3",
"nodemailer": "6.7.5", "nodemailer": "6.7.5",
"p-retry": "5.1.1",
"react": "18.2.0", "react": "18.2.0",
"react-calendar": "3.7.0", "react-calendar": "3.7.0",
"react-dom": "18.2.0", "react-dom": "18.2.0",
@@ -1546,6 +1546,41 @@
"integrity": "sha512-WiBSI6JBIhC6LRIsB2Kwh8DsGTlbBU+mLRxJmAe3LjHTdkDpwIbEOZgoXBbZilk/vlfjK8i6nKRAvIRn1XaIMw==", "integrity": "sha512-WiBSI6JBIhC6LRIsB2Kwh8DsGTlbBU+mLRxJmAe3LjHTdkDpwIbEOZgoXBbZilk/vlfjK8i6nKRAvIRn1XaIMw==",
"dev": true "dev": true
}, },
"node_modules/@sendgrid/client": {
"version": "7.7.0",
"resolved": "https://registry.npmjs.org/@sendgrid/client/-/client-7.7.0.tgz",
"integrity": "sha512-SxH+y8jeAQSnDavrTD0uGDXYIIkFylCo+eDofVmZLQ0f862nnqbC3Vd1ej6b7Le7lboyzQF6F7Fodv02rYspuA==",
"dependencies": {
"@sendgrid/helpers": "^7.7.0",
"axios": "^0.26.0"
},
"engines": {
"node": "6.* || 8.* || >=10.*"
}
},
"node_modules/@sendgrid/helpers": {
"version": "7.7.0",
"resolved": "https://registry.npmjs.org/@sendgrid/helpers/-/helpers-7.7.0.tgz",
"integrity": "sha512-3AsAxfN3GDBcXoZ/y1mzAAbKzTtUZ5+ZrHOmWQ279AuaFXUNCh9bPnRpN504bgveTqoW+11IzPg3I0WVgDINpw==",
"dependencies": {
"deepmerge": "^4.2.2"
},
"engines": {
"node": ">= 6.0.0"
}
},
"node_modules/@sendgrid/mail": {
"version": "7.7.0",
"resolved": "https://registry.npmjs.org/@sendgrid/mail/-/mail-7.7.0.tgz",
"integrity": "sha512-5+nApPE9wINBvHSUxwOxkkQqM/IAAaBYoP9hw7WwgDNQPxraruVqHizeTitVtKGiqWCKm2mnjh4XGN3fvFLqaw==",
"dependencies": {
"@sendgrid/client": "^7.7.0",
"@sendgrid/helpers": "^7.7.0"
},
"engines": {
"node": "6.* || 8.* || >=10.*"
}
},
"node_modules/@sinclair/typebox": { "node_modules/@sinclair/typebox": {
"version": "0.23.5", "version": "0.23.5",
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.23.5.tgz", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.23.5.tgz",
@@ -1753,11 +1788,6 @@
"@types/react": "*" "@types/react": "*"
} }
}, },
"node_modules/@types/retry": {
"version": "0.12.1",
"resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.1.tgz",
"integrity": "sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g=="
},
"node_modules/@types/scheduler": { "node_modules/@types/scheduler": {
"version": "0.16.2", "version": "0.16.2",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
@@ -2192,6 +2222,14 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/axios": {
"version": "0.26.1",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz",
"integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==",
"dependencies": {
"follow-redirects": "^1.14.8"
}
},
"node_modules/axobject-query": { "node_modules/axobject-query": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz",
@@ -3928,6 +3966,25 @@
"integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==",
"dev": true "dev": true
}, },
"node_modules/follow-redirects": {
"version": "1.15.1",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz",
"integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"engines": {
"node": ">=4.0"
},
"peerDependenciesMeta": {
"debug": {
"optional": true
}
}
},
"node_modules/fraction.js": { "node_modules/fraction.js": {
"version": "4.2.0", "version": "4.2.0",
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz",
@@ -7044,21 +7101,6 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/p-retry": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/p-retry/-/p-retry-5.1.1.tgz",
"integrity": "sha512-i69WkEU5ZAL8mrmdmVviWwU+DN+IUF8f4sSJThoJ3z5A7Nn5iuO5ROX3Boye0u+uYQLOSfgFl7SuFZCjlAVbQA==",
"dependencies": {
"@types/retry": "0.12.1",
"retry": "^0.13.1"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/p-try": { "node_modules/p-try": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
@@ -8203,14 +8245,6 @@
"node": ">=10" "node": ">=10"
} }
}, },
"node_modules/retry": {
"version": "0.13.1",
"resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz",
"integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==",
"engines": {
"node": ">= 4"
}
},
"node_modules/reusify": { "node_modules/reusify": {
"version": "1.0.4", "version": "1.0.4",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
@@ -10368,6 +10402,32 @@
"integrity": "sha512-WiBSI6JBIhC6LRIsB2Kwh8DsGTlbBU+mLRxJmAe3LjHTdkDpwIbEOZgoXBbZilk/vlfjK8i6nKRAvIRn1XaIMw==", "integrity": "sha512-WiBSI6JBIhC6LRIsB2Kwh8DsGTlbBU+mLRxJmAe3LjHTdkDpwIbEOZgoXBbZilk/vlfjK8i6nKRAvIRn1XaIMw==",
"dev": true "dev": true
}, },
"@sendgrid/client": {
"version": "7.7.0",
"resolved": "https://registry.npmjs.org/@sendgrid/client/-/client-7.7.0.tgz",
"integrity": "sha512-SxH+y8jeAQSnDavrTD0uGDXYIIkFylCo+eDofVmZLQ0f862nnqbC3Vd1ej6b7Le7lboyzQF6F7Fodv02rYspuA==",
"requires": {
"@sendgrid/helpers": "^7.7.0",
"axios": "^0.26.0"
}
},
"@sendgrid/helpers": {
"version": "7.7.0",
"resolved": "https://registry.npmjs.org/@sendgrid/helpers/-/helpers-7.7.0.tgz",
"integrity": "sha512-3AsAxfN3GDBcXoZ/y1mzAAbKzTtUZ5+ZrHOmWQ279AuaFXUNCh9bPnRpN504bgveTqoW+11IzPg3I0WVgDINpw==",
"requires": {
"deepmerge": "^4.2.2"
}
},
"@sendgrid/mail": {
"version": "7.7.0",
"resolved": "https://registry.npmjs.org/@sendgrid/mail/-/mail-7.7.0.tgz",
"integrity": "sha512-5+nApPE9wINBvHSUxwOxkkQqM/IAAaBYoP9hw7WwgDNQPxraruVqHizeTitVtKGiqWCKm2mnjh4XGN3fvFLqaw==",
"requires": {
"@sendgrid/client": "^7.7.0",
"@sendgrid/helpers": "^7.7.0"
}
},
"@sinclair/typebox": { "@sinclair/typebox": {
"version": "0.23.5", "version": "0.23.5",
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.23.5.tgz", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.23.5.tgz",
@@ -10575,11 +10635,6 @@
"@types/react": "*" "@types/react": "*"
} }
}, },
"@types/retry": {
"version": "0.12.1",
"resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.1.tgz",
"integrity": "sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g=="
},
"@types/scheduler": { "@types/scheduler": {
"version": "0.16.2", "version": "0.16.2",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
@@ -10872,6 +10927,14 @@
"integrity": "sha512-gd1kmb21kwNuWr6BQz8fv6GNECPBnUasepcoLbekws23NVBLODdsClRZ+bQ8+9Uomf3Sm3+Vwn0oYG9NvwnJCw==", "integrity": "sha512-gd1kmb21kwNuWr6BQz8fv6GNECPBnUasepcoLbekws23NVBLODdsClRZ+bQ8+9Uomf3Sm3+Vwn0oYG9NvwnJCw==",
"dev": true "dev": true
}, },
"axios": {
"version": "0.26.1",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz",
"integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==",
"requires": {
"follow-redirects": "^1.14.8"
}
},
"axobject-query": { "axobject-query": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz",
@@ -12122,6 +12185,11 @@
"integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==",
"dev": true "dev": true
}, },
"follow-redirects": {
"version": "1.15.1",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz",
"integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA=="
},
"fraction.js": { "fraction.js": {
"version": "4.2.0", "version": "4.2.0",
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz",
@@ -14272,15 +14340,6 @@
"p-limit": "^2.2.0" "p-limit": "^2.2.0"
} }
}, },
"p-retry": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/p-retry/-/p-retry-5.1.1.tgz",
"integrity": "sha512-i69WkEU5ZAL8mrmdmVviWwU+DN+IUF8f4sSJThoJ3z5A7Nn5iuO5ROX3Boye0u+uYQLOSfgFl7SuFZCjlAVbQA==",
"requires": {
"@types/retry": "0.12.1",
"retry": "^0.13.1"
}
},
"p-try": { "p-try": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
@@ -14998,11 +15057,6 @@
"resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz",
"integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==" "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ=="
}, },
"retry": {
"version": "0.13.1",
"resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz",
"integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg=="
},
"reusify": { "reusify": {
"version": "1.0.4", "version": "1.0.4",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",

View File

@@ -11,6 +11,7 @@
}, },
"dependencies": { "dependencies": {
"@next-auth/mongodb-adapter": "1.0.3", "@next-auth/mongodb-adapter": "1.0.3",
"@sendgrid/mail": "^7.7.0",
"autoprefixer": "10.4.7", "autoprefixer": "10.4.7",
"classnames": "2.3.1", "classnames": "2.3.1",
"date-fns": "2.28.0", "date-fns": "2.28.0",
@@ -22,7 +23,6 @@
"next-auth": "4.6.1", "next-auth": "4.6.1",
"next-mdx-remote": "4.0.3", "next-mdx-remote": "4.0.3",
"nodemailer": "6.7.5", "nodemailer": "6.7.5",
"p-retry": "5.1.1",
"react": "18.2.0", "react": "18.2.0",
"react-calendar": "3.7.0", "react-calendar": "3.7.0",
"react-dom": "18.2.0", "react-dom": "18.2.0",