How to notify an API user once a process has been finished? - ruby-on-rails

I have an API where users can create, what I call, orders.
I enqueue those orders and process them via Sidekiq gem. When the process is done, I currently send an email to the user. However, I am looking on how to notify him programatically.
So, sending the user a POST request to a particular endpoint, telling him that the order has been processed.
I am wondering which kind of security or other technical things I should take into account when doing this, or if there is any kind of gem that would help me on developing this.

you can check pub/sub pattern to do this...
when sidekiq finish processing then you publish an event... and you register the browser to listen to this event... which is better than sending the user a POST request to a particular endpoint, telling him that the order has been processed.
there are many libraries out there that can help you implementing the pub/sub pattern check the following...
PubNub
Pusher
Bunny
RabbitMQ
Redis
please note that you will have to use the rails app as the publisher and the front end as the subscriber ( you can check equivalent libs for JS )
and if you are interested in implementing the pub/sub within the same rails app... i've looked a lot and found that only those are the working solutions ( for app to publish and listen to his published events without getting locked in the process )
EventBus
Event_BG_Bus
Wisper
this is a post on how to use those gems to implement pub/sub pattern

Related

Twilio SDK JS, is possible to get status of participant on conference/phone?

I'm trying to get events on specific participants on the client side when they get put on hold. I can set the participant on hold on the backend via REST API, but I wonder how I can get the events of the call or participant when it changes to hold/unhold?
The Twilio Voice JavaScript SDK allows you to make voice calls from the browser, but it will not emit events like when someone is put on hold.
However there are techniques to achieve your goal:
You could create a WebSocket (bidirectional connection) from your web client to your backend, and when you put someone on hold, send an event with the details over the WebSocket. When your web client receives your event, it can update its UI.
You could use Twilio Sync to share and update state in real-time between your web client and your backend. When you put someone on hold, you can update the state on the server, and the web client can receive this update so you can update your UI. There are also other real-time database/services you could use.
You could persist state about your call in your backend and request the data from your web client every couple of seconds. When the data changes, the web client can update its UI. This is not ideal as it sends many unnecessary HTTP requests, but it works.
I recommend the first two solutions, but would avoid the 3rd which I am including for completeness.
This sounds like an interesting project, good luck!

How to dynamically and efficiently pull information from database (notifications) in Rails

I am working in a Rails application and below is the scenario requiring a solution.
I'm doing some time consuming processes in the background using Sidekiq and saves the related information in the database. Now when each of the process gets completed, we would like to show notifications in a separate area saying that the process has been completed.
So, the notifications area really need to pull things from the back-end (This notification area will be available in every page) and show it dynamically. So, I thought Ajax must be an option. But, I don't know how to trigger it for a particular area only. Or is there any other option by which Client can fetch dynamic content from the server efficiently without creating much traffic.
I know it would be a broad topic to say about. But any relevant info would be greatly appreciated. Thanks :)
You're looking at a perpetual connection (either using SSE's or Websockets), something Rails has started to look at with ActionController::Live
Live
You're looking for "live" connectivity:
"Live" functionality works by keeping a connection open
between your app and the server. Rails is an HTTP request-based
framework, meaning it only sends responses to requests. The way to
send live data is to keep the response open (using a perpetual connection), which allows you to send updated data to your page on its
own timescale
The way to do this is to use a front-end method to keep the connection "live", and a back-end stack to serve the updates. The front-end will need either SSE's or a websocket, which you'll connect with use of JS
The SEE's and websockets basically give you access to the server out of the scope of "normal" requests (they use text/event-stream content / mime type)
Recommendation
We use a service called pusher
This basically creates a third-party websocket service, to which you can push updates. Once the service receives the updates, it will send it to any channels which are connected to it. You can split the channels it broadcasts to using the pub/sub pattern
I'd recommend using this service directly (they have a Rails gem) (I'm not affiliated with them), as well as providing a super simple API
Other than that, you should look at the ActionController::Live functionality of Rails
The answer suggested in the comment by #h0lyalg0rithm is an option to go.
However, primitive options are.
Use setinterval in javascript to perform a task every x seconds. Say polling.
Use jQuery or native ajax to poll for information to a controller/action via route and have the controller push data as JSON.
Use document.getElementById or jQuery to update data on the page.

Is it possible to use 'push' services at the back-end?

I'm using pusher gem to manipulate my front-end from an external API. It works fine, no problem with that.
But the thing I wonder is if there is a possibility to use push notifications at the back-end of my application? I spent a serious amount of time investigating this but couldn't find something useful.
Let me summarize:
I have an application and another API application which is tightly interacting with other. Sometimes I want to use my API to send notification to my main application and I want to be able to manipulate data at the back-end of my main application regarding the data received from API side. These are things like 'an action was completed/started/succeed' etc...
I understand that 'pusher' receives push notifications by JavaScript at the front-end. But I believe that there must be a way to use those notifications at the back-end as well.
If there is another way (maybe Faye? Websocket) to do that I'd love to learn what it is. Any clue would be appreciated.
Is it something doable?
Thank you
Pusher is a backend system too (to "push" updates to channels)
Endpoints
I think you may be interested in endpoints
From what I can gather, it seems you're looking to trigger the transfer of data to an endpoint once an action occurs in your API? For example:
User signs up on "API" app
API app sends "notification" to main app
Main app increases user count by 1
The way I can see this working is by either using ajax, or sending a curl request to your main app's endpoint (set in routes), triggering the action:
#main_app/config/routes.rb
post "endpoint", to: "application#endpoint"
#main_app/controllers/application_controller.rb
def endpoint
#count = Option.increment!(:user_count)
end
This will allow you to manipulate your data in the backend of your "main" app
API
The tricky, non-conventional part comes when you want to send the data from your API app to your Main app (this is where you got the "pusher" idea from)
I would personally look at sending a standard HTTP request to the Main app endpoint, probably with Curl (if from the backend):
Curl on Ruby on Rails
Rails curl syntax
You may want to install curb (CUrl RuBy) here: https://github.com/taf2/curb
I could write some code if you wanted?
I had asked the same question to the Pusher's support team and I got the exact answer I was looking for.
You can install a client library on your server
(http://pusher.com/docs/client_libraries) if there is one for your
server. You can then subscribe to a client channel this way.
In my case, I use Ruby gem which can be reached from https://github.com/pusher/pusher-ruby-client .

Triggering a SWF Workflow based on SQS messages

Preamble: I'm trying to put together a proposal for what I assume to be a very common use-case, and I'd like to use Amazon's SWF and SQS to accomplish my goals. There may be other services that will better match what I'm trying to do, so if you have suggestions please feel free to throw them out.
Problem: The need at its most basic is for a client (mobile device, web server, etc.) to post a message that will be processed asynchronously without a response to the client - very basic.
The intended implementation is to for the client to post a message to a pre-determined SQS queue. At that point, the client is done. We would also have a defined SWF workflow responsible for picking up the message off the queue and (after some manipulation) placing it in a Dynamo DB - again, all fairly straightforward.
What I can't seem to figure out though, is how to trigger the workflow to start. From what I've been reading a workflow isn't meant to be an indefinite process. It has a start, a middle, and an end. According to the SWF documentation, a workflow can run for no longer than a year (Setting Timeout Values in SWF).
So, my question is: If I assume that a workflow represents one message-processing flow, how can I start the workflow whenever a message is posted to the SQS?
Caveat: I've looked into using SNS instead of SQS as well. This would allow me to run a server that could subscribe to SNS, and then start the workflow whenever a notification is posted. That is certainly one solution, but I'd like to avoid setting up a server for a single web service which I would then have to manage / scale according to the number of messages being processed. The reason I'm looking into using SQS/SWF in the first place is to have an auto-scaling system that I don't have to worry about.
Thank you in advance.
I would create a worker process that listens to the SQS queue. Upon receiving a message it calls into SWF API to start a workflow execution. The workflow execution id should be generated based on the message content to ensure that duplicated messages do not result in duplicated workflows.
You can use AWS Lambda for this purpose . A lambda function will be invoked by SQS event and therefore you don't have to write a queue poller explicitly . The lambda function could then make a post request to SWF to initiate the workflow

sendgrid_webapi event notification sendgrid

I'm having difficulty retrieving the event notifications for my SendGrid account and I'm not sure how to proceed.
I'm utilizing the sendgrid_webapi gem (https://github.com/kylejginavan/sendgrid_webapi) and I'm attempting to retrieve the event notifications for the client using the barebones implementation that the README.rdoc provides.
Very simple:
client = SendGridWebApi::Client.new(*user*, *password*)
notifications = client.event_notification.get()
return notifications
Each of the other calls (bounces, unsubscribes, etc.) work as expected, but for some reason I've been unable to retrieve anything other than the URL that I've specified within the SendGrid interface (I've enabled all events and the event notification app).
The documentation for the gem states that the options available can be found at http://sendgrid.com/docs/API_Reference/Webhooks/event.html but I've been unable to take that information and turn it into something tangible that I can use when making the call.
I feel like this is just something simple that I'm missing, but any help / guidance would be greatly appreciated.
Thanks in advance!
The API call you are trying to use is for configuring the Event Webhook, not for consuming events.
A webhook is a "push" API rather than one that you query for information. You need to setup a URL with a script that can handle HTTP posts from SendGrid in order to use the webhook.
Here is a gem called gridhook that can do what you need.

Resources