Unable to update a collection

I have a webhook set up that lives in imports/api in my application. This is a Stripe webhook and I’m trying update Campaign collection. I’m using a Meteor method to make this call however nothing happens. If I add the call back to it, I receive no error or results. However if I take this same Meteor Method an include it in main.js on the server in a Meteor startup function it runs fine. I’ve also tried just using the update function for a collection and it won’t work either. Main.js includes this file and I cannot figure out why this doesn’t work nor will push an error. The most important part of this line is the bottom where Paid == true, this is where the logic is. The console will spit out the information but the method won’t run. What could be the issue?

import bodyParser from 'body-parser';
import { Picker } from 'meteor/meteorhacks:picker';
import { Meteor } from 'meteor/meteor';
import {Campaign} from '../api/campaigns';

let campaignID;
let chargeAmount;
let chargeID;
let hasPaid = false;

// Middleware declaration
Picker.middleware(bodyParser.json({
  limit: '10MB',
  verify: function(req,res,buf) {
    var url = req.originalUrl;
    if (url.startsWith('/webhook')) {
      req.rawBody = buf.toString();
      let newResponse = req.rawBody;   

      //stripe returns to 2 objects, this makes it two arrays to parse it
      let parsedResponse = JSON.parse('[' + newResponse.replace(/}{/g, '},{') + ']');
      parsedResponse = parsedResponse[0].data.object;

      //break down two further objects
      if (parsedResponse.object == "charge"){
        chargeID = parsedResponse.id;
        hasPaid = parsedResponse.paid;
        chargeAmount = parsedResponse.amount / 100;
      }
      else if (parsedResponse.object == "checkout.session"){
        let campaignIDArray = parsedResponse.success_url.split('/');
        campaignID = campaignIDArray[5];
      }
      // If user has paid, update campaign
      if (hasPaid == true && chargeID && campaignID && chargeAmount){

        // This console works!
       console.log(campaignID, chargeAmount, chargeID));
        updateCampaign(campaignID, chargeAmount, chargeID);
       
        
      }
    }
  }
}));

let updateCampaign = function(campaignID, chargeAmount, chargeID){
  Campaign.update({_id: campaignID}, {$set: {chargeTrx: chargeID, amount: chargeAmount}} );
  // Meteor.call("updateCampaignForPayment", campaignID, chargeAmount, chargeID);
}

This code should work, I’m using picker for webhooks and I’m able to execute Meteor methods (but I use validated methods).

So I can’t tell exactly where its breaking without running the code, but for now, have you thought about using DirectCollection as a workaround to run the update?

Also, try keeping the Meteor.call and Campaign.update inside the picker method body (where the console message is).

Thanks, I tried having in the picker call originally, but pulled it out as I thought it may be part of the issue.

I guess you can give DirectCollection a try and see if it updates. :man_shrugging:

I’d like to bump this up. While I appreciate the advice, I’m not really intersted in finding hacky work arounds, I’m trying to understand why Meteor wouldn’t do this. It seems the same call will update on file load, but for some reason in the conditional it will not (even though a console print proves the conditional is true). Does anybody have any thoughts on why this might be? Thanks!

I’m curious why you’re doing all the work in the verify hook of body-parser?
I doubt this has anything to do with it, but you never know when doing a weird thing will give you weird bugs.

1 Like

It’s probably not the right way… I’m new to node and backend programing in general. I just saw that I could get the req data and parse it, so it seemed logical enough to create a true/false condition there to run a function.

That is a good catch :+1:

Here is how I’m using picker.


Picker.middleware(bodyParser.json());
Picker.middleware(bodyParser.urlencoded({ extended: false }));

Picker.route('/api/webhooks/:provider', ({ provider }, request, response) => {
...
1 Like

Thank you! This was way simpler than I was making it, and the collection update works inside Picker.route().

2 Likes