how can i add the sendgrid webhook event Json response in a firebase cloud firestore using node.js

Premjeet Kumar

I have no idea how to implement this thing but before that, I have done a part of SendGrid where any document is created then it will send the email to the user. but this part what I am asking I has no idea how to proceed.this is my first part of this implementation wherein any collection if a new record is created then it will send email to the particular email and there is a response called event Object I want to write a cloud function to store the data. and I don't know how to start this function or proceed with this problem.

"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: "[email protected]",
          from: "[email protected]",
          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));
  });

and the expected output of my question be like a collection name XYZ wherein an object there are three fields like

{email:"[email protected]",
event:"processed",
timestamp:123555558855},
{email:"[email protected]",
event:"recieved",
timestamp:123555558855},
{email:"[email protected]",
event:"open",
timestamp:123555558855}
Renaud Tarnec

As you will read in the Sendgrid documentation:

SendGrid's Event Webhook will notify a URL of your choice via HTTP POST with information about events that occur as SendGrid processes your email

To implement the HTTP endpoint in your Firebase Project, you will implement an HTTPS Cloud Function that will be called by the Sendgrid webhook through an HTTPS POST request.

Each call from the Sendgrid webhook will concern a specific event and you will be able, in your Cloud Function, to get the value of the event (processed, delivered, etc...).

Now, you need in your Cloud Function to be able to link a specific event with a specific email that was previously sent through your Cloud Function. For that you should use custom arguments.

More precisely, you would add to your msg object (that you pass to the send() method) a unique identifier. A classical value is a Firestore document ID, like event.params.officeId but could be any other unique ID that you generate in you Cloud Function.


Example of implementation

In your Cloud Function that sends the email, pass the officeId in a custom_args object, as shown below:

 exports.sentMail = functions.firestore
  .document("/Offices/{officeId}")
  .onCreate((documentSnapshot,event) => {

    const documentData = documentSnapshot.data();

    const officeId = event.params.officeId;

    const msg = {
          to: "[email protected]",
          from: "[email protected]",
          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;
      });
  });

Note that you get the data of the newly created document (the one which triggers the Cloud Function) through documentSnapshot.data(): you don't need to query for the same document in your Cloud Function.


Then, create a simple HTTPS Cloud Function, as follows:

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();
        })

})

Deploy it and grab its URL as shown in the terminal: it should be like https://us-central1-<your-project-id>.cloudfunctions.net/sendgridWebhook.

Note that here I use admin.firestore().collection('Offices').... You may use const db = newProject.firestore(); ... db.collection('Offices')...

Also note that the body of the HTTPS POST request sent by the Sendgrid webhook contains an array of JavaScript objects, therefore we will use Promise.all() to treat these different objects, i.e. write to the Firestore document with officeId the different events.

Then you need to set-up the Webhook in the Sendgrid platform, in the "Mail Settings/Event Notification" section, as explained in the doc and as shown below.

enter image description here

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

How to write to the Cloud Firestore using Node JS Cloud Function from Complex JSON Webhook?

How can i add DocumentID in CollectionReference of cloud firestore? Using flutter

How do I get a Webhook JSON written to the Cloud Firestore?

How can i import JSON into Cloud Firestore

how can i send an email using node and sendgrid including a link?

How can i ask a firestore request that depend on the first firebase response next.js

How to add data to firebase using node js?

How can I get the timestamp of a field in firebase cloud firestore?

How can I send a custom response from a firebase cloud function?

In Cloud Firestore how can I add a document with an explicit documentid

Sendgrid Event Webhook sends fake emails response and not real data

how can I parse the json response from facebook graph api in node.js

Add Firebase Firestore DB listener from Node.js Cloud Function

How can I add a child node to an existing json file through node js?

How can I trim this value stored in cloud Firestore using flutter?

Node.JS Firebase Cloud Function - HTTP Request - Return JSON response to client

How can I ungzip a file and send it in response in Node.js?

How can i use the data gotten from a json response in another html file using angular js

How can I remove extra slashes in my response using node?

How can I execute an add to Cloud Firestore in Cloud Functions through routes in Angular?

How I can do hosting my web app using node js with handlebars template engine on firebase

Firebase how can I add a child node with a given name?

how can i add single firebase node into listview?

How can I inspect the node.js event queue?

Can i use Cloud Firestore triggers in Cloud Functions with node 8?

How can I integrate the Google Actions responses in a webhook response in Dialogflow?

How can i add a onchange js event to Select widget in Django?

Can I do "Collection group queries" to Firestore from Cloud Function using firebase_functions_interop?

Using Node.js, how can I add values from a column in the CSV file?