javascript - 在 firestore 错误时使用 sendgrid 发送电子邮件
问题描述
我目前正在为一个朋友开发一个网站,他有一家代客公司。我正在为他创建一个网站,以便人们可以上网并为他们的位置请求私人活动,例如家庭聚会或聚会。
请求部分已经完成,但现在他问我是否可以让网站在每次有新请求时向他发送电子邮件,而不是去网站登录然后从那里继续。
我了解到您可以使用 sendgrid 发送电子邮件。我正在为我的项目使用 firebase/firestore。我已经安装了@sendgrid/mail 并创建了一个 JS 文件来查看电子邮件服务是否有效。
我创建只是为了看看我是否可以发送电子邮件。如果我用节点和终端运行它的代码,它工作得很好
我继续将代码添加到客户端的 JS 文件中。我做了一些研究,发现我不能在客户端使用 require 并且看到如果我安装 require.js 它将允许我这样做。
然后我安装了 requirejs 并继续将相同的代码添加到包含客户端 html 的新 JS 文件中。
我一开始遇到了这个错误
" 模块名称 "@sendgrid/mail" 尚未加载上下文:_。使用 require([] )"
然后我阅读了错误并尝试添加“[]”。这把我带到了我现在卡住的地方这显示了所有添加了“[]”的代码。我现在收到一个新错误,类似于此代码图片 这是我现在遇到的错误
这是我的 JS 文件,它位于客户端,带有 sendgrid/mail。
const sgMail = require(['@sendgrid/mail']);
const API_KEY = '';
sgMail.setApiKey(API_KEY);
(function(){
//configuration file for firebase. The way we acess the app location in the database
var firebaseConfig = {
apiKey: "",
authDomain: "",
projectId: "",
storageBucket: "",
messagingSenderId: "",
appId: "",
measurementId: ""
};
//firebase initialiaztion. The way we initialize
firebase.initializeApp(firebaseConfig);
var db = firebase.firestore();
const email = document.getElementById('emailTxt');
const firstName = document.getElementById('firstNameTxt');
const lastName = document.getElementById('lastNameTxt');
const firstPhone = document.getElementById('numberTxtArea');
const secondPhone = document.getElementById('numberTxtMiddle');
const thirdPhone = document.getElementById('numberTxtEnd');
const location = document.getElementById('locationTxt');
const numberOfCars = document.getElementById('carCount');
const numberOfPeople = document.getElementById('peopleCount');
const startTime = document.getElementById('starTime');
const endTime = document.getElementById('endTime');
const parking = document.getElementById('availability');
const details = document.getElementById('details');
const submitQuoteBtn = document.getElementById('requestQuoteBtn');
const succesfullySubmited = document.getElementById('requestConfirm');
submitQuoteBtn.addEventListener('click', e=>{
const emailValue = email.value;
const firstNameValue = firstName.value;
const lastNameValue = lastName.value;
const firstPhoneValue = firstPhone.value;
const secondPhoneValue = secondPhone.value;
const thirdPhoneValue = thirdPhone.value;
const phoneNumber = firstPhoneValue + "-" + secondPhoneValue + "-" + thirdPhoneValue;
const locationValue = location.value;
const numberOfCarsValue = numberOfCars.value;
const numberOfPeopleValue = numberOfPeople.value;
const startTimeValue = startTime.value;
const endTimeValue = endTime.value;
const parkingValue = parking.value;
const detailsValue = details.value;
var datePlaced = new Date();
var dd = datePlaced.getDate();
var mm = datePlaced.getMonth() +1;
var yyyy = datePlaced.getFullYear();
var fullDate = (mm + "-" + dd + "-" + yyyy);
const message = {
to: '',
from: '',
subject: 'New Private EVENT',
text: "hi",
html: "hello",
};
sgMail.send(message)
.then((response) => console.log('Email sent'))
.catch((error) => console.log(error.message));
db.collection("Manager").doc("Quote").collection("Quotes").doc((firstNameValue + " " +
lastNameValue)).set({
email: emailValue,
firstName: firstNameValue,
lastName: lastNameValue,
phone: phoneNumber,
location: locationValue,
numberOfCars: numberOfCarsValue,
numberOfPeople: numberOfPeopleValue,
startTime: startTimeValue,
endTime: endTimeValue,
parking: parkingValue,
details: detailsValue,
date: fullDate,
}).then(() =>{
console.log("i am here 6");
console.log("document written successfully");
succesfullySubmited.style = "visible";
}).catch((error) => {
console.log(error);
})
});
})()
这是我连接到js文件的html文件
<!DOCTYPE html>
<html lang="en">
<head>
<link rel = "stylesheet" href="RCMA.css" >
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Providing proffesional valet services around the Cleveland
Area. Restaurants, Private events, and more">
<title></title>
</head>
<body>
<script src="https://www.gstatic.com/firebasejs/8.3.1/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.3.1/firebase-firestore.js"></script>
<script src="scripts/require.js"></script>
<div class= "banner">
<div class="navbar">
<img src="pictures/rcmalogo.jpeg" class= "logo">
<ul>
<li><a href="index.html">Home</a></li>
<li><a href="contact.html">Contact</a></li>
<li><a href="Quote.html">Get a Quote</a></li>
<li><a href="AboutUs.html">About Us</a></li>
<li><a href="SignIn.html">Sign In</a></li>
</ul>
</div>
<div class="inputBoxes">
<input type="email" id="emailTxt" class="emailTxt" placeholder="Email..." /> <br>
<input type="textfield" id="firstNameTxt" class="firstNameTxt" placeholder="First Name..." />
<input type="textfield" id="lastNameTxt" class="lastNameTxt" placeholder="Last Name..." /><br>
<input type="textfield" id="numberTxtArea" class="numberTxtArea" placeholder="###" />
<input type="textfield" id="numberTxtMiddle" class="numberTxtMiddle" placeholder="###" />
<input type="textfield" id="numberTxtEnd" class="numberTxtEnd" placeholder="####" /> <br>
<input type="textfield" id="locationTxt" class="locationTxt" placeholder="Location..." /><br>
<input type="textfield" id="carCount" class="carCount" placeholder="Estimated # of Cars..." /><br>
<input type="textfield" id="peopleCount" class="peopleCount" placeholder="Estimated # of People..." /><br>
<input type="textfield" id="starTime" class="starTime" placeholder="Event Start time..." />
<input type="textfield" id="endTime" class="endTime" placeholder="Event End Time..."/><br>
<input type="textfield" id="availability" class="availability" placeholder="Parking Availability..."/> <br>
<input type="textfield" id="details" class="details" placeholder="Details / Questions..."/><br> <br> <br>
<button id="requestQuoteBtn"> Request Quote</button>
<h1 id="requestConfirm" style="display: none;" >Submited Succesfully! </h1>
</div>
</div>
</body>
<script type="module" src="scripts/quote.js"></script>
</html>
解决方案
您需要从您控制的后端(Node.js 服务器,或者更简单的云函数)执行此操作。并且您需要为 Node.js 使用 Sendgrid APi。
此外,您不应在前端代码中共享您的 Sendgrid API 密钥,因为可以轻松阅读源代码。
因此,发送电子邮件的简单云函数将是这样的:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const sgMail = require('@sendgrid/mail');
sgMail.setApiKey(functions.config().sendgrid.apikey);
// See the doc for the config: https://firebase.google.com/docs/functions/config-env
// The API key is securely stored as a Cloud Function configuration item
exports.createUser = functions.firestore
.document('requests/{requestId}')
.onCreate((snap, context) => {
const newValue = snap.data();
// access a particular field as you would any JS property
const requestName = newValue.name;
const msg = {
to: 'recipient@whatevermail.com',
from: '....', // Change to your verified sender
subject: '',
html: 'Here is the name: ' + requestName // Adapt that with HTML code
}
return sgMail.send(msg)
.catch(error => {
console.log(JSON.stringify(error));
return null;
})
});
每次创建新的请求文档时,都会发送一封电子邮件。
另一种可能性是使用“触发电子邮件”Firebase 扩展。您可以在 Medium 上的“Firebase Tips & Tricks”出版物中找到,该文章解释了如何使用 Sendgrid 配置扩展。
推荐阅读
- flutter - Flutter中为什么Container不限制ListView的高度?
- excel - 如何制作单个、非重复的 Outlook 日历条目?
- cmake - CMake:如何将定义和标志作为字符串常量编译到我的 C(++) 程序中?
- android - 将 observables 列表压缩到另一个 Zip observable RxJava2
- r - 在闪亮的过滤数据表后导出xlsx
- git - 防止 git 将 LF 转换为 CRLF,反之亦然 - 并在需要时重新开始转换
- django - Django - 如何使用 HTML 选择标签过滤数据库?
- c# - 使用 ResourceDictionary.MergedDictionaries 的不同方式
- java - 如何在 Android 中通过 MediaStore API 检索和打开保存到下载的 PDF 文件?
- python - 使用 Apriori 算法没有输出