nodemailer + convex?
Hi team! sorry it's me again. im running into some bugs when i try to use nodemailer for my app.
in scenario 1, i've been running into
in scenario 2, i've been running into
does anyone know what did i do wrong? i also have
"jsx": "react",
set in my convex/tsconfig.ts. thanks! 🙏18 Replies
In scenario 2 it looks like you have a node_modules directory inside of the convex directory. You should delete that add these dependencies to the package.json outside of the convex directory.
For scenario 1, it looks like you're trying to use nodemailer, which is a Node.js library. You can use Node.js libraries by adding
"use node";
to the top of a file in the Convex directory, but you can only declare actions in that file.thanks! i will go with scenario 2. looks like im still getting scenario 1's error after deleting the node_modules. do i need to clear cache or something?
still this error for the dir above
What does the top of
sendEmail.ts
look like, are you using "use node";
? see https://docs.convex.dev/functions/actions#calling-third-party-apis-and-using-npm-packages, in order to use a Node.js package like this you'll need to add this line.Actions | Convex Developer Hub
Actions can call third party services to do things such as processing a payment
yea, i have that above. i didnt wrap an internalAction and just did it
calling it like that
is giving the node error
doing
is giving me
this type error is what you'd get if you use module as a function reference, e.g.
internal.email
instead of internal.email.sendEmail
Right now you're calling the actions like sendEmail(ctx, ...)
which means it's going to run in whatever environment myFunc
is in. Does that file have "use node"; at the top?
I'd suggest ctx.runAction(api.emails.sendEmail, {...})
instead
when you just call the function it's as though it's not an action at all, it's just a helper functionnope! i only have use node at the email/sendEmail.ts
which means i should wrap sendEmail in
action
, add "use node" at the top of the file and from the myFunc
, do ctx.runAction(api.email.sendEmail. {...})
?
should myFunc be wrapped in action
?I would not add "use node" to the file containing myFunc and just sendEmail with the other syntax, but to back up a bit
- "use node"; is a bundler directive; every module (file) in convex/ gets bundled separately, and if it has "use node"; at the top it will be bundled for Node.js instead of the Convex JS Runtime.
-
ctx.runAction()
means "run that action as RPC;" this means the called function could be in a different runtime. Just calling a function, even if it's had a internalAction
or action
wrapper applied to it, is just a function call. It doesn't even have to be async if the function wasn't async.yes, that's what im doing i only have "use node" in the sendEmail.ts. myFunc is in a diff file from sendEmail.ts
so I'd say use the RPC syntax (
ctx.runAction(internal.email.sendEmail, ...)
) and you should be set
and generally I try to use Node.js only for what I have to, because it's a bit sloweryea i think im only using it for nodemailer :/
Another note,
process.env.NODE_ENV === "development"
doesn't work in Convex: it's always "development" for now. So better to set something manually in the Convex deployment dashboard with different values for dev and prod.ok i just did what you recommended
still getting
there's no "use node" in myFunc.ts
huh, what does replacing
internal.email.sendEmail
with internal.email.sendEmail.sendEmail
do?lol this worked!!!
that type error looks like there's an extra level of nesting
Do you have a file called sendEmail or is there something weird going on
ugh right! i forgot i have a file name called sendEmail... 🤦♂️
right... sorry
i forgot i needed to camelCase filenames and confused myself lol
np! One way to get rid of this level of nesting is to make the
sendEmail
function the default export, they you're allowed to drop itthanks so much tom! im all set 🙂