I want to create a simple CRUD App which does two things once the user enters an item to a to-do list:
The tech stack is Next, Supabase, Mailgun. The basic idea is to combine two already existing quick start examples, see details here.
I place this file under the ./components
directory.
import FormData from "form-data"
import Mailgun from "mailgun.js"
const API_KEY = "secret"
const DOMAIN = "secret.mailgun.org"
export async function sendEmail(email: any) {
console.log(API_KEY)
console.log(DOMAIN)
const mailgun = new Mailgun(FormData)
const client = mailgun.client({ username: "api", key: API_KEY })
const messageData = {
from: ` Contact <contact@${DOMAIN}>`,
// to: specified email
subject: "new item!",
text: `Hello! Here is the new item${item}.
`,
}
try {
const emailRes = await client.messages.create(DOMAIN, messageData)
console.log(emailRes)
} catch (err: any) {
console.log("an error")
console.log(err)
}
}
I then import and call sendEmail()
in a fellow component, TodoList.tsx
.
This console logs a {status: 200} message, and moments later my specified email receives the email.
But when I use a .env and .env.local instead, i.e. change the API_KEY and DOMAIN to:
require("dotenv").config()
// I understand I should not use "NEXT_PUBLIC_", but just for illustration purpose.
const API_KEY = process.env.NEXT_PUBLIC_MAILGUN_API_KEY as string
const DOMAIN = process.env.NEXT_PUBLIC_MAILGUN_DOMAIN as string
Mailgun gives me a {status: 401} error (unauthorised), even though:
Why? Why would using a .env file change the behaviour of Mailgun.js?
I have thought about whether client/server components may be causing the issue. But the issue persists whether I add 'use client' or 'use server' right after the export async function sendEmail(email: any) {
line.
I have considered getting mailgun.js to return a more meaningful error message, but am unsuccessful.
My reasoning was correct. I was stymied by an unmatched trailing " for the API key on my .env file.