How to get Realm Trigger + Webhook to work together?

Hi all,

After spending some time searching I couldn’t find a clear way forward so here goes:

  1. I will have a realm trigger querying my Atlas db daily.
  2. I want to send the results of the trigger to my backend node server, (currently running on my local machine -> will be eventually deployed, not sure where yet).

Any idea on how to send the results to my backend?

Thanks!

Hi @Al_B and welcome in the MongoDB Community :muscle: !

Humm I think you are doing this the other way around. When the backend node server needs the data, he can consume a REST (webhook) or a GraphQL API for example to retrieve the data it needs.

I guess you could also send a POST command to your backend though with the data when it’s ready.

In this scenario, you don’t need a webhook. You just execute a function with the trigger that sends a POST command to your backend which needs to be listening, of course.

Cheers,
Maxime.

This worked!

However, when trying to send an array, it’s sending just an empty response.
When I return the array to the console, it’s full. Any clue what’s going here?

exports = function() {
  const mongodbAtlas = context.services.get("mongodb-atlas");
  const auctions = mongodbAtlas.db("myFirstDatabase").collection("items");
  //Date now
  var now = new Date();
  //Get customer with last bid
  const findHighestBidder = auctions.aggregate([
    {$match: { $and: [ 
       {endDate: {$lt: now}}, 
       {status: "active" }
    ] }},
    { $project : { status: 1, bidHistory: 1 } },
    {$addFields : {bidHistory : {$reduce : {
        input : "$bidHistory", 
        initialValue : {bid : 0}, 
        in : {$cond: [{$gte : ["$$this.bid", "$$value.bid"]},"$$this", "$$value"]}}
    }}}
])
    const result = findHighestBidder.toArray

   //This returns the results as expected
    return result
   //This returns: "{ results: {} }"
    return context.http.post({
    url: "http://27b1e5a30df2.ngrok.io/api/stripe/test",
    body:  {result} ,
    encodeBodyAsJSON: true
  })
};

I think you have a couple of issue in the above piece of code.

  1. toArray is a function so you need the parenthesis:
const result = findHighestBidder.toArray()
  1. toArray() returns a promise, not the actual result. See this example. So currently, your variable result that you use to populate your body doesn’t contain what you think it contains.

Cheers,
Maxime.

Hi Maxime,

I made the following changes. When I return the function, I get the array. When I return the POST method, the body is still empty.

const findHighestBidder = auctions.aggregate(pipeline).toArray()
    .then((results) => {
      return results
    })
    .catch(err => console.error(err))
    
//I get the desired array here
    return findHighestBidder

//Results is still returning nothing    
    return context.http.post({
    url: "http://679339cf1551.ngrok.io/api/stripe/test",
    body:  {Results: findHighestBidder} ,
    encodeBodyAsJSON: true
  })

I could be wrong, but maybe your need to stringify the docs in the body?

I have something like this in one of my function:

  coll.find(query, project).sort(sort).toArray()
    .then( docs => {
      response.setBody(JSON.stringify(docs));
      response.setHeader("Contact","devrel@mongodb.com");
    });

It’s an HTTP service implemented in Realm so here I have a payload and a response object.

exports = function(payload, response) { ... }

That’s why I have a response object here. Here the backend calls this GET webhook and I provide an HTTP answer.

The issue is that findHighestBidder is a promise, not a string (or whatever other type the server expects body.Results to be). You need to either:

  • await the Promise (requires an async function)
    exports = async function() {
      ...
      const findHighestBidder = await auctions.aggregate(pipeline).toArray();
      return context.http.post({
        url: "http://679339cf1551.ngrok.io/api/stripe/test",
        body:  { Results: findHighestBidder },
        encodeBodyAsJSON: true
      })
    }
    
  • return the Promise from the function and return the result of the http.post call from within the Promise’s .then() callback
    exports = function() {
      ...
      return auctions.aggregate(pipeline).toArray().then(results => {
        return context.http.post({
          url: "http://679339cf1551.ngrok.io/api/stripe/test",
          body:  { Results: results },
          encodeBodyAsJSON: true
        })
      })
    }
    
1 Like

Excellent, this worked! Thanks so much :grinning:

1 Like

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.