14

I'am trying to handle http post message from Mailgun bounce webhook. When sending it to Mailgun's Postbin service all data is found of course. But I'm now sending that POST to my localhost server for development purposes and all I get is empty json array. I use Test Webhook.

Intent is to keep this simple as possible besides our main service. That for I started using nodejs/expressjs to create stand alone webservice to work as relay to receive POST messages of email bounces from Mailgun and inform admins about bounced email addresses.

Now I can't figure why I don't get the same data as is visible in Postbin.

var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var mailgun = require('mailgun-js')({apiKey: 'key-...', domain: 'mymailgundomain.com'});

app.use(bodyParser.urlencoded({
  extended: true
}));

function router(app) {
  app.post('/webhooks/*', function (req, res, next) {
    var body = req.body;

    if (!mailgun.validateWebhook(body.timestamp, body.token, body.signature)) {
      console.error('Request came, but not from Mailgun');
      res.send({ error: { message: 'Invalid signature. Are you even Mailgun?' } });
      return;
    }

    next();
  });

  app.post('/webhooks/mailgun/', function (req, res) {
    // actually handle request here
    console.log("got post message");
    res.send("ok 200");
  });
}

app.listen(5000, function(){
  router(app);
  console.log("listening post in port 5000");
});

I'm running this from Mailgun's Test Webhook using url like http://mylocalhostwithpublicip.com:5000/webhooks/mailgun

Code structure is copied from https://github.com/1lobby/mailgun-js. Probably I'm missing something fundamental here as I can't figure it out myself.

Qrila
  • 143
  • 1
  • 6

5 Answers5

16

The reason you're not seeing req.body populated is because the body-parser module does not support multipart/form-data requests. For those kinds of requests you need a different module such as multer, busboy/connect-busboy, multiparty, or formidable.

mscdex
  • 104,356
  • 15
  • 192
  • 153
  • Can you elaborate how you got this working with multer? I can receive body fields using multer, but can seem to get the attachments to come through. – skinneejoe Aug 12 '15 at 13:29
  • In my case I simply replaced body-parser with multer. I was only interested in message body and did not use any other attachments. – Qrila Sep 15 '15 at 09:38
  • body-parser supports urlencoder, see reply from 'dbarabander'. Mailgun uses this header so his answer helped me. – asktomsk Jan 19 '17 at 20:36
6

If your content-type (shown by logging console.dir(req.headers['content-type'])) is 'application/x-www-form-urlencoded', and you're using body-parser, try adding the following line:

    bodyParser = require('body-parser')
    app.use(bodyParser.urlencoded({ extended: false }))
dbarabander
  • 61
  • 2
  • 2
4

to make it work with multer, you can use .any() (version 1.1.0)

for me it worked like this: (assuming multer is included and declared as "multer")

post('/track', multer.any(),function(req, res){
   //if body is a string, parse the json
   var data=(typeof req.body=='string')?JSON.parse(req.body):req.body;
   //if data is an object but you can't verify if a field exists with hasOwnProperty, force conversion with JSON
   if(typeof data=='object' && typeof data.hasOwnProperty=='undefined')
        data=JSON.parse(JSON.stringify(data));
        //data is your object
});
O'Neill
  • 366
  • 2
  • 5
0
var multer = require('multer');  
var msg = multer();  
post('/track', msg.any(), function(req, res){ 
    console.log(req.body); 
}
Anil
  • 967
  • 10
  • 20
  • This answer turned up in the low quality review queue, presumably because you don't provide any explanation of the code. If this code answers the question, consider adding adding some text explaining the code in your answer. This way, you are far more likely to get more upvotes — and help the questioner learn something new. – lmo Sep 07 '16 at 22:16
0

I make a custom parser for get data in req.body when the Content-type = 'multipart/alternative'

https://github.com/josemadev/Multiparser/