diff --git a/package-lock.json b/package-lock.json index dae900b..07b9ea0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,7 +22,7 @@ "astro-icon": "^1.1.1", "limax": "4.1.0", "lodash.merge": "^4.6.2", - "nodemailer": "^6.9.15", + "loops": "^3.3.0", "preact": "^10.24.3", "typescript": "^5.6.3", "unpic": "^3.18.0" @@ -39,7 +39,6 @@ "@types/js-yaml": "^4.0.9", "@types/lodash.merge": "^4.6.9", "@types/mdx": "^2.0.13", - "@types/nodemailer": "^6.4.16", "@typescript-eslint/eslint-plugin": "^8.8.1", "@typescript-eslint/parser": "^8.8.1", "astro-compress": "2.3.3", @@ -3040,16 +3039,6 @@ "@types/node": "*" } }, - "node_modules/@types/nodemailer": { - "version": "6.4.16", - "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-6.4.16.tgz", - "integrity": "sha512-uz6hN6Pp0upXMcilM61CoKyjT7sskBoOWpptkjjJp8jIMlTdc3xG01U7proKkXzruMS4hS0zqtHNkNPFB20rKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/sax": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz", @@ -7398,6 +7387,15 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/loops": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/loops/-/loops-3.3.0.tgz", + "integrity": "sha512-jAVPzzz0+OH6X+lml1TTY5EkZjYGN0CiC5O8Ibx3okkepKAokXTwqpwcEZt0Np6a5EAQ/raeM59LROIYmeKpXg==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/lower-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", @@ -8820,15 +8818,6 @@ "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", "license": "MIT" }, - "node_modules/nodemailer": { - "version": "6.9.15", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.15.tgz", - "integrity": "sha512-AHf04ySLC6CIfuRtRiEYtGEXgRfa6INgWGluDhnxTZhHSKvrBu7lc1VVchQ0d8nPc4cFaZoPq8vkyNoZr0TpGQ==", - "license": "MIT-0", - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", diff --git a/package.json b/package.json index 67f069b..d6b23a2 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "astro-icon": "^1.1.1", "limax": "4.1.0", "lodash.merge": "^4.6.2", - "nodemailer": "^6.9.15", + "loops": "^3.3.0", "preact": "^10.24.3", "typescript": "^5.6.3", "unpic": "^3.18.0" @@ -52,7 +52,6 @@ "@types/js-yaml": "^4.0.9", "@types/lodash.merge": "^4.6.9", "@types/mdx": "^2.0.13", - "@types/nodemailer": "^6.4.16", "@typescript-eslint/eslint-plugin": "^8.8.1", "@typescript-eslint/parser": "^8.8.1", "astro-compress": "2.3.3", diff --git a/src/env.d.ts b/src/env.d.ts index 0b6119a..e5d74a2 100644 --- a/src/env.d.ts +++ b/src/env.d.ts @@ -6,7 +6,7 @@ type KVNamespace = import('@cloudflare/workers-types').KVNamespace; type ENV = { - SMTP: KVNamespace; + LOOPS: KVNamespace; }; // use a default runtime configuration (advanced mode). diff --git a/src/pages/api/contact.ts b/src/pages/api/contact.ts index 7799d36..16a4879 100644 --- a/src/pages/api/contact.ts +++ b/src/pages/api/contact.ts @@ -1,6 +1,5 @@ import type { APIRoute } from 'astro'; -import nodemailer from 'nodemailer'; -import type SMTPTransport from 'nodemailer/lib/smtp-transport'; +import { LoopsClient } from 'loops'; export const prerender = false; export const POST: APIRoute = async ({ request, locals }) => { @@ -24,28 +23,34 @@ export const POST: APIRoute = async ({ request, locals }) => { return new Response(JSON.stringify({ errors: errors }), { status: 400 }); } - const smtpKv = locals.runtime.env.SMTP; - const smtpHost = await smtpKv.get('host'); - const smtpUser = await smtpKv.get('user'); - const smtpPassword = await smtpKv.get('password'); - const toEmail = await smtpKv.get('toEmail'); + const loopsKv = locals.runtime.env.LOOPS; + const loopsApiKey = await loopsKv.get('api_key'); + const loopsEmail = await loopsKv.get('email'); + const loopsTransactionalId = await loopsKv.get('transactionalId'); try { - const transporter = nodemailer.createTransport({ - host: smtpHost, - port: 465, - secure: true, - auth: { - user: smtpUser, - pass: smtpPassword, + const loops = new LoopsClient(loopsApiKey as string); + + const resp = await loops.sendTransactionalEmail({ + transactionalId: loopsTransactionalId as string, + email: loopsEmail as string, + dataVariables: { + message: message as string, + from: name as string, + reply: email as string, }, - } as SMTPTransport.Options); - await transporter.sendMail({ - from: `"${name}" <${email}>`, - to: toEmail as string, - subject: 'Website Contact Me Form', - text: message as string, }); + if (!resp.success) { + console.error(JSON.stringify(resp)); + return new Response( + JSON.stringify({ + errors: { + submit: 'Unable to send message. Please try again in a few moments.', + }, + }), + { status: 500 } + ); + } } catch (err) { console.error(err); return new Response( diff --git a/wrangler.toml b/wrangler.toml index a999d00..c5c5ab0 100644 --- a/wrangler.toml +++ b/wrangler.toml @@ -2,5 +2,5 @@ compatibility_flags = [ "nodejs_compat" ] compatibility_date = "2024-09-23" kv_namespaces = [ - { binding = "SMTP", id = "fastmail-smtp" }, + { binding = "LOOPS", id = "loops" }, ]