Skip to content

Instantly share code, notes, and snippets.

@kinxori
Last active May 14, 2023 08:33
Show Gist options
  • Save kinxori/b829986cc5ed634d1974b406a516a3e5 to your computer and use it in GitHub Desktop.
Save kinxori/b829986cc5ed634d1974b406a516a3e5 to your computer and use it in GitHub Desktop.
Sending emails via Gmail using React.js and Firebase Functions. (Ignore the typescript)👺
const functions = require("firebase-functions");
const nodemailer = require("nodemailer");
const dotenv = require("dotenv"); // enable enviorment variables
dotenv.config();
const transport = nodemailer.createTransport({ // This is what is going to send your email
service: "Gmail", // We are using gmail here
auth: {
user: "user@example.com", //use your enviorment variables here
pass: "password", //use your enviorment variables here
},
});
// VERIFY IF NODEMAILER IS ACCESSING TO MY ACCOUNT WITH THE PLAIN CREDENTIALS (just to catch any error with nodemailer)
transport.verify()
.then(() => {
console.log("SMTP server connection successful");
})
.catch((error:any)=> {
console.error("SMTP server connection error:", error);
});
const sendContactForm = (form:any)=>{
return transport
.sendMail({
subject: "You got a message 👺",
bcc: "whereto@mail.com",
html: `<h3>Got a message</h3>
<p> From: ${form.email} </p> //Accessing your input data from email
<p> Message: ${form.message} </p> //Accessing your input data from message
`,
})
.then((r:any) =>{
console.log("accepted🤝", r.accepted) //Google console logs for debugging
console.log("rejected👺", r.rejected)
})
.catch((e:any)=>console.log("IF you see this theres an error 🥲",e)) //Catching more erros
}
exports.formFunction = functions.https.onRequest(async(request:any, response:any)=>{ //this is the function you gotta deploy first (formFunction)
response.set('Access-Control-Allow-Origin', '*'); // All of this is to enable the fetch to access and URL
response.set('Access-Control-Allow-Methods', 'GET, POST'); // All of this is to enable the fetch to access and URL
response.set('Access-Control-Allow-Headers', 'Content-Type'); // All of this is to enable the fetch to access and URL
console.log("body🍿", request.body) //Just making sure my data is being fetched to this point
if (request.method === "OPTIONS"){ // If methods wrong, another error catcher
response.status(204).send("");
}
else if(request.body.secret !== "secret") //Final step of validation with the previous secret
return response.json({ message:"Wrong secret 👺" });
await sendContactForm(request.body); //If secret correct, the function sendContactForm will be invoked sending your data (body)
return response.json({ message:"Sending Email 🛐" });
});
import { useEffect, useState } from "react";
import Button from "../Buttons/Button"; //Composition Component For a Button inside a Link
export default function InputForm (){
const [isEmail, setEmail] = useState("");
const [isMessage, setMessage] = useState("");
const [popUp, setPopUp] = useState("")
const handlePopUp = () => {
setPopUp("")
}
const handleSubmit = async (event:any) => {
event.preventDefault();
const { target } = event;
const form = {
email: target.email.value,
message: target.message.value,
};
const result = await fetch(
'https://your-firebase-function-link/formFunction', // You need to deploy your function first and then Firebase will generate this URL
{
method: "POST",
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ ...form, secret:"homelo" }), // Secret just for an extra validation (not necessary)
}
)
setPopUp("isShown") // Custom pop-up for confirmation
setTimeout(()=>{ // Set a timer of 5 seconds
setPopUp("");
}, 5000)
setEmail(""); // Set Email input to empty ""
setMessage(""); // Set Message input to empty ""
};
return ( //Return your input JSX
<form onSubmit={handleSubmit}> //Here you are sending your input data to the firebase function (locally)
<div>
<h3>Email: </h3>
<label>
<input
type="email"
value={isEmail}
name="email"
onChange={(event) => setEmail(event.target.value)} //This will send the value to the setEmail State
required
placeholder="email@example.com"
/>
</label>
<h3>Message:</h3>
<label>
<textarea
required
value={isMessage}
name="message"
onChange={(event) => setMessage(event.target.value)} //This will send the value to the setMessage State
placeholder="Enter your message here"
/>
</label>
</div>
<button type="submit">
Submit
</button>
{popUp === "isShown" && // This jsx will be displayed when the email is sent
<div >
<div >
<h2>Email sent! 👨‍💻</h2>
<Button onClick={handlePopUp}>
Ok
</Button>
</div>
<div></div>
</div>
}
</form>
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment