【问题标题】:how can i add the sendgrid webhook event Json response in a firebase cloud firestore using node.js如何使用 node.js 在 Firebase 云 Firestore 中添加 sendgrid webhook 事件 Json 响应
【发布时间】:2020-02-13 16:25:50
【问题描述】:

我不知道如何实现这个东西,但在此之前,我已经完成了 SendGrid 的一部分,其中创建了任何文档,然后它将电子邮件发送给用户。但这部分我要问的是我不知道如何继续。这是我这个实现的第一部分,其中任何集合如果创建了新记录,那么它将向特定的电子邮件发送电子邮件,并且有一个名为 event Object I 的响应想写一个云函数来存储数据。而且我不知道如何启动此功能或继续解决此问题。

"use strict";
const functions = require("firebase-functions");
const admin = require("firebase-admin");

var serviceAccount1 = require("./key.json");

const newProject = admin.initializeApp({
  credential: admin.credential.cert(serviceAccount1),
  databaseURL: "xyz"
});
const sgMail = require("@sendgrid/mail");
const sgMailKey = "key";
sgMail.setApiKey(sgMailKey);


 exports.sentMail = functions.firestore
  .document("/Offices/{officeId}")
  .onCreate((documentSnapshot,event) => {
    const documentData = documentSnapshot.data()
    const officeID = event.params.officeId;
    console.log(JSON.stringify(event))
    const db = newProject.firestore();
    return db.collection("Offices").doc(officeID).get()
      .then(doc => {
        const data = doc.data();
        const msg = {
          to: "amarjeetkumars34@gmail.com",
          from: "singhamarjeet045@gmail.com",
          text: "hello from this side",
          templateId: "d-8ecfa59aa9d2434eb8b7d47d58b4f2cf",
          substitutionWrappers: ["{{", "}}"],
          substitutions: {
            name: data.name
          }
        };
        return sgMail.send(msg);
      })
      .then(() => console.log("payment mail sent success"))
      .catch(err => console.log(err));
  });

我的问题的预期输出就像一个集合名称 XYZ,其中一个对象有三个字段,如

{email:"xyz@gmail.com",
event:"processed",
timestamp:123555558855},
{email:"xyz@gmail.com",
event:"recieved",
timestamp:123555558855},
{email:"xyz@gmail.com",
event:"open",
timestamp:123555558855}

【问题讨论】:

    标签: node.js firebase google-cloud-firestore google-cloud-functions sendgrid


    【解决方案1】:

    正如您将在Sendgrid documentation 中看到的那样:

    SendGrid 的 Event Webhook 将通过 HTTP 通知您选择的 URL POST 包含有关作为 SendGrid 进程发生的事件的信息 您的电子邮件

    要在您的 Firebase 项目中实现 HTTP 端点,您将实现一个 HTTPS Cloud Function,Sendgrid Webhook 将通过 HTTPS POST 请求调用该端点。

    来自 Sendgrid webhook 的每个调用都将涉及特定的 event,您将能够在您的云函数中获取事件的值(processeddelivered 等...)。

    现在,您需要在 Cloud Function 中将特定事件与之前通过 Cloud Function 发送的特定电子邮件关联起来。为此,您应该使用custom arguments

    更准确地说,您将向您的msg 对象(您传递给send() 方法)添加一个唯一标识符。经典值是 Firestore 文档 ID,例如 event.params.officeId,但也可以是您在 Cloud Function 中生成的任何其他唯一 ID。


    实施示例

    在发送电子邮件的 Cloud Function 中,将 officeId 传递到 custom_args 对象中,如下所示:

     exports.sentMail = functions.firestore
      .document("/Offices/{officeId}")
      .onCreate((documentSnapshot,event) => {
    
        const documentData = documentSnapshot.data();
    
        const officeId = event.params.officeId;
    
        const msg = {
              to: "amarjeetkumars34@gmail.com",
              from: "singhamarjeet045@gmail.com",
              text: "hello from this side",
              templateId: "d-8ecfa59aa9d2434eb8b7d47d58b4f2cf",
              substitutionWrappers: ["{{", "}}"],
              substitutions: {
                name: documentData.name
              },
              custom_args: {
                 "officeId": officeId
              }
        };
        
        return sgMail.send(msg)
          .then(() => {
             console.log("payment mail sent success"));
             return null;
          })
          .catch(err => {
             console.log(err)
             return null;
          });
      });
    

    请注意,您通过documentSnapshot.data()获取新创建的文档(触发云功能的文档)的数据:您无需在云功能中查询相同的文档。


    然后,创建一个简单的HTTPS Cloud Function,如下:

    exports.sendgridWebhook = functions.https.onRequest((req, res) => {
        const body = req.body; //body is an array of JavaScript objects
    
        const promises = [];
    
        body.forEach(elem => {
    
            const event = elem.event;
            const eventTimestamp = elem.timestamp;
            const officeId = elem.officeId;
    
            const updateObj = {};
            updateObj[event] = true;
            updateObj[event + 'Timestamp'] = eventTimestamp;
    
            promises.push(admin.firestore().collection('Offices').doc(officeId).update(updateObj));
    
        });
    
        return Promise.all(promises)
            .then(() => {
                return res.status(200).end();
            })
    
    })
    

    部署它并获取它的 URL,如终端所示:它应该类似于 https://us-central1-<your-project-id>.cloudfunctions.net/sendgridWebhook

    注意这里我使用admin.firestore().collection('Offices')...。你可以使用const db = newProject.firestore(); ... db.collection('Offices')...

    还要注意,Sendgrid webhook 发送的 HTTPS POST 请求的主体包含一个 JavaScript 对象数组,因此我们将使用 Promise.all() 来处理这些不同的对象,即使用不同的 officeId 写入 Firestore 文档事件。

    然后您需要在 Sendgrid 平台的“邮件设置/事件通知”部分中设置 Webhook,如doc 中所述,如下所示。

    【讨论】:

    • app.post('/mailevent', async(req,res)=> { try { const {email,timestamp,event} = req.body; const data = { email, timestamp, event } const maileventRef = await db.collection('mailevents').add(data); const mailevent = await maileventRef.get(); res.json({ id:maileventRef.id, data:office.data() }) } catch(err){res.status(500).send(err) }}) 你能告诉我这是你告诉我实现的方式,当我部署它时,他们给了我一个我必须粘贴的 ur生成 JSON 并将其存储到集合中?
    • @PremjeetKumar 给我大约 1 小时,因为我正在上下班,但我会给你一个答案!
    • @PremjeetKumar 抱歉,今天我无法找到答案,但明天你可以指望我!
    • 如果可能,请谢谢
    • 如果您有空,请您就我的问题向我提出任何建议
    猜你喜欢
    • 1970-01-01
    • 2019-06-04
    • 2018-11-21
    • 2021-12-15
    • 2019-10-13
    • 1970-01-01
    • 1970-01-01
    • 2022-06-21
    • 2019-08-08
    相关资源
    最近更新 更多