Setting up email sending functionality
I'm trying to set up a simple functionality for sending email notifications. Basically, from the frontend, I want to send a notification when an action occurs. My approach was to create an api function called sendNotifications(), add it to main.wasp, then call it from the frontend as await sendNotifications(to,from,subject,message). The thing is that I need to retrieve some data from the database to add to the body of the email in the backend, so the sendNotification() function should include calls to the db (either context.entity.TableName.... or by calling the 'operational' functions).
Should the sendNotification() be in the operations file, or as an api call?
Please show me an example of the best way to implement this
6 Replies
Hi @Kynetix. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
----------------------
To implement email notification functionality in Wasp, the recommended approach is to use an Action (not an API route) for your sendNotification logic. Actions in Wasp are designed for server-side business logic, can access the database, and can be called directly from the frontend using the generated client API. This fits your use case perfectly: you want to trigger an email from the frontend, but the backend needs to fetch data from the database before sending the email.
Here's how you can implement this:
1. Declare the Action in
- Use an Action for your notification logic, not an API route. - Actions can access the database and be called from the frontend. - Use
main.wasp
You can adjust the entities list to match the tables you need to access.
2. Implement the Action in NodeJS
In src/server/actions.js
:
You can access the database via context.entities
as shown above. The emailSender.send
method is the standard way to send emails in Wasp and supports all configured providers (see docs).
3. Call the Action from the Frontend
In your React component:
4. Configure the Email Provider
In your main.wasp
file, set up the email provider (e.g., Dummy for development, SMTP, Mailgun, or SendGrid for production):
And set the required environment variables for your provider (see docs).
---
Summary:- Use an Action for your notification logic, not an API route. - Actions can access the database and be called from the frontend. - Use
emailSender.send
to send emails from your Action.
- Configure your email provider in main.wasp
and .env.server
.
For more details, see the official docs on Working with Actions and Sending Emails.
----------------------
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?@kapa.ai I noticed the actions file is a js file, not ts. Does it have to be a js file?
Let me check the knowledge base for you again. One moment! :books:
----------------------
No, your actions file does not have to be a JavaScript (.js) file—you can use TypeScript (.ts) as well. Wasp supports both JavaScript and TypeScript for implementing actions, and you can freely choose between them or even mix them within your project. The documentation and community discussions confirm that both file types are supported, and examples are provided for both
.js
and .ts
files. You just need to ensure that your import path in the Wasp file matches the actual file extension you are using (e.g., @src/actions.ts
or @src/actions.js
) Docs: Creating a New Action, Discord: Typescript vs Javascript.
So, you can implement your actions in TypeScript if you prefer.
----------------------
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?@kapa.ai I tried your sample above, but the frontend function call is asking for the context parameter, which is a parameter in the action definition. Should the context parameter be passed from the frontend, or is it available somehow via the backend?
Let me check the knowledge base for you again. One moment! :books:
----------------------
You should not pass the
context
parameter from the frontend. In Wasp, when you call an action from the frontend, Wasp automatically injects the context
on the backend for you. The context
contains things like the current user and access to entities, and is only available on the server side.
If you are seeing a TypeScript or IDE error asking for the context
parameter when calling the action from the frontend, it usually means you are either:
- Importing the action incorrectly (e.g., importing the server implementation directly instead of the generated client operation), or
- Calling the action in a context where Wasp is not handling the call (e.g., from another server function, not from the frontend).
Correct usage:
- From the frontend, import the action from wasp/client/operations
and call it with only the arguments you defined (not the context).
- The context is only passed manually when you are calling the action from another server-side function (e.g., from another action or a job) Docs: Implementing Actions, Discord: Action calling action.
Example:
Frontend (React component):
Server (action implementation):
If you are calling an action from another action or from a server-side job, then you must pass the context
manually Discord: Action calling action.
In summary:---------------------- 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?
Do not passcontext
from the frontend. Wasp handles it for you when the action is called from the client. Only passcontext
manually when calling actions from other server-side code.
Thanks, I was importing from wasp/server/operations instead of wasp/client/operations.
Works great now, thanks.