Delayed_Jobs will not refresh - ruby-on-rails

I had previously a mailer set up to send me emails to all user accounts. But now I'm trying to debug it. So I gutted it out completely and it still sends emails to me.
I have absolutely no reasoning or understanding as to why. Insanity! :D
controller
def org_blast_send
Delayed::Job.enqueue OrgBlast.new(params[:subject], params[:editor1])
redirect_to org_blast_admin_email_blast_path
end
org_blast.rb
class OrgBlast < Struct.new(:subject, :editor1)
def perform
# You see? There is absolute nothing here but it still sends an email.
# However, if I rename this file, the website fails looking for it.
end
end
notifier.rb
def org_blast(org, subject, message)
subject subject
from NOTIFIER_EMAIL
recipients org.users.first.email
sent_on Time.zone.now
body :user => org.users.first.first_name + ' ' + org.users.first.last_name, :message => message
content_type "text/html"
end

If you are running delayed_jobs on your local, it must be stopped and restarted or it will despite your code do whatever was in your code the last time it was started.
>> script/delayed_job stop
>> script/delayed_job start

Related

Why won't my Twilio SMS send in Sidekiq background worker?

I am having issues sending a text with Twilio through my SideKiq background worker. The worker is supposed to send a text and then send an email (with Mandrill).
The email works fine.
The text never happens.
I haven't had issues with other jobs (including ones that also involve use
of environment variables).
I haven't had issues sending Twilio texts outside of a background worker.
I'm using Foreman to start my application.
In console, running UserNotifier.new.perform(1) works fine - both the email and the text are sent.
Here is some of the code in question:
This is the class that I'm using to send my SMS:
(My Gemfile includes the twilio-ruby gem)
class SendSMS
def initialize
#twilio_client = Twilio::REST::Client.new "#{ENV['TWILIO_SID']}", "#{ENV['TWILIO_TOKEN']}"
end
def send(message, user)
#twilio_client.account.sms.messages.create(
:from => "+1#{ENV['TWILIO_PHONE_NUMBER']}",
:to => user.phone_number,
:body => message
)
end
end
My worker looks like this:
class UserNotifier
include Sidekiq::Worker
sidekiq_options queue: :immediate
def perform(user_id)
user = User.find(user_id)
message = "Hi #{user.name}!"
SendSMS.new.send(message, user)
UserMailer.send(message, user).deliver
end
end
Can anyone see an issue with my code? Please let me know if there is anything else I should post or if there is any clarification that I could make.
My server was displaying the worker logs and it didn't seem to be running into an error.
Any suggestions on how to debug background workers would be appreciated as well.
Try catching REST errors from Twilio and logging some debug info. You can discover errors that might prevent messages from sending, or investigate sent messages in your Twilio account logs via their sid (Twilio's internal id). Also updated your create call to use the messages resource instead of deprecated sms/messages.
begin
message = #twilio_client.account.messages.create(
:from => "+1#{ENV['TWILIO_PHONE_NUMBER']}",
:to => user.phone_number,
:body => message
)
logger.debug "sent #{message.sid}"
rescue Twilio::REST::RequestError => e
logger.debug "error: #{e.message}"
end

Delayed job throwing an error failed with TypeError: can't convert String into Hash

Actually I am using the delayed job to run the email process at background. When I called the delay method of delayed_job its insert the record into Delayed::Job table but mails are not going and when I check the delayed_job.log it contains "failed with TypeError: can't convert nil into Hash" error.
UserMailer.rb file contain following code
def welcome_email(user)
#username = user.name
setup_email(user)
end
In User controller
UserMailer.delay.welcome_email(User.last)
But when I removed delay method then mails are going
the code is :
UserMailer.welcome_email(User.last).deliver
I am not getting why this error is coming withe delay,please help me to find the cause of this issue.
Check your mailer configuration.
use this
def welcome_email(user)
##access hash in this way user['email']..not using dot operator user.email
#user=User.find_by_email user['email']
mail(:to => user['email'], :subject => "Hi #{user['username']},Welcome to mywebsite.com")
end
Moreover for delay You need to run the rake jobs:work task to have a process by Delayed Job work off jobs from that table. Without this, you will not receive any emails.

Options with Rails for triggering an email to all (or some) users?

Newb question: We've got a live site with registered users. Some new functionality has been added (including support for Mailers). We would like to trigger an email to all existing users (similar but not identical to one that will now automatically go out to new users).
What options do we have for triggering the sending of that email? This message will likely only be sent once so we don't need the code (other than the message itself) in the Rails app. Nor do we really need to store who received it because it will be assumed that all users have received such a message once we can get this one out.
I'm thinking Rake task but all the examples I seem to be able to find are for build script?!? Or should we just use the Rails console in production? Perhaps get an array of all users we want to send email to and then deliver message to them?
Not sure. I haven't worked with ActionMailer much.
I'd probably do it like this:
In order to determine if the system has sent an email to a user, you should add an attribute let's say 'sent_email' which is basically just a boolean.
I'd create a cron job for a rake task that checks all users with sent_email=0. Then, I'll loop through each array and send the email and set sent_email=1. The cron job can be run daily, depending on your preference. You can use whenever gem to setup the cron job.
schedule.rb (whenever stuff)
job_type :run_script, "RAILS_ENV=:environment ruby :path/script/:task"
every 1.day do
run_script('send_email.rb')
end
script/send_email.rb
#!/usr/bin/env ruby
puts "Loading rails environment..."
require(File.dirname(__FILE__) + "/../config/environment") unless defined?(Rails)
class SendEmail
def send_email
users = User.send_email_to
users.each do |user|
OneTimeMailer.deliver_one_time_email(user)
end
end
end
mailers/one_time_mailer.rb
class OneTimeMailer < ActionMailer::Base
def one_time_email(user)
recipients user.email
from 'your system'
subject 'hello world'
body 'this is a one time email. thank you'
end
end
I hope this helps.
I suggest doing a rake task, run it once and you are done.
rails g task my_namespace my_task1 my_task2
Now you loop through your database:
namespace :sent_email_to_everyone do
desc "TODO"
task send_that_mail: :environment do
user = User.all
user.each do |user|
Yourmailer.send_email(user.email)
end
end
end
end
Now you just run it and done
rake sent_that_mail

How does one use delayed_job to make an Rails 3.0 ActionMailer run asynchronously? Encountering ArgumentErrors

I'm trying to delay a notification email to be sent to users upon signing up to my app. The emails are sent using an ActionMailer which I call InitMailer. The way I am trying to delay the jobs is using collectiveidea's delayed_job https://github.com/collectiveidea/delayed_job. To do this you can see that i specify handle_asynchronously after defining the method initial_email:
class InitMailer < ActionMailer::Base
default :from => "info#blahblahblah.com"
def initial_email(user)
#user = user
#url = "http://www.blahblahblah.com"
mail(:to => user.email,
:subject => "Welcome to my website!"
)
end
handle_asynchronously :initial_email
end
However, I encounter an argument error in my log file "delayed_job.log":
Class#initial_email failed with ArgumentError: wrong number of arguments (1 for 0) - 5
failed attempts
For your information, the email is sent in a controller using the line:
#user = InitUser.new(params[:init_user])
InitMailer.delay.initial_email(#user)
Additionally, when I set up my code without the delay, the emails were sent out without problem (except for the fact that it slowed down my app waiting for gmail servers)
Where is causing the errors here? How can I get the delayed mail to send properly?
Due to the way that Rails3 implements mailers, there are some unusual workarounds for delayed_jobs. For instance, you have seen that to delay the mailing, you write
ExampleMailer.delay.example(user)
While typically you would have to write handle_asynchronously after the method definition, in the case of mailers this declaration (for some reason) prevents that delayed job from working.
So in this code, drop the declaration entirely:
class InitMailer < ActionMailer::Base
default :from => "info#blahblahblah.com"
def initial_email(user)
#user = user
#url = "http://www.blahblahblah.com"
mail(:to => user.email,
:subject => "Welcome to my website!"
)
end
#No handle_asynchronously needed here
end

Rails 3 - abandon sending mail within ActionMailer action

I'm wondering how I could conditionally abandon sending mail within the action ActionMailer action itself.
class SomeMailer < ActionMailer::Base
...
def some_emails
some_models = Model.where(:a => 1)
if !some_models.blank?
mail(...)
else
# What to add here?
# render :nothing => true doesn't work
end
end
end
Now invoking this through SomeMailer.some_emails.deliver! returns an
ArgumentError: A sender (Return-Path, Sender or From) required to send a message
Set perform_deliveries to false, like so:
emails = get_email_list_somehow
if emails.present?
mail options.merge(:bcc => emails)
else
self.message.perform_deliveries = false
end
This will quietly not try to send and should stop the error from happening.
In Rails 3.2.9 you can finally conditionally call mail(). Here's the related GitHub thread. Now the OP's code can be reworked like this:
class SomeMailer < ActionMailer::Base
...
def some_emails
some_models = Model.where(:a => 1)
unless some_models.blank?
mail(...)
end
end
end
The strange thing is, that with Rails 3.1.rc4 and WEBrick, it works fine on my local WEBrick webserver. But as soon as I push to Heroku cedar stack, their WEBrick throws the
ArgumentError: A sender (Return-Path, Sender or From)
You have to remove the conditional statements as stated in above answer. That fixes it so that it also works on Heroku, not just your local machine
I had this same problem. There is no real way to do it within the ActionMailer action so I did the following in my cron task:
users.each do |user|
begin
UserMailer.event_second_reminder_group_user_email(user).deliver
puts " - sending reminder email to user #{user.email}"
rescue
end
end
puts "Complete!"
Now if an error is thrown, it doesn't break the app!
Instead put your conditions in the place where you are making the call to SomeMailer.some_emails.deliver!

Resources