W
Wasp•2d ago
Kynetix

Mailgun send email issue

Hi all, I created a simple backend function for sending emails as so: import { Email, emailSender } from 'wasp/server/email'; export const sendEmail = async (to: string, subject: string, text: string, html: string) => { const emailToSend: Email = { to, subject, text, html, }; await emailSender.send(emailToSend); } and call it from teh frontend import { sendEmail } from './sendEmail'; ... await sendEmail(to, subject, stripHtml(message), message); However, on page load, it crashes with the error Uncaught SyntaxError: The requested module '/node_modules/.vite/deps/mailgun__js.js?v=3002b96a' does not provide an export named 'default' (at mailgun.ts:1:8) Why does this happen? Am I not implementing it correctly?
7 Replies
kapa.ai
kapa.ai•2d ago
Hi @Kynetix. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- It looks like you're encountering an issue with the Mailgun email provider in your Wasp application. The error suggests there's a problem with the Mailgun module exports. Based on the knowledge sources, here are a few things to check: 1. Email Provider Setup: Make sure you've properly configured the Mailgun provider in your main.wasp file:
app Example {
...
emailSender: {
provider: Mailgun,
}
}
app Example {
...
emailSender: {
provider: Mailgun,
}
}
2. Environment Variables: Ensure you've added the required Mailgun credentials to your .env.server file:
MAILGUN_API_KEY=your_api_key
MAILGUN_DOMAIN=your_domain
MAILGUN_API_KEY=your_api_key
MAILGUN_DOMAIN=your_domain
3. Import Issue: The error suggests a problem with importing from Mailgun. Your import statement for the email functionality looks correct:
import { Email, emailSender } from 'wasp/server/email';
import { Email, emailSender } from 'wasp/server/email';
4. Frontend vs Backend: It appears you might be trying to import server-side code on the client side. The error occurs on page load, which suggests the Mailgun module is being imported in client-side code. Email sending should only be done from server-side code (actions or queries), not directly from the frontend. Instead of importing your sendEmail function directly in the frontend, you should create a Wasp action and call that action from your frontend. The email sending logic should be contained within the action handler on the server. 5. Try the Dummy Provider: For development and testing, you might want to use the Dummy provider first to make sure your email sending logic works correctly before switching to Mailgun Sending Emails. If you continue to have issues, you could try running wasp clean and then wasp start to reinstall and recompile everything for a fresh start, as suggested in one of the Discord support threads Discord support thread. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @Kynetix, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
Kynetix
KynetixOP•2d ago
@kapa.ai I added the following to main.wasp ction sendEmail { fn: import { sendEmail } from "@src/newsletter/sendEmail" } but it's still crashing , this time with the error "error TS2344: Type '(to: string, subject: string, text: string, html: string) => Promise<void>' does not satisfy the constraint 'GenericBackendOperation'."
kapa.ai
kapa.ai•2d ago
Let me check the knowledge base for you again. One moment! :books:
MEE6
MEE6•2d ago
Wohooo @Kynetix, you just became a Waspeteer level 5!
kapa.ai
kapa.ai•2d ago
---------------------- I see the issue with your action implementation. The error is related to TypeScript types for your action function. When implementing actions in Wasp, you need to follow a specific function signature pattern. Here's how to fix your action implementation: 1. First, make sure your action declaration in main.wasp is correct (you have a typo "ction" instead of "action"):
action sendEmail {
fn: import { sendEmail } from "@src/newsletter/sendEmail"
}
action sendEmail {
fn: import { sendEmail } from "@src/newsletter/sendEmail"
}
2. Then, in your implementation file, you need to follow the correct action function signature:
import { type SendEmail } from 'wasp/server/operations';
import { emailSender } from 'wasp/server/email';

export const sendEmail: SendEmail<{
to: string;
subject: string;
text: string;
html: string;
}, void> = async (args, context) => {
const { to, subject, text, html } = args;

await emailSender.send({
to,
subject,
text,
html
});
}
import { type SendEmail } from 'wasp/server/operations';
import { emailSender } from 'wasp/server/email';

export const sendEmail: SendEmail<{
to: string;
subject: string;
text: string;
html: string;
}, void> = async (args, context) => {
const { to, subject, text, html } = args;

await emailSender.send({
to,
subject,
text,
html
});
}
The key differences from your original implementation: - Actions in Wasp expect two parameters: args (containing your input data) and context (containing user session info if authenticated) - You need to use the generated type from Wasp (in this case SendEmail) - The function signature needs to match what Wasp expects for actions When calling this action from the frontend, you would do:
import { sendEmail } from 'wasp/client/operations';

// Then in your component:
await sendEmail({
to: emailAddress,
subject: emailSubject,
text: stripHtml(message),
html: message
});
import { sendEmail } from 'wasp/client/operations';

// Then in your component:
await sendEmail({
to: emailAddress,
subject: emailSubject,
text: stripHtml(message),
html: message
});
This follows the pattern shown in the Actions documentation where actions are implemented with specific types and parameter structures. Working with Actions explains that actions are declared in Wasp and implemented in NodeJS, and Wasp generates code that allows you to call them from anywhere in your code using the same interface. Let me know if you need further clarification! ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @Kynetix, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
Carlos
Carlos•2d ago
@Kynetix bot is right 🙂 the params to your action should be inside the args object
Kynetix
KynetixOP•this hour
That did it, guys. Thanks a lot!

Did you find this page helpful?