对于我们的网络应用,我们目前正在使用Firebase的免费计划,并且需要发送有关各种事件/触发器的电子邮件。问题是,我认为Mailgun可以完美地完成这项任务以及他们的云功能,但看起来可以将他们的API仅用于Firebase的付费计划,我们并不打算这样做我们的应用程序仍处于开发阶段时立即使用。因此,我们在没有了解如何使用Firebase以最少的金额实现电子邮件功能的情况下陷入困境(当我们对我们的应用程序是否会获得任何利润有点明确时,我们总是可以支付或支付更多费用)...任何人都可以帮助我。现在以任何方式(几乎)自由地进行 - 我们可以在以后随时升级吗?
谢谢! Piyush Soni
答案 0 :(得分:18)
我在个人投资组合网站中使用firebase托管和云功能。我创建了一个云功能(http事件)来发送联系表单部分的电子邮件,我还没有启用结算选项,但免费报价(云功能执行)仍然足以满足我当前的需求。我通过以下方式发送电子邮件:
云功能:
const functions = require('firebase-functions');
const nodemailer = require('nodemailer');
const rp = require('request-promise');
//google account credentials used to send email
const mailTransport = nodemailer.createTransport(
`smtps://user@domain.com:password@smtp.gmail.com`);
exports.sendEmailCF = functions.https.onRequest((req, res) => {
//recaptcha validation
rp({
uri: 'https://recaptcha.google.com/recaptcha/api/siteverify',
method: 'POST',
formData: {
secret: 'your_secret_key',
response: req.body['g-recaptcha-response']
},
json: true
}).then(result => {
if (result.success) {
sendEmail('recipient@gmail.com', req.body).then(()=> {
res.status(200).send(true);
});
}
else {
res.status(500).send("Recaptcha failed.")
}
}).catch(reason => {
res.status(500).send("Recaptcha req failed.")
})
});
// Send email function
function sendEmail(email, body) {
const mailOptions = {
from: `<noreply@domain.com>`,
to: email
};
// hmtl message constructions
mailOptions.subject = 'contact form message';
mailOptions.html = `<p><b>Name: </b>${body.rsName}</p>
<p><b>Email: </b>${body.rsEmail}</p>
<p><b>Subject: </b>${body.rsSubject}</p>
<p><b>Message: </b>${body.rsMessage}</p>`;
return mailTransport.sendMail(mailOptions);
}
更新,包括联系表单和脚本:
<form class="rsForm" action="/sendEmailCF" method="post">
<div class="input-field">
<label>Name</label>
<input type="text" name="rsName" value="">
<span class="line"></span>
</div>
<div class="input-field">
<label>Email</label>
<input type="email" name="rsEmail" value="">
<span class="line"></span>
</div>
<div class="input-field">
<label>Subject</label>
<input type="text" name="rsSubject" value="">
<span class="line"></span>
</div>
<div class="input-field">
<label>Message</label>
<textarea rows="4" name="rsMessage"></textarea>
<span class="line"></span>
</div>
<input type="hidden" name="rsLang" value="en" />
<span class="btn-outer btn-primary-outer ripple">
<input class="formSubmitBtn btn btn-lg btn-primary" type="submit" data-recaptcha="global" value="Send">
</span>
<div id="recaptcha-global"></div>
</form>
处理表单提交的脚本:
$('.formSubmitBtn').on('click', function (e) {
glForm = $(this).closest('.rsForm');
var recaptchaId = 'recaptcha-' + $(this).data('recaptcha');
var rsFormErrors = false;
glFormAction = glForm.attr('action');
var rsFormFields = glForm.find('.input-field');
var rsFormName = glForm.find("[name='rsName']");
var rsFormEmail = glForm.find("[name='rsEmail']");
var rsFormMessage = glForm.find("[name='rsMessage']");
// Button ripple effect
ripple($(this).parent(), e.pageX, e.pageY);
// Reset form errors
rsFormFields.removeClass('error');
rsFormErrors = false;
// Validate form fields
if(!rsFormName.val()) {
rsFormErrors = true;
rsFormName.parent().addClass('error');
}
if(!rsFormEmail.val() || !isValidEmail(rsFormEmail.val())) {
rsFormErrors = true;
rsFormEmail.parent().addClass('error');
}
if(!rsFormMessage.val()) {
rsFormErrors = true;
rsFormMessage.parent().addClass('error');
}
if(rsFormErrors) {
// if has errors - do nothing
return false;
} else {
if(rca[recaptchaId] === undefined){
rca[recaptchaId] = grecaptcha.render(recaptchaId, {
'sitekey' : 'sitekey',
'callback' : onExecutedCaptcha,
'size' : 'invisible',
'badge':'inline'
});
} else {
grecaptcha.reset(rca[recaptchaId]);
}
grecaptcha.execute(rca[recaptchaId]);
return false;
}
});
处理recaptcha响应和表单帖子的脚本:
function onExecutedCaptcha(token) {
var sendingMsg = null, textMsg = null, textErr = null;
var lang = glForm.find("[name='rsLang']").val();
if(lang == 'es') {
sendingMsg = 'Enviando mensaje...';
textMsg = 'Tu mensaje se ha enviado con \u00e9xito!';
textErr = 'Algo ha salido mal. Intenta mas tarde';
} else {
textMsg = 'Your email was sent successfully!';
textErr = 'Oops! Something went wrong. Please try again.';
sendingMsg = 'Sending email...';
}
swal({
text: sendingMsg,
button: false,
closeOnClickOutside: false,
closeOnEsc: false,
});
$.post( glFormAction,
glForm.serialize(),
function (response) {
grecaptcha.reset();
var data = jQuery.parseJSON( response );
swal.close();
if(data){
swal({
text: textMsg,
icon: "success",
});
glForm.find("input[type=text], input[type=email], textarea").val("");
} else {
swal({
text: textErr,
icon: "error",
});
}
}
);
}
答案 1 :(得分:3)
如果您升级到Blaze计划,则只需为您使用的内容付费,而对于云功能,您将获得免费的执行层数。
我不知道您的应用程序的具体细节,但是在大多数应用程序的开发过程中,您不太可能每月收取超过几美元的费用(可能只有几美分)。