【问题标题】:Implementing sending email with Firebase cloud functions使用 Firebase 云功能实现发送电子邮件
【发布时间】:2017-12-03 15:24:26
【问题描述】:

对于我们的网络应用,我们目前使用 Firebase 的免费计划,并且需要发送有关各种事件/触发器的电子邮件。问题是,我认为 Mailgun 与他们的云功能一起完美地完成了这项任务,但看起来他们的 API 只能与 Firebase 的付费计划一起使用,当我们的应用程序仍在开发中时,我们现在不打算使用它.因此,我们在不知道如何用最少的钱用 Firebase 实现电子邮件功能的知识的情况下陷入了困境(当我们对我们的应用程序是否会产生任何利润有点清楚时,我们总是可以支付或支付更多)。 .. 任何人都可以帮助我。现在以(几乎)免费的方式来做这件事——我们以后可以随时升级吗?

谢谢! 皮尤什索尼

【问题讨论】:

    标签: firebase google-cloud-functions


    【解决方案1】:

    如果您升级到 Blaze 计划,您只需为使用的内容付费,特别是对于 Cloud Functions,您仍然可以获得免费层级的执行次数。

    我不知道您的应用程序的具体情况,但在大多数应用程序的开发过程中,您每月产生的费用不太可能超过几美元(可能只有几美分)。

    【讨论】:

    • 无论如何,Google Cloud Platform 都会在第一年为您提供可观的信用额度,这样您就可以享受 OP 正在寻找的几乎免费的层级。
    【解决方案2】:

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

    【讨论】:

    • 嗨 Carlos,您能分享您发送电子邮件的表单 html 和 ts 文件吗??
    • @Serkanünal 它正在处理my site,你可以在那里查看。
    • 嗨@Carlos Eduardo Casallas Fonsec;
    • @CarlosCasallas 你的 标签有效吗?我似乎可以解析我的电子邮件模板中的任何 html
    • 我不断收到错误“错误:getaddrinfo ENOTFOUND ...”(在函数日志中),还注意到“未配置计费帐户。无法访问外部网络并且配额受到严格限制” .在我切换到火焰计划后,一切正常。我不得不说我使用的是非谷歌 SMTP 服务器,所以也许如果你使用谷歌服务器它可以工作,因为它可能不必去外部网络......
    猜你喜欢
    • 2020-11-22
    • 2018-11-15
    • 2021-06-18
    • 2018-10-16
    • 2019-04-20
    • 1970-01-01
    • 2018-12-19
    • 2021-08-14
    • 2019-08-08
    相关资源
    最近更新 更多