firebase - 使用Firebase云功能实现发送电子邮件

标签 firebase google-cloud-functions

对于我们的网络应用程序,我们目前正在使用Firebase的免费计划,并且需要发送有关各种事件/触发器的电子邮件。问题是,我认为Mailgun及其云功能可以很好地完成此任务,但是看来只有在Firebase的付费计划中才可以使用其API,而当我们的应用仍在开发中时,我们现在不打算使用该计划。因此,我们有点不了解如何使用Firebase以最少的钱来实现电子邮件功能(如果我们不清楚我们的应用程序是否会带来任何利润,我们总是可以支付或支付更多)。 ..有人可以(几乎)免费的方式帮助我吗?我们以后可以随时升级吗?

谢谢!
Piyush Soni

最佳答案

我在个人投资组合网站中使用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",
                });
            }
        }
    );
}

关于firebase - 使用Firebase云功能实现发送电子邮件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44833384/

相关文章:

javascript - 如何在 node.js 和 Cloud Functions for Firebase 上获取正确的日期和月份?

Swift 4 和 Firebase 附加所有带有用户名和个人资料图像错误的帖子

java - 如何修复在类 com.example.chatappfirebase.Model.User 上找不到 id 的 setter /字段?

javascript - 如何使用云功能向 Mailchimp 事件添加新用户?

google-cloud-platform - 如何将 Google Cloud Functions 与自定义 Google Cloud 端点结合使用?

android - firebase 监听器实际上是如何工作的?

javascript - Firebase数据库返回null;刷新后,它返回正确的值

python - 从云源存储库部署时不会触发 Firestore 云功能

javascript - 创建一个 firebase 函数以在数据库中设置负服务器时间戳但保持 NaN

python - 如何从谷歌云 Composer 调用云功能?