Im trying to build a simple faye realtime based notification system so I can execute a certain javascript on certain actions.The idea is relatively simple though Im having problems implementing it, not sure wich road to take on this after reading the documentation of faye.
Current thoughts are
One unique faye channel per logged-in user, so you can push a action (popup, set text) to a certain user only
One div in my app layout that I can write text to
One div in my app that holds layout for a popup
Now I've seen the railscast tutorial about faye but ryan works from a controller/action method create. I don't want to insert stuff in the db, just call the JS function from anywhere ( building an application helper would be a good idea I think ), I would just want to do something like "execute javascript 'set_text'" and execute javascript 'show_popup'
What would be the best way to build such functionality with Faye, Basically I only have to
Execute a javascript function on a certain Faye channel
To accomplish the popup and text message.
A bit lost on this anyone can point me in the right direction or maybe have build such functionality already? thx in advanche!
On the server side, you can just do (this needs eventmachine):
client = Faye::Client.new('http://localhost:9292/faye')
client.publish('/notifications/1', 'alert(1);')
Or via HTTP:
message = {:channel => '/notifications/1', :data => 'alert(1);'}
uri = URI.parse("http://localhost:9292/faye")
Net::HTTP.post_form(uri, :message => message.to_json)
Then on the client side, you can then do anything with the data.
var client = new Faye.Client('http://localhost:9292/faye');
client.subscribe('/notifications/1', function(data) {
eval(data);
});
Just replace alert(1); with whatever JS you want to execute.
Related
Q1 - I have been reading through the docs for reCaptcha, and looking at many different forum cases but I am not experienced with API calls at all - I am trying to add a captcha to my custom contact form but I am stuck on the verification step trying to figure out how/where to send the info for verification, and how/where to receive it so I know weather or not the user is verified.
(Side Question: Why is it necessary to validate the token generated by the captcha? Isn't it good enough that you can tell weather or not the puzzle/answer was solved?)
Before the closing head tag:
<script src='https://www.google.com/recaptcha/api.js'></script>
End of my form:
<div class="g-recaptcha" data-sitekey="my-site-key"></div>
I can see the string/token generated by a correct answer when I call:
grecaptcha.getResponse();
Now (as I understand it) I have to verify this string/token which is where I get stuck:
URL: https://www.google.com/recaptcha/api/siteverify
METHOD: POST
DOCS: https://developers.google.com/recaptcha/docs/verify
I am relatively decent with jQuery and vanilla JS but when it comes to API calls I have almost no experience, which is why at this point in the docs I am unsure of how to 1 - form an/the API call (for verification), 2 - where to make the API call from template files-wise, 3 - how to get the response back, or rather how the response comes back.
As I mentioned I am using a Bigcommerce store, and the Google reCaptcha documentation mentioned in several different areas that this step is done on the server-side (or should be). I know that I am fairly restricted in the template files that I can modify - I can view and modify the HTML/CSS/JS files but I have no access to any PHP.
Any help or push in the right direction would be greatly appreciated - at this point I am going in circles finding and trying to read/follow the same docs (Google and other) and forum cases. Thank you.
Trying to answer your questions one by one.
Client side Captcha's are discussed here, please check and note that considering the power of Java Script, client side captchas are not safe.
How reCAPTCHA works: Once someone include below script, google will verify
user.
https://www.google.com/recaptcha/api.js
Writing below attributes in the Form will send data to google first and
response will be added in final post of the current Form with
attribute named g-recaptcha-response :
<div class="g-recaptcha" data-sitekey="your_site_key"></div>
How to validate reCAPTCHA One has to validate this g-recaptcha-response with google. [ NOTE: this is requried becaues
client can send any random value for attribute g-recaptcha-response
without going through Captcha ]
$verifyResponse =
file_get_contents('https://www.google.com/recaptcha/api/siteverify?
secret='.$YOUR_SECRET.'&response='.$_POST['g-recaptcha-response'])
/*allow_url_fopen must be ON if you want to use file_get_contents.
check it using phpinfo();*/
file_put_contents( "logfile", $verifyResponse, FILE_APPEND );
$responseData = json_decode($verifyResponse);
$register_result = 'Robot verification failed, please try again.';
if( $responseData->success )
{
$register_result = 'You are not a bot';
}
else $register_result = 'You are a bot.';
Captcha with HTML/JS/CSS reCaptcha will not work for you if you don't have PHP access.
Puzzles as Captcha Captcha Puzzles are also possible and such captcha's are also available but they are handled on server side.
The reCaptcha verification si to make sure that the answer you received does come from reCaptha server, that the user is not a robot, that it hasn't matured, and that it hasn't been used more than once.
All this is really important to the server running the app, more that the cliente showing the form in order to accept or reject the form to be processed.
This is why the validation has to be done on the server. The client is an unsecure environment that can be tricked so the server cannot trust it.
Besides, to do the validation you need a secret api key. As it is secret it can't be embeded into the client code.
If you don't have access to the php or cannot add and aditional php to do the validation, I don't think you can implement reCaptcha.
EDIT I
The bottom line is that client code (js, jQuery running in a browser) cannot be trusted to do any kind of validation from the server point of view.
For example suppose you implement an input element for the user to enter the result of the sum of two random integers between 0 and 9. Very simple.
In the javascript code in some place there is an:
if(a + b === c){
sendFormToServer();
}else{
reject();
}
Anyone using the browser's developer tools could bypass the "if" and directly call sendFormToServer(). And the server has no way of knowing it.
Is it possible to use your rails variables on a Mandrill template?
I have an app where a user gets notified via email on certain actions, and right now it's done with action mailer without using Mandrill so it's just a text email with no styling. Obviously, I'd prefer to use a mandrill template I already have to add some dynamic content via variables.. I see a ton of companies using variables in email notifications so i assume it's possible, i just haven't found many useful articles that explain how it's done. If you can point me towards a useful article or just answer the question it'd be really helpful! Right now, I already made the template using Mailchimp, then sent it to mandrill and it's ready for use. My app already has the Mandrill configurations and works properly (i use it for static email that don't include variables). All i really need to do is configure it to allow me to use variables.
Thanks in advance. Happy holidays and war eagle!
One way is to use the merge tags in the Mandrill template, and then either global_merge_vars (all recipients) or merge_vars (per recipients) message options to populate the template.
It is not very exciting approach, but it works fine.
In short, the solution is to put tags like:
*|MYTAG|*
anywhere in the template. Then, the send calls just need to populate the right option. Here for all participants:
mandrill = Mandrill::API.new('my_api_key')
template_name = "my-template-name"
template_content = [] # See doc, not related to the issue at hand.
message = {
to: [{email: 'smith#example.com'}],
headers: {"Reply-To" => "noreply#example.com"},
merge: true,
global_merge_vars: [
{name: 'mytag', content: "Hello, World"}
]
}
mandrill.messages.send_template(template_name, template_content, message)
This should send an email with the tag replaced with the corresponding contents (Hello, World here).
This seems like a question that would have already been asked, but I couldn't find quite what I was looking for, so I'll just go ahead and ask.
I'm trying to use angular.js to make an instant search function on my site. I want users to be able to search through Posts (by title and content, ideally) instantaneously, so after hearing about angular's ability to do this, I gave it a shot.
I have this going on in my posts.js.coffee file:
#PostListCtrl = ($scope, $http) ->
$http.get("posts.json").success (data) ->
$scope.posts = data
And this going on in the JSON doc it references (just to make sure it was working -- which it is).
data =
[
name: "Blog ex"
content: "This is my example post."
,
name: "Test posting"
content: "A different ex post"
,
name: "Test3"
content: "This has some unusual, unique vocabulary."
]
Now all I have left to do is get Rails to save an object (with name/content attributes) in the above JSON file each time a new Post is created, so that the search actually runs through meaningful data. I'm new to Rails/JSON/computer stuff and don't have a clue how to do this. I'm guessing it's in the posts controller, maybe in one of those respond_to blocks, but if anyone could point me to the right way to do this, I'd appreciate it.
If all you want is an instant search, or autocomplete functionality, you should not use Angular.js or any other JS MVC frameworks. Instead, consider using jQuery as #charliefl suggested, it's easy. A simple Ajax call will do it.
JS MVC frameworks are heavy, and you need to design the architecture from the bottom to suit them. Not worthy for such a single functionality.
To make this function work in jQuery, basically:
Listen the event on search box, say typing one or more characters
Catch the characters and use jQuery Ajax to send a POST request to a method in PostsController in Rails, say "search"
Make this method respond to JSON.
Update DOM according to server response.
What I'm trying to do:
Be able to have users subscribed to a number of different 'chat rooms' and use reverse AJAX / comet to send messages from a chat room to everyone logged into that room. (a bit more complicated but this is a similar use case).
What I'm doing:
Using Grails with JMS and Atmosphere. When a message is sent, I'm using JMS to send the message object which is received by a Grails service which is then broadcasted to the atmosphere URL (i.e. atmosphere/messages).
Obviously JMS is a bit redundant there but I though I could use it to help me filter who should retrieve the message although that doesn't really look it'll work (given that the subscriber is basically a singleton service...).
Anyway, what I need to be able to do is only send out a message to the correct subset of people listening to atmosphere/messages. A RESTful-type URL will be perfect here (i.e. atmosphere/messages/* where * is the room ID) however I have no idea how to do that with Atmosphere.
Any ideas / suggestions on how I can achieve what I want? Nothing is concrete at all here so feel free to suggest almost anything. I've even been thinking (based on the response to another question), for example, if I could do something like send out messages to a Node.js server and have that handle the reverse AJAX / comet part.
If I understand your requirements correctly the following should work (jax-rs + scala code):
1) Everyone who wants to get messages from a chat room registers for it:
#GET
#Path(choose/a/path)
def register(#QueryParam("chatroomId") chatroomId: Broadcaster) {
// alternatively, the Suspend annotation can be used
new SuspendResponse.SuspendResponseBuilder[String]()
.resumeOnBroadcast(false).broadcaster(chatroomId).scope(SCOPE.REQUEST)
.period(suspendTimeout, TimeUnit.MINUTES)
.addListener(new AtmosphereEventsLogger()).build
}
2) To broadcast a message for all the registered users, call the following method:
#POST
#Broadcast
#Path(choose/a/path/{chatroomId})
def broadcast(#PathParam("chatroomId") id: String) {
// first find your broadcaster with the BroadcasterFactory
BroadcasterFactory.getDefault().lookupAll() // or maybe there is a find by id?
broadcaster = ...
broadcaster.broadcast(<your message>)
}
I also recommend reading the atmosphere whitepaper, have a look at the mailing list and at Jeanfrancois Arcand's blog.
Hope that helps.
There is a misunderstaning of the concept of comet. Its just another publish/subscribe implementation. If you have multiple chat-rooms, then you need to have multiple "topics", i.e. multiple channels the user can register to. E.g.:
broadcaster['/atmosphere/chatRoom1'].broadcast('Hello world!')
broadcaster['/atmosphere/chatRoom2'].broadcast('Hello world!')
So I would advance you to creaet multiple channels and do not filter manually the set of users, which should retrieve messages (which is definitely not the way it should be done). You do not need to create anything on the server side on this, since the user will just register for a specific channel and receive messages, which anyone is putting into it.
I would recommend you create an AtmosphereHandler for one URL like /atmosphere/chat-room and then use the AtmosphereResource and bind an BroadcastFilter with it, lets say name it ChatRoomBroadcastFilter.
Whenever a user subscribes to a new chat room, a message would be sent to the server (from the client) telling the server about the subscription. Once subscribed, maintain the list of users <> chat room bindings somewhere on the server.
Whenever a message is broadcasted, broadcast it with the chat room id with it. The in the ChatRoomBroadcastFilter (You probably need to make this a PerRequestBroacastFilter) propagate the message to the user only if the user subscribed to the chat room. I am not sure if this clears it out. If you need code example please mention in the comments. I'll put that but that needs some time so ain't putting it right now ;).
So this seems like it should be simple. I'd like to set a public model property from javascript that's fired on the mouseover of an image.
So something like this:
Html:
...img src="<%=Model.AppDetails.Logo%>" onmouseover="showMenu(this);...
Javascript:
function showMenu(app) {
<%Model.CurrentId = app.id%> //app.id is of course undefined here
...
Or is a better approach to call a controller method to set it? If so what's the best approach? Ajax? Seems like a lot of heavy lifting for something so simple.
Appreciate the feedback.
Sharon
What exactly are you trying to do with Model.CurrentId? If you're trying to just send it back to the server when the page next sends information, use a hidden field or similar.
However, if you're trying to set a value on the server when the user mouses over an image, of course you need to use ajax or similar. How else is the server going to know what the client is doing.
If you want to use Model.CurrentId later in the same file, you will need to re-apply the template as well. Once the view is processed on the server, the client has no information from the template (the client doesn't see the <%...%> tags, those are replaced on the server before sending).
I can't imagine any scenario where you'd want to send information to the server on a mouseover unless you were going to also get information back (like an extended tooltip, or an image popup), so ajax is probably your best option.