From d092fefd41a744d0d27d5855a35a2a00e4116d42 Mon Sep 17 00:00:00 2001 From: Mihovil Ilakovac Date: Wed, 25 Sep 2024 15:41:24 +0200 Subject: [PATCH] Official Mailgun SDK + EU host support (#2303) --- .../server/email/core/providers/mailgun.ts | 23 +++++++++++++------ .../sdk/wasp/server/email/core/types.ts | 1 + .../templates/sdk/wasp/server/email/index.ts | 1 + .../waspComplexTest/.wasp/out/.waspchecksums | 2 +- .../wasp/dist/server/email/core/types.d.ts | 1 + .../out/sdk/wasp/server/email/core/types.ts | 1 + waspc/examples/todoApp/package-lock.json | 20 ++++++++-------- .../SdkGenerator/EmailSender/Providers.hs | 4 ++-- web/docs/advanced/email/email.md | 17 ++++++++++---- 9 files changed, 46 insertions(+), 24 deletions(-) diff --git a/waspc/data/Generator/templates/sdk/wasp/server/email/core/providers/mailgun.ts b/waspc/data/Generator/templates/sdk/wasp/server/email/core/providers/mailgun.ts index 7d008aa9f7..7c57806842 100644 --- a/waspc/data/Generator/templates/sdk/wasp/server/email/core/providers/mailgun.ts +++ b/waspc/data/Generator/templates/sdk/wasp/server/email/core/providers/mailgun.ts @@ -1,4 +1,4 @@ -import { NodeMailgun } from "ts-mailgun"; +import Mailgun from 'mailgun.js'; import { getDefaultFromField } from "../helpers.js"; import type { MailgunEmailProvider, EmailSender } from "../types"; @@ -6,17 +6,26 @@ import type { MailgunEmailProvider, EmailSender } from "../types"; export function initMailgunEmailSender( config: MailgunEmailProvider ): EmailSender { - const mailer = new NodeMailgun(config.apiKey, config.domain); - const defaultFromField = getDefaultFromField(); + const mailgun = new Mailgun(FormData); + + const mailer = mailgun.client({ + username: 'api', + key: config.apiKey, + url: config.apiUrl, + }); + return { async send(email) { const fromField = email.from || defaultFromField; - mailer.fromEmail = fromField.email; - mailer.fromTitle = fromField.name; - mailer.init(); - return mailer.send(email.to, email.subject, email.html); + return mailer.messages.create(config.domain, { + from: `${fromField.name} <${fromField.email}>`, + to: [email.to], + subject: email.subject, + text: email.text, + html: email.html, + }) }, }; } diff --git a/waspc/data/Generator/templates/sdk/wasp/server/email/core/types.ts b/waspc/data/Generator/templates/sdk/wasp/server/email/core/types.ts index dc5c965f96..292d04f4ab 100644 --- a/waspc/data/Generator/templates/sdk/wasp/server/email/core/types.ts +++ b/waspc/data/Generator/templates/sdk/wasp/server/email/core/types.ts @@ -22,6 +22,7 @@ export type MailgunEmailProvider = { type: "mailgun"; apiKey: string; domain: string; + apiUrl?: string; }; // PRIVATE API diff --git a/waspc/data/Generator/templates/sdk/wasp/server/email/index.ts b/waspc/data/Generator/templates/sdk/wasp/server/email/index.ts index d24f0b032f..fa0712469a 100644 --- a/waspc/data/Generator/templates/sdk/wasp/server/email/index.ts +++ b/waspc/data/Generator/templates/sdk/wasp/server/email/index.ts @@ -22,6 +22,7 @@ const emailProvider = { type: "mailgun", apiKey: process.env.MAILGUN_API_KEY, domain: process.env.MAILGUN_DOMAIN, + apiUrl: process.env.MAILGUN_API_URL, } as const; {=/ isMailgunProviderUsed =} {=# isDummyProviderUsed =} diff --git a/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/.waspchecksums b/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/.waspchecksums index 0717744b46..65f8003b51 100644 --- a/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/.waspchecksums +++ b/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/.waspchecksums @@ -648,7 +648,7 @@ "file", "../out/sdk/wasp/server/email/core/types.ts" ], - "871f4081d0606b9c79b7a43528de7200ab91408f471a05389e8c0150af74787b" + "2cdb06f4cf935e023ef90353c783033187e55ac75ce2fae59e30d050ea176eb1" ], [ [ diff --git a/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/dist/server/email/core/types.d.ts b/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/dist/server/email/core/types.d.ts index 30f5666643..b5e916fc1d 100644 --- a/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/dist/server/email/core/types.d.ts +++ b/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/dist/server/email/core/types.d.ts @@ -14,6 +14,7 @@ export type MailgunEmailProvider = { type: "mailgun"; apiKey: string; domain: string; + apiUrl?: string; }; export type DummyEmailProvider = { type: "dummy"; diff --git a/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/server/email/core/types.ts b/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/server/email/core/types.ts index f13e69895b..1e5dacdd75 100644 --- a/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/server/email/core/types.ts +++ b/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/server/email/core/types.ts @@ -21,6 +21,7 @@ export type MailgunEmailProvider = { type: "mailgun"; apiKey: string; domain: string; + apiUrl?: string; }; // PRIVATE API diff --git a/waspc/examples/todoApp/package-lock.json b/waspc/examples/todoApp/package-lock.json index 3dff37d255..aba879bfac 100644 --- a/waspc/examples/todoApp/package-lock.json +++ b/waspc/examples/todoApp/package-lock.json @@ -4161,11 +4161,11 @@ } }, "node_modules/axios": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", - "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", + "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", "dependencies": { - "follow-redirects": "^1.15.4", + "follow-redirects": "^1.15.6", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } @@ -5484,9 +5484,9 @@ "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==" }, "node_modules/follow-redirects": { - "version": "1.15.5", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", - "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", "funding": [ { "type": "individual", @@ -7011,9 +7011,9 @@ "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" }, "node_modules/nodemailer": { - "version": "6.9.9", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.9.tgz", - "integrity": "sha512-dexTll8zqQoVJEZPwQAKzxxtFn0qTnjdQTchoU6Re9BUUGBJiOy3YMn/0ShTW6J5M0dfQ1NeDeRTTl4oIWgQMA==", + "version": "6.9.15", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.15.tgz", + "integrity": "sha512-AHf04ySLC6CIfuRtRiEYtGEXgRfa6INgWGluDhnxTZhHSKvrBu7lc1VVchQ0d8nPc4cFaZoPq8vkyNoZr0TpGQ==", "engines": { "node": ">=6.0.0" } diff --git a/waspc/src/Wasp/Generator/SdkGenerator/EmailSender/Providers.hs b/waspc/src/Wasp/Generator/SdkGenerator/EmailSender/Providers.hs index 0af2ae1656..cea9734e70 100644 --- a/waspc/src/Wasp/Generator/SdkGenerator/EmailSender/Providers.hs +++ b/waspc/src/Wasp/Generator/SdkGenerator/EmailSender/Providers.hs @@ -64,10 +64,10 @@ mailgun = } where mailgunVersionRange :: SV.Range - mailgunVersionRange = SV.Range [SV.backwardsCompatibleWith (SV.Version 0 5 1)] + mailgunVersionRange = SV.Range [SV.backwardsCompatibleWith (SV.Version 10 2 3)] mailgunDependency :: AS.Dependency.Dependency - mailgunDependency = AS.Dependency.make ("ts-mailgun", show mailgunVersionRange) + mailgunDependency = AS.Dependency.make ("mailgun.js", show mailgunVersionRange) dummy :: EmailSenderProvider dummy = diff --git a/web/docs/advanced/email/email.md b/web/docs/advanced/email/email.md index 5bc15e4746..0617bc6593 100644 --- a/web/docs/advanced/email/email.md +++ b/web/docs/advanced/email/email.md @@ -222,16 +222,25 @@ Then, get the Mailgun API key and domain and add them to your `.env.server` file #### Getting the API Key and Domain 1. Go to [Mailgun](https://www.mailgun.com/) and create an account. -2. Go to [API Keys](https://app.mailgun.com/app/account/security/api_keys) and create a new API key. -3. Copy the API key and add it to your `.env.server` file. -4. Go to [Domains](https://app.mailgun.com/mg/sending/domains) and create a new domain. -5. Copy the domain and add it to your `.env.server` file. +1. Go to [Domains](https://app.mailgun.com/mg/sending/new-domain) and create a new domain. +1. Copy the domain and add it to your `.env.server` file. +1. Create a new Sending API key under `Send > Sending > Domain settings` and find `Sending API keys`. +1. Copy the API key and add it to your `.env.server` file. ```properties title=".env.server" MAILGUN_API_KEY= MAILGUN_DOMAIN= ``` +#### Using the EU Region + +If your domain region is in the EU, you need to set the `MAILGUN_API_URL` variable in your `.env.server` file: + +```properties title=".env.server" +MAILGUN_API_URL=https://api.eu.mailgun.net +``` + + ### Using the SendGrid Provider Set the provider field to `SendGrid` in your `main.wasp` file.