Are there existing gems or services for web hook implementations? - ruby-on-rails

Most major services like github provide Webhooks functionality.
So, with github - you can set hooks to notify you on every commit.
In the same time web hooks are not that easy.
Each web hook has to be ran asynchronously to not block web server at the time of communicating with destination. And it can take a good time (10-15 seconds). There should be implemented repeating functionality (in case if destination is not responding).
So, I think that there for sure should be some service or library which will do this for you.
Do you know any of these?
I need to send data to lots of endpoints and to receive a response from them..

You need a gem providing background job functionality. Sidekiq and Delayed Job are ones of most frequently used.
Idea is that after request (in ruby on rails you can use after_action hook or just do it in controller action) you create a job which will be executed asynchronously. Put logic you need in the job class
Both sidekiq and delayed job have repeating functionality, just pick gem that looks simpler to use

There is a gem called ActiveHook but it does not appear to be maintained anymore.
Benedikt Deicke wrote a good article on sending webhooks with Rails, you should check it.

Related

How to schedule a rake tasks in Google Cloud?

I had a Rails application on Heroku, and to schedule some rake tasks I used an add-on called Scheduler. I had to change my application to Google Cloud and I do not know how to schedule the same rakes. Could someone help me?
Reference:
https://cloud.google.com/appengine/docs/flexible/ruby/scheduling-jobs-with-cron-yaml
This will allow you to setup cron scripts that call out to a web endpoint. My suggestion would be to add an API endpoint that can trigger the code you need ran. If security is an issue, you can always add http basic auth behind the endpoint and pass it along in the URL payload from the cron.
If you wanted to get dirty with it, you could trigger the rake code from the controller itself, though I wouldn't recommend this approach as it's bad design, but instead just move all the code your executing in rake to the controller.
If the above approach doesn't fit your needs, then the next best option would be to setup a sidekiq instance and use that to schedule and run code from your codebase.

External web service for sending background emails in rails

I've used this instructions and sent "Welcome" mail to my signed up user. But this makes the user wait for 5-8 seconds because the server is trying to complete this mail thing.
I don't want the user to wait until the mail is sent but immediately see the "Mail has sent" message. So this brings me background jobs in Rails.
There are many options like delayed_job, Resque etc for background jobs in Rails. But to use these kind of solutions, as I understand:
1- Create a background job
2- Run this job
Let's say I used one of the background job solutions, so then I need something else to run also this job, like cron job...
I think just for sending sign-up and password reminder emails, another easier solution should be possible. I mean like another external service that 1- I'll create a template for each kind of mail I'll send, 2- I'll pass some arguments like receiver_email, template_id, receiver_username, password_link etc... With that way, I won't need any background job, and the user will not wait.
I came across some other gem called "sucher_punch" but as I understand from the people's messages and posted problems, with using heroku, this gem can fail for some reasons of heroku dynos and the mail may not be sent, and you don't know it.
Anyway, what is the general way that rails developers handle this email issue? Maybe I can also use sendgrid like the way I explained above, can I ?
Sending emails in the background is such a common use case, Rails 4.2 introduced a #deliver_later method in ActionMailer to provide seamless ActiveJob integration.
You don't need to set up a cron job to check if there are any jobs in the background queue. Sidekiq, Resque or DelayedJob will take care of that for you.
It seems Sendgrid does allow creating templates and sending variable content to fill them up, but that feature doesn't undermine the benefits of making that call asynchronously. In fact, deferring it to the background also has the added benefit of not disrupting user experience if the external resource(Sendgrid) is unavailable.
You should try installing one of the background processing solutions you mentioned(I recommend sidekiq) and take advantage of the ActionMailer + ActiveJob integration.

Can I use github-services hook to post my feeds to other services?

Github has developed github-services hook to push commits to other services like bugzilla, campfire, basecamp ..
Can one use the same github-services hook to push my application data to other services? If yes how may I integrate github-services to my Rails application.
Any Help ? Any suggestion ?
Update Can I integrate github-services hook source code as Sinatra application inside my Rails application ? How may I call other services(bugzilla, campfire, basecam, twitter) hooks from my application triggers ?
As example, When one user post something on other user's wall than message should be sent to the other services like bugzilla,campfire,basecamp, twitter ...
The Post-Receive Url is the simplest hook to perform such notification. It triggers a POST to a pre-configured Url whenever a pushis performed on the repository.
You could start with this Github.help page on testing web hooks to understand the format of what is being POSTed and how the service reacts. This is done thanks a very useful service: PostBin.
This help page gives a simple example of what one would have to implement on a Sinatra server to parse the POSTed JSON:
post '/' do
push = JSON.parse(params[:payload])
"I got some JSON: #{push.inspect}"
end
This gist goes a little further and show some really basic JSON data extraction.
If you want to go further, you can configure, through the GitHub API, some additional hooks to listen to more events (new issue, new fork, download, ...).
I think you are looking for an easy way to post your app's data to many other web services.
github-services is designed to take git commit information and push it to other services that accept that commit information... so if your app's data looks enough like github's payload, then those other services that work with github-services will work with your app.
But I suspect your app is not like github and your data is different than a git commit. In that case, you could make use of the code in 'services/' as examples of how to implement event handlers in your app. This one for Campfire uses the Tinder gem, for example: https://github.com/github/github-services/blob/master/services/campfire.rb
Then your WallPostsController#create could call a method that posts data in the format you choose to the various services. If you're going to post to many services, you may want to do it in an asynchronous job (DelayedJob, resque, etc.) because calls to many external services will take quite a while.

parallel asynchronous processing with callbacks in rails controller

I am making a rails app and I am wondering whether it is possible to setup an asynchronous/callback architecture in the controller layer. I am trying to do the following:
When a HTTP request is made to /my_app/foo, I want to asynchronously dish out two jobs - a naive ranking job and a complicated ranking job both of which rank 1000 posts - to several worker machines. I want to setup a callback method in the controller for each job which is called when the respective job is finished. If the complicated job does not return within X milliseconds, I want to return the output from the naive job. Otherwise, I want to return the output from the complicated job.
It is important to note that I want these jobs to performed in parallel. What is the best way to implement such a system in Rails? I am using Apache Phusion Passenger as my rails server if that helps.
Thanks.
Sounds like you should be using background jobs. In that case, when a request comes in, you would start / queue two jobs which would be picked up and processed by a worker, which acts independently of your Rails app.
Here a few links that could be of help:
https://www.ruby-toolbox.com/categories/Background_Jobs
http://railscasts.com/episodes/171-delayed-job
http://railscasts.com/episodes/243-beanstalkd-and-stalker
http://railscasts.com/episodes/271-resque
http://rubyrogues.com/queues-and-background-processing/
It's possible to issue several HTTP request asynchronously in Rails. However, it's impossible to make Rails event-driven.
In can send several HTTP request asynchronously with libraries such as Typhoeus. However, you might have concurrency issue if your timeout is too long.
Otherwise, you can try some event-driven web framework such as Cramp and Goliath. They are both based on EventMachine, so you can try em-http-request.
Try using rabbitmq where you can post a message on queue and expect the response in reply queue. The queue consumer can be even implemented in Scala for fastness. amqp gem would suffice what I am saying. Rails controller with amqp binding would be even more nice if possible(I am exploring that option having endpoints with amqp binding instead of http). That would solve enough no of problems

Suggestions for how to write a service in Rails 3

I am building an application which will send status requests to users (via email & sms) on a regular basis. I want to execute the service each hour which will:
Query the database for all requests that need to be sent (based on some logic)
Send the requests through Amazon's Simple Email Service (this is already working)
Write a record of the status request notification back to the data store
I am considering wrapping up this series of operations into a single controller with an end point that can be called remotely to kick off the process within the rails app.
Longer term, I will break this process out into an app that can be run independently of my rails app, but for now I'm just trying to keep it simple.
My first inclination is to build the following:
Controller with the following elements:
A method which will orchestrate the steps outlined above (and can be called externally)
A call to the status_request model which will bring back a collection of request needing to be sent
A loop to iterate through the pending requests, which will:
Make a call to my AWS Simple Email Service module to actually send the email, and
Make a call to the status_request model to log the request back to the database
Model:
A method on my status_request model which will bring back a collection of requests that need to be sent
A method in my status_request model which will log that a notification was sent
Since this will behave as a service that gets called periodically from an outside scheduler I don't think I'll need a view for this operation. (Will, of course, need views to show users and admins what requests have been sent, but that's later...).
As someone new to Rails, I'm asking for review of this approach and any suggestions you may have.
Thanks!
Instead of a controller which Jeff pointed out exposes a security risk, you may just want to expose a rake task and use cron to invoke it on an hourly basis.
If you are still interested in building a controller, look at devise gem and its single access token, token_authenticatable, for securing the methods you are exposing.
You may also want to look at delayed_job or resque to offload the call to status_request and the loop to AWS simple service to a background worker process.
You may want a seperate controller and view for the log file so you can review progress on demand.
And if you want to get real fancy use Amazon SNS to send you alerts when the service reaches some unacceptable level of failures, backlog, etc.
Since you are trying to invoke this from an outside process, your approach should work. You could also have a worker process that processes task when they are there.
You will need routes to expose your service, and you may want to also make security decisions. How will the service that invokes your application authenticate so all others can't hit it at will?
Another consideration should be how many emails are you sending. If there are enough, we may want to look into the fact that writing this sort of loop is going to be extremely top heavy; and may affect users on the current system if it's a web application.
In the end, there are many ways to do this. I would focus on the performance/usage you expect as well as security. There's never one perfect way to solve a problem like this, and your way should just be aware of the variables it will need to be operating within.
Resque and Redis might be helpful to you in scheduling and performing operatio n .They are simple and superfast, [here](http://railscasts.com/episodes/271-resque] is a simple tut on same.

Resources