Send notification to user after a while Rails - ruby-on-rails

I have this scenario: A user buys a product and when two days have passed after the transaction has been processed, I need to send a mail notification to buyer.
At this moment my idea is to use whenever gem and check build a cron job to check in each day and if 2 days have passed and if true, cron job will send mail notification.
I don't know if is ok to do this... Can you give me better solution?

You can use ActiveJob with perform_later, like:
NotificationSendJob.set(wait: 2.days).perform_later(record)
Note that not all backends support this. You can see check feature matrix here: http://api.rubyonrails.org/classes/ActiveJob/QueueAdapters.html

Rather that using whenever,I would suggest using sidekiq which is a background processing library. The cron job has to be executed everyday(in your particular case). It doesn't consider whether a mail has to be sent or not. The job will still be executed even if no mails are to be sent, which is a wrong approach.
You can use a background processing library like sidekiq to schedule the job in the background. checkout https://github.com/mperham/sidekiq/wiki/Scheduled-Jobs

Related

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.

Sending SMS from rails app

I am building a medication reminder system using Ruby on Rails to be deployed on heroku.
Using this system a doctor will enter a patient's medication details including medication name, dose as well as timing details and the app will then notify the patient via sms when its time to take his/her medicine.
I have developed the application but I am stuck on the sms part since that involves running a process over and over again until the medication's period has elapsed.
I want to be able to run a script from a rails app that will repeatedly query the database and when it is time to send a sms it will dispatch it to the patient. This cannot function in the normal request/response web cycle.
I explored rubygems that allow developers to create background jobs such as rufus scheduler and resque but I can't seem to figure out how to go about doing this.
Please help I am open to all types of suggestions. I am using Twilio for sending sms
I don't know about resque/rufus, but I know that sidekiq has the ability to queue jobs, but have them delayed till a certain time.
https://github.com/mperham/sidekiq/wiki/Delayed-Extensions#advanced-options
You'd need to look into how exact the delay is (ie. what sidekiq's polling frequency is) depending on your needs, but I would suspect this would work well.
It would require another dynamo or whatever heroku calls it these days.
I use delayed_job using the run_at param to send scheduled SMS via Twilio from Heroku.
I have a send_message method on my message model that does the actual send with the Twilio API. I chose to create a custom job with Delayed Job so when I schedule the message:
Delayed::Job.enqueue my_custom_job, :run_at => TIME_I_WANT_TO_SEND
Using a the heroku worker to run the background task of sending has been very reliable.
Since you're deploying to Heroku, reading their documentation about scheduling jobs is a must for you:
https://devcenter.heroku.com/articles/scheduler

How to set up user onboarding emails with cron or delayed jobs?

I am trying to send email reminders to users who have not completed the sign-up process. The sign-up process has three different stages:
1. input for interested users (this will redirect them to a registration section)
2. registration section (this will redirect them to set-up profile)
3. set-up profile
If the user has not continued to the next stage in the process I would like to send an email reminder:
1. after 18 hrs
2. after 1 days
3. after 4 days
I have heard about CRON (whenever gem) and DELAYED JOBS but don't know which one to use. And most important WHY I should choose one over the other?
Please provide an example if possible.
I would write a script with all the logic for timing, what email to send, who to send it to etc.
Then schedule a cronjob every 24 hours to run the script. Don't try to use the cronjobs to do the timing of how many days after to send the message.
Well the reason why you would choose one over the other should be based on what you're trying to do and how you are doing it. As a developer, I would create new branches and experiment with both gems to see which one works better for you and your app.
FYI though. The whenever gem is not supported by Heroku and I believe delayed jobs is. That might be your deciding factor.
I suggest you write a function that checks for unfinished registrations. Then on your server, simple run a cron job every 18 hours, 1 day and 4 days (one line of script).
This cron job with call the controller that triggers the function which send reminder emails.
You could also use sidekiq as a background processor for email sending.

Rails - Implementing a real time console or logger for background tasks

I have a couple of rake tasks. I would want to be able to trigger these manually from my Rails admin. So far, this is not a problem. But those tasks contain a lot of puts and prints, and it would be cool to be able to see these in the browser as they happen.
(I have no problem rewriting the tasks to be run with delayed_job/sidekiq/redis if necessary)
Any idea how this could be achieved?
Update:
Idea #1: What about doing puts and pushing a message to Faye, and just subscribe to a specific channel in the browser? :) I'm going to use Faye soon anyways. Yes, or no? :)
In this case, it may be the best to publish your messages to Faye in a protected channel, and subscribe to that in Faye after starting the job. You may need to start the job using Delayed job or resque to launch the job asynchronously.

sidekiq background job to send email and heroku worker

Sorry for the basic question about Sidekiq's delaying ActionMailer. As per this article, Sidekiq can delay sending out emails by just saying UserMailer.delay_for(1.hour).....
Does this mean this is handled in the background now, or does it mean that it simply just delays sending the email out for an hour but once that hour comes, then the email is basically being sent like a regular ActionMailer, which slows down response time?
Or is it that if I truly want to do this in the background then I would have to do the other sidekiq stuff like putting it in a specific Worker and then firing it up that way?
Also, separately, if I do just do it via UserMailer.delay..., I presume I won't need a worker dyno on Heroku to save some money, correct?
Thanks for the help!
Yes, for emails you don't need to do anything else. It's like calling the Mailer 1 hour later. You just need to make sure you don't pass any complex objects into the mailer, for example a user object, you should only pass the user_id, because it will be stored in redis. On the Mailer fetch the user object with the given id.

Resources