Meteor Modify Boilerplate Response with Iron Router - meteor

Using Iron Router I can add a route such as /index returns "INDEX CONTENT" from the server:
this.route('index', {
path: '/',
where: 'server',
action: function () {
this.response.end("INDEX CONTENT");
}
});
The default behaviour for a Meteor app is to return a boilerplate HTML file on the initial request to the server which contains the js/css etc required to run the web app.
What I would like to do, however, is place a string (ie "INDEX CONTENT" as above) within the boilerplate which would normally be returned by default if I hadn't added the route. To do this, I'd need to be able to modify a boilerplate response before it is sent to the client but after it is constructed by the standard meteor response mechanism.
Can anyone recommend a way to be able to do this?

You could try the inject-initial meteorite package.
From the docs:
Inject.rawModHtml(id, func). At injection time, calls func(html, res) with the full page HTML which it expects to be returned, in full, after modification. res is the current http connection response request.
I think you would use it like this.
Inject.rawModHtml('breakEverything', function(html) {
return "INDEX CONTENT";
});

Related

What path should I use for Meteor's Webapp API?

I'm using Meteor v1.9 Webapp API to have my app listen to HTTP requests, specifically from a link to the app itself from a website, let's say example.org.
The documentation says to use
WebApp.connectHandlers.use([path], handler)
Where the [path] is defined as such:
path - an optional path field. This handler will only be called on
paths that match this string. The match has to border on a / or a ..
For example, /hello will match /hello/world and /hello.world, but not
/hello_world.
My question:
Let's say my meteor application is hosted on abc.com and the POST data being sent over to it is from example.org (where the link to abc.com is as well).
For the [path] argument mentioned above, in this case, should I have it as "/example" since example.org is where my app is listening to requests from (getting the POST data)? Or does it have to be a different format? I tried the former, but it doesn't seem to be working for it, so I'm trying to find the root of the issue.
Additional information that might be useful: I know it says 'optional' so I tried omitting it, but when I tested it out via 'meteor run' where it runs off of localhost:3000, it just yielded a blank page, with no errors and a success sent back, probably because it uses a GET request instead of POST.
My code for the webapp in my meteor application is as follows:
WebApp.connectHandlers.use("/[example]", async (req, res, next) => {
userName = req.body;
res.writeHead(200);
res.end();
});
Also technically my meteor application is built/bundled and deployed as a Node.js application on the website, but that shouldn't affect anything regarding this as far as I could tell.
That path is the path (part of the URL) on your meteor server. So in your example, for instance,
WebApp.connectHandlers.use("/example", async (req, res, next) => {
userName = req.body;
res.writeHead(200);
res.end();
});
means that you will need to send your POST requests to abc.com/example.

Need to call the meteor js function from php

Is it possible to call the meteor functions from php. i need to call like this for integrate the new package on my site. the package in meteor js.
If it is possible please give the example for this
This is quite a simple one! In php you can do something with a http call such as file_get_contents("http://yoursite.com/api/yourfunction?variableOne=1");
Or even curl if you want
And in Meteor (assuming you understand Iron Router and server side routes) do something like
Router.route( "/api/yourfunction", function() { var variableOne = this.request.header.variableOne;
this.response.statusCode = 200; //Post your status code
this.response.end();}, { where: "server" });
If you are making a CORS request, remember to allow access to cross servers (don't use the wildcard *)
this.response.setHeader( 'access-control-allow-origin', '*' );
Edit: Did this answer help? If so please rate it

Accept post request with iron router

I'm trying to accept a post request from my twilio account to my application to get an xml response back. How do I respond to an incoming post request in iron router? I have read the docs and tried everything in there but I just get (Error: Not implemented on server yet). I have tried putting it on the server, on the client and in lib.:
Router (lib/router.coffee)
Router.route('/api/twilio/voice', where: 'server')
.post -> console.log 'hey'
This is due to having this.subscribe then .wait()s configured for both server and client. Look for .wait within your Router configuration scopes and make sure it only runs at the client.
Look at the code part where this happens at the iron-controller repo:
https://github.com/EventedMind/iron-controller/blob/devel/lib/controller_server.js
Also I think a better way to debug (instead of console.log) is to actually use this.response:
Router.route('/api/twilio/voice', { where: server })
.post(function() {
this.response.end('hey');
});
or even the classic format:
Router.route('/api/twilio/voice', { where: server })
.post(function(req, res, next) {
res.end('hey');
});
Edit: Issue filed here and PR here.

Meteor: what code goes on the client side and server side?

I just don't know exactly what I should put on the server side and what on the client side. I understand that the templates goes on the client side. But what about the javascript code? Can you give me an example of some code going on the server side?
You can write all your business logic and complex database operations in your server side code. Typically the code you don't want to serve to the client.
For example.
Method calls
# client-side
Template.post.events({
"click #add-post": function(e) {
var post, post_object;
post = $("#post-message").val().trim();
post_object = {
user_id: Meteor.userId(),
post: post
};
Meteor.call("create_post", post_object,(function(error, response) {
if(error){
..do something
}else{
.. do something else
});
);
}
});
# server-side
Meteor.methods({
create_post: function(post_object) {
return Posts.insert(post_object);
}
});
publish / subscribe
# common
Posts = new Mongo.Collection("posts");
# client-side
Meteor.subscribe("posts");
# server-side
Meteor.publish("posts", function(limit) {
return Posts.find({
user_id: this.userId
});
});
Html, css and Template managers should go into the client-side code. Meteor methods and publishers should go into the server-side code. Read more about structuring the app and data security in official docs.
Here is an example for a collection: Declare, publish and subscribe to it.
Server and client (any directory except private, client, or server, don't use public for that too), declare the collection:
Rocks = new Meteor.Collection('rocks');
Server-side (server directory or in a Meteor.isServer condition) ,publish the collection:
Meteor.publish('allRocks', function()
{
return Rocks.find();
}
Client-side (client directory or in a Meteor.isClient condition), subscribe to the publication:
Meteor.subscribe('allRocks');
You can find a lot of examples in the documentation or in this blog (Discover Meteor).
Edit: For more precision according to OP's question... All code is shared by default (executed by both the server and the client). However, files in the server and private directory will never be sent to the client.
if create a directory named client that goes only to client.
if you create a directory named server that goes only to server.
every thing else you code goes to client and server both. (even if
you use Meteor.isServer check)
you can read more about directory structure here.
You use Meteor.isClient and Meteor.isServer to load the code in the proper place.
Using the folder:
server - goes to the server duh!
client - goes to the client duh!
both - shared code
Everything that is placed outside client or server, is loaded on both places.
When you create Meteor package you've to add manually the files and specify where it should be loaded, example:
api.add_files(['my-packages.js', 'another-file.js'], 'client');
api.add_files(['server/methods.js'], 'server');
On this example althouhg you have a server folder, it doesn't mean that it be placed in the server, in the package scenario.
Something you've code that is going to run on the client and server but some functionalities might only be present at server or client.
Example:
ImageManager = {
uploadImageToAmazonS3 : function(){
if(Meteor.isServer){
//your code goes here
//YOU DON'T WANT TO SEND YOUR AMAZON PRIVATE KEY TO THE CLIENT
//BAD THINGS CAN HAPPEN LIKE A HUGE BILL
var amazonCredentials = Config.amazon.secretKey;
}
else{
throw new Error("You can't call this on the client.");
}
}
}
This a scenario where you can add functions that the client can do like: resizeImage, cropImage, etc and the server can also do this, this is shared code. Send a Private API KEY to the client is out of question but this file will be shared by the server and client.
Documentation: http://docs.meteor.com/#/basic/Meteor-isServer
According to the documentation this doesn't prevent the code from being sent to client, it simply won't run.
With this approach an attack knows how things work at the server and might try an attack vector based on the code that you sent to the him.
The best option here is extend the ImageManager only on the server. On the client this function shouldn't even exist or you can simply add a function throwing an error: "Not available".

How do I access Request Parameters in Meteor?

I am planning to use Meteor for a realtime logging application for various
My requirement is pretty simple, I will pass a log Message as request Parameter ( POST Or GET) from various application and Meteor need to simply update a collection.
I need to access Request Parameters in Meteor server code and update Mongo collection with the incoming logMessage. I cannot update Mongo Collection directly from existing applications, so please no replies suggesting the same.I want to know how can I do it from Meteor framework and not doing it by adding more packages.
EDIT: Updated to use Iron Router, the successor to Meteor Router.
Install Iron Router and define a server-side route:
Router.map(function () {
this.route('foo', {
where: 'server',
action: function () {
doSomethingWithParams(this.request.query);
}
});
});
So for a request like http://yoursite.com/foo?q=somequery&src=somesource, the variable this.request.query in the function above would be { q: 'somequery', src: 'somesource' } and therefore you can request individual parameters via this.request.query.q and this.request.query.src and the like. I've only tested GET requests, but POST and other request types should work identically; this works as of Meteor 0.7.0.1. Make sure you put this code inside a Meteor.isServer block or in a file in the /server folder in your project.
Original Post:
Use Meteorite to install Meteor Router and define a server-side route:
Meteor.Router.add('/foo', function() {
doSomethingWithParams(this.request.query);
});
So for a request like http://yoursite.com/foo?q=somequery&src=somesource, the variable this.request.query in the function above would be { q: 'somequery', src: 'somesource' } and therefore you can request individual parameters via this.request.query.q and this.request.query.src and the like. I've only tested GET requests, but POST and other request types should work identically; this works as of Meteor 0.6.2.1. Make sure you put this code inside a Meteor.isServer block or in a file in the /server folder in your project.
I know the questioner doesn't want to add packages, but I think that using Meteorite to install Meteor Router seems to me a more future-proof way to implement this as compared to accessing internal undocumented Meteor objects like __meteor_bootstrap__. When the Package API is finalized in a future version of Meteor, the process of installing Meteor Router will become easier (no need for Meteorite) but nothing else is likely to change and your code would probably continue to work without requiring modification.
I found a workaround to add a router to the Meteor application to handle custom requests.
It uses the connect router middleware which is shipped with meteor. No extra dependencies!
Put this before/outside Meteor.startup on the Server. (Coffeescript)
SomeCollection = new Collection("...")
fibers = __meteor_bootstrap__.require("fibers")
connect = __meteor_bootstrap__.require('connect')
app = __meteor_bootstrap__.app
router = connect.middleware.router (route) ->
route.get '/foo', (req, res) ->
Fiber () ->
SomeCollection.insert(...)
.run()
res.writeHead(200)
res.end()
app.use(router)
Use IronRouter, it's so easy:
var path = IronLocation.path();
As things stand, there isn't support for server side routing or specific actions on the server side when URLs are hit. So it's not easy to do what you want. Here are some suggestions.
You can probably achieve what you want by borrowing techniques that are used by the oauth2 package on the auth branch: https://github.com/meteor/meteor/blob/auth/packages/accounts-oauth2-helper/oauth2_server.js#L100-109
However this isn't really supported so I'm not certain it's a good idea.
Your other applications could actually update the collections using DDP. This is probably easier than it sounds.
You could use an intermediate application which accepts POST/GET requests and talks to your meteor server using DDP. This is probably the technically easiest thing to do.
Maybe this one will help you?
http://docs.meteor.com/#meteor_http_post

Resources