Express, bindEnvironment, wrapAsync and validated methods

Hi,

I’m trying to set up a validated meteor method to be triggered via SMS. I have so far:

  1. Set up a POST endpoint using Express
  2. Set up Twilio to trigger that endpoint (working successfully)
  3. The last step is to call the validate method in question. When doing so, the method errors out with the message:

Error: Meteor code must always run within a Fiber. Try wrapping callbacks that you pass to non-Meteor libraries with Meteor.bindEnvironment.

I’ve done some reading, looked at https://themeteorchef.com/tutorials/synchronous-methods and https://www.eventedmind.com/items/meteor-what-is-meteor-bindenvironment but still can’t quite get my head around where exactly I am going wrong. If anyone can point me in the right direction, much appreciated!

Code:

export function smsTrigger() {
	//Create a new instance of express
	const app = express();
	
	// Tell express to use the body-parser middleware and to not parse extended bodies
	app.use(bodyParser.urlencoded({ extended: false }));

	// Route that receives a POST request to /sms-demo
	app.post('/sms-demo', function (req, res) {
		let sender = req.body.From;		
		let data = {
			//Data to be sent to method
		};
		//Call meteor method 
		methodName.call(data, Meteor.bindEnvironment((err, res)=>{
			if (err) {
				console.log(err);
			};
			console.log(res);
		}));
		res.set('Content-Type', 'text/plain');
		res.send('Success. Mobile added: ${sender}')
	});
	
	WebApp.connectHandlers.use(app);
}

Thanks in advance to anyone who can shed some light!

This is a pattern I’ve been using pretty successfully, although it skips the express step: Meteor webapp vs Picker vs simple:rest for REST API

Thanks to @ffxsam for this one =)

Cheers for the pointer @vigorwebsolutions!

Experimenting with that pattern - working successfully although the req body is coming up in a different way (obv, since it is not going through bodyparser). Noobie problems! I’ll do some debugging, figure it out and post a solution here!

Updated solution, thanks to Ryan from @themeteorchef -

  app.post('/sms-demo', Meteor.bindEnvironment(function (req, res) {

      //Handle the function here

  }))
1 Like

There’s an even better, generic way, by creating a middleware:

app.use(Meteor.bindEnvironment((req, res, next) => next()));

app.get("/", (req, res, next) => { ...usual code... })
2 Likes

Excellent, thank you