Emails notifications are not sent from the God gem - ruby-on-rails

I use the God gem to monitor my delayed_job processes, so far the gem is doing its job as it should but from some reason I can't get him to send email notifications (i use google apps).
Here are my god file configuration:
God::Contacts::Email.defaults do |d|
d.from_email = 'system#example.com'
d.from_name = 'Process monitoring'
d.delivery_method = :smtp
d.server_host = 'smtp.gmail.com'
d.server_port = 587
d.server_auth = true
d.server_domain = 'example.com'
d.server_user = 'system#example.com'
d.server_password = 'myPassword'
end
God.contact(:email) do |c|
c.name = 'me'
c.group = 'developers'
c.to_email = 'me#example.com'
end
w.start_if do |start|
start.condition(:process_running) do |c|
c.interval = 20.seconds
c.running = false
c.notify = {:contacts => ['me'], :priority => 1, :category => 'staging'}
end
Any thoughts?

According to this post on the mailing list:
gem install tlsmail
add Net::SMTP.enable_tls(OpenSSL::SSL::VERIFY_NONE) in the email
part of god's config
Use :login intead of true for your server_auth setting.

Related

ActionMailer working fine in terminal, not sending to gmail

I'm just about in the finishing stages of my website, however I am having trouble with the ActionMailer. It prints out the message just fine, I'm just eager to know how to wire it so it can send to gmail account. I'm primary confused how to route it and configure it properly. I have a contact page that has a model that takes parameters like the recipient, subject, message and the time it was sent: Mailer model: Note all this code is on a local machine
class UserEmail < ActionMailer::Base
default from: 'XXX#gmail.com'
def contact(sender, subject, message, sent_at = Time.now)
#sender = sender
#message = message
#sent_at = sent_at.strftime("%B %e, %Y at %H:%M")
mail(:subject => subject)
end
end
Here's the about controller which the contact methods lie in:
class AboutController < ApplicationController
# ...\controllers\home_controller.rb
#----------------------------------------------------
# show contact form
def contact
#title = "Contact"
#sender = ''
#subject = ''
#message = ''
end
def sendmail
#sender = params[:sender]
#subject = params[:subject]
#message = params[:message]
if validate(#sender, #subject, #message)
UserEmail.contact(#sender, #subject, #message).deliver
flash[:success] = "Your message sent sucessfully!"
redirect_to about_index_path
else
flash.now[:error] = "Your message did not send"
redirect_to about_index_path
end
end
private
def validate(sender, subject, message)
#email_regex = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
if sender.blank? || subject.blank? || message.blank?
#error = "Message not sent: Required information not filled"
return false
elsif subject.length >= 50
#error = "Message not sent: Subject must be smaller than 50 characters"
return false
elsif sender[#email_regex].nil?
#error = "Message not sent: Email not valid"
return false
else
return true
end
end
end
Now this is where I am lost.
Here's what my route like to the mailer. Is this routed appropriately?:
match '/contact_email', :to => 'about#sendmail'
When I configure the mailer, does the code rest in the application.rb or the development.rb? Here's what I have in my application.rb:
config.action_mailer.raise_delivery_errors = true
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:address => "smtp.gmail.com",
:port => 587,
:user_name => 'XXX#gmail.com',
:password => 'XXX',
:authentication => 'plain',
:enable_starttls_auto => true,
}
Thanks in advance!
Change
def contact(sender, subject, message, sent_at = Time.now)
#sender = sender
#message = message
#sent_at = sent_at.strftime("%B %e, %Y at %H:%M")
mail(:subject => subject)
end
to
def contact(sender, subject, message, recipient, sent_at = Time.now)
#sender = sender
#message = message
#sent_at = sent_at.strftime("%B %e, %Y at %H:%M")
#recipient = recipient
mail(:subject => subject, :to => #recipient)
end
And don't forget to set recipient in your calling function.
Have you put the following lines in development.rb
config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = true

Attaching PDF's to Emails in Rails 2

I am sending an email in my Rails 2 app and after a bit of hacking and learning about emails in Rails it now works fine.
Now I am just trying to add an attachment which in theory should probably be straightforward but I seem to be having issues with it.
I am using mailcatcher to preview the emails in the development environment and I can see the attachment headers in the email source but nothing is shown in mailcatcher (docs say it supports attachments)
emailer.rb
class Emailer < ActionMailer::Base
def quotation_notification(q)
#recipients = q.recipient_email
#from = q.partner_name + "<#{q.partner_email}>"
#subject = "New Quotation from " + q.partner_name
#sent_on = Time.now
#quote_id = q.quote_id
#customer_id = q.customer_id
#customer_name = q.customer_name
#recipient_email = q.recipient_email
#partner_name = q.partner_name
#partner_email = q.partner_email
#partner_ref = q.partner_ref
#version_no = q.version_no
#line_items = q.line_items
#quotation_date = q.quotation_date
content_type "multipart/alternative"
part "text/html" do |p|
p.body = render_message("quotation_notification.text.html.rhtml", :message => q)
end
attachment :content_type => "application/pdf",
:body => File.read(RAILS_ROOT + '/pdfs/' + q.quote_id + '.pdf')
#body[:q] = q
end
end
The email is being sent in a controller like so
q = QuotationEmail.new(quote_id, customer_id, customer_name, recipient_email, partner_name, partner_email, partner_ref, version_no, line_items, quotation_date)
# send email
Emailer.deliver_quotation_notification(q)
Just for completeness, my view is app/views/emailer/quotation_notification.text.html.rhtml
quotation_email.rb
class QuotationEmail
attr_accessor :quote_id, :customer_id, :customer_name, :recipient_email, :partner_name, :partner_email, :partner_ref, :version_no, :line_items, :quotation_date
def initialize(quote_id, customer_id, customer_name, recipient_email, partner_name, partner_email, partner_ref, version_no, line_items, quotation_date)
#quote_id = quote_id
#customer_id = customer_id
#customer_name = customer_name
#recipient_email = recipient_email
#partner_name = partner_name
#partner_email = partner_email
#partner_ref = partner_ref
#version_no = version_no
#line_items = line_items
#quotation_date = quotation_date
end
end
In the source of the email, after the closing html tag I can see
--mimepart_522da7e7e5959_a0885cd9314396
Content-Type: application/pdf
Content-Transfer-Encoding: Base64
Content-Disposition: attachment
*base 64 encoded stuff*
--mimepart_522da7e7e5959_a0885cd9314396--
If I have done anything bonkers then it is because I haven't sent any emails in Rails yet so still figuring things out.
I can only assume this was a problem with mailcatcher, by setting up development emails to be sent to a gmail account, the emails were sent correctly with attachments.
environments/development.rb
config.action_mailer.raise_delivery_errors = true
config.action_mailer.perform_deliveries = true
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:address => "smtp.gmail.com",
:port => 587,
:domain => "domain.co.uk",
:user_name => "gmailaddress#domain.co.uk",
:password => "accountpassword",
:authentication => :plain,
:enable_starttls_auto => true #This line is must to ensure the tls for Gmail
}
I used an existing app email address hosted on gmail, so not strictly an username#gmail.com / username#googlemail.com but I would think that those addresses would also work with the above.

ActiveMerchant requiring pin?

I am using activemerchant in a rails application like this
ActiveMerchant::Billing::Base.mode = :test
::GATEWAY = ActiveMerchant::Billing::UsaEpayGateway.new(
:login => "SOMEKEY"
)
and I keep getting this error code
error_code: \"10117\"\nauth_code: \"000000\"\nstatus: Error\nerror: Transaction authentication required.\n
when i look at the error codes (10117) for usaepay I notice that i need to enter in the pin. This I have, but i dont know how to implement. I tried these two below
ActiveMerchant::Billing::Base.mode = :test
::GATEWAY = ActiveMerchant::Billing::UsaEpayGateway.new(
:login => "SOMEKEY",
:password => "MYPIN"
)
ActiveMerchant::Billing::Base.mode = :test
::GATEWAY = ActiveMerchant::Billing::UsaEpayGateway.new(
:login => "SOMEKEY",
:pin => "MYPIN"
)
and I still get the same error
Looking at the USAEPAY Library's initializer I see login but not pin
def initialize(options = {})
requires!(options, :login)
#options = options
super
end
...any ideas how I can sent this pin into Activemerchant
UPDATE
here is my call to the transaction
options = {
:card_code=>self.card_verification
:billing_address=>{
:address1=>self.billing_address,
:city=>self.city,
:state=>self.state,
:zip=>self.zip,
:country=>"US"
}
}
response = GATEWAY.purchase(price_in_cents, credit_card, options)
i tried to do this
options = {
:card_code=>self.card_verification,
:pin=>"333333",
:billing_address=>{
:address1=>self.billing_address,
:city=>self.city,
:state=>self.state,
:zip=>self.zip,
:country=>"US"
}
}
response = GATEWAY.purchase(price_in_cents, credit_card, options)
but still nothing
Maybe you need to pass the authorization pin into the transaction. Can you paste the code where you call a transaction, please?
For example, calling this method: capture(money, authorization, options = {})
Edit:
I don't think ActiveMerchant has the pin feature implemented. Here are your options:
Use another script. Here are some examples: http://wiki.usaepay.com/developer/ruby
Add this to your Gemfile: gem 'activemerchant', :git => 'git://github.com/kalinchuk/active_merchant.git' It will install a gem from my github account. I added the pin field to active merchant.
You can then call:
::GATEWAY = ActiveMerchant::Billing::UsaEpayGateway.new(
:login => "SOMEKEY",
:pin => "PIN"
)

generating email address images or something which can't be easily scraped

I'm looking for a better Text-to-image solution for my Rails project to replace my current method which is generating a png using ImageMagick every time a new record is created or updated.
I want to prevent a mass scraping of data and abuse of email addresses provided. I'm wondering if there is an API to generate the text or use of javascript, or SVG, etc. Anything short of Flash.
I'm looking for a better solution than my current method:
def create_new_email_image
if email_changed?
path_to_images = '/images/emails'
puts "Connecting to AWS..."
config = YAML.load(File.open("#{RAILS_ROOT}/config/s3_credentials.yml"))[RAILS_ENV]
AWS::S3::Base.establish_connection!(
:access_key_id => config['access_key_id'],
:secret_access_key => config['secret_access_key']
)
puts "Finding S3 bucket..."
begin
bucket = AWS::S3::Bucket.find config['bucket_name']
rescue AWS::S3::NoSuchBucket
AWS::S3::Bucket.create config['bucket_name']
bucket = AWS::S3::Bucket.find config['bucket_name']
end
images_path = "#{RAILS_ROOT}/tmp/"
file_name = "#{id}.png"
#file_name = "5056.png"
file_path = images_path + "/"+ file_name
File.delete file_path if File.exists? file_path
img = Magick::Image.new(400, 22) { self.background_color = 'transparent' }
img.format = 'PNG'
text = Magick::Draw.new
text.annotate(img, 0, 0, 1, 0, "#{email}") {
self.gravity = Magick::WestGravity
self.pointsize = 18
self.fill = '#000000'
self.kerning = -1
self.font_weight = Magick::BoldWeight
}
img.write file_path
if AWS::S3::S3Object.exists? file_name, bucket.name + path_to_images
puts "file exists (deleting)"
AWS::S3::S3Object.delete file_name, bucket.name + path_to_images, :force => true
end
AWS::S3::S3Object.store file_name,
File.open(file_path),
bucket.name + path_to_images,
:content_type => 'image/png',
:access => :public_read,
:reload => true
`rm #{file_path}`
end
end
Rails provides a mail_to helper.
mail_to "me#domain.com"
# => me#domain.com
mail_to "me#domain.com", "My email", :encode => "javascript"
# => <script type="text/javascript">eval(decodeURIComponent('%64%6f%63...%27%29%3b'))</script>
mail_to "me#domain.com", "My email", :encode => "hex"
# => My email
mail_to "me#domain.com", nil, :replace_at => "_at_", :replace_dot => "_dot_", :class => "email"
# => me_at_domain_dot_com
mail_to "me#domain.com", "My email", :cc => "ccaddress#domain.com",
:subject => "This is an example email"
# => My email
The :encode => "hex" or :encode => "javascript" options are what you are looking for.
I've had the same problem. Here is my solution:
def text_to_image(text,options={})
return if text.blank?
filename=get_text_file_path(text)
unless File.exists?(filename)
gc = Magick::Draw.new
gc.fill = options[:color] unless options[:color].blank?
gc.pointsize options[:size] unless options[:size].blank?
gc.font=options[:font] unless options[:font].blank?
gc.gravity = Magick::CenterGravity
gc.text(0,0, text)
metrics=gc.get_type_metrics(text)
image = Magick::Image.new(metrics.width, metrics.height){
self.background_color = 'transparent'
}
gc.draw(image)
image.write(filename)
end
end
I use after_save callback to update graphic cache of email attribute.

Ruby, RoR, gmail and NET::SMTP

Is there any way to use gmail as a smtp server on rails 2.3.5/ruby 1.9.1?
My smtp settings for actionmailer are
options = {
:address => "smtp.gmail.com",
:port => 587,
:domain => 'REMOVED',
:user_name => 'REMOVED',
:password => 'REMOVED',
:authentication => 'plain',
:enable_starttls_auto => true }
and these result in the error
Net::SMTPAuthenticationError: 530 5.7.0 Must issue a STARTTLS command first.
Try this:
#config/initializers/smtp_tls.rb
require "openssl"
require "net/smtp"
Net::SMTP.class_eval do
private
def do_start(helodomain, user, secret, authtype)
raise IOError, 'SMTP session already started' if #started
if RUBY_VERSION == "1.8.6"
check_auth_args user, secret, authtype if user or secret
else
check_auth_args user, secret if user or secret
end
sock = timeout(#open_timeout) { TCPSocket.open(#address, #port) }
#socket = Net::InternetMessageIO.new(sock)
#socket.read_timeout = 60 ##read_timeout
#socket.debug_output = STDERR ##debug_output
check_response(critical { recv_response() })
do_helo(helodomain)
raise 'openssl library not installed' unless defined?(OpenSSL)
starttls
ssl = OpenSSL::SSL::SSLSocket.new(sock)
ssl.sync_close = true
ssl.connect
#socket = Net::InternetMessageIO.new(ssl)
#socket.read_timeout = 60 ##read_timeout
#socket.debug_output = STDERR ##debug_output
do_helo(helodomain)
authenticate user, secret, authtype if user
#started = true
ensure
unless #started
# authentication failed, cancel connection.
#socket.close if not #started and #socket and not #socket.closed?
#socket = nil
end
end
def do_helo(helodomain)
begin
if #esmtp
ehlo helodomain
else
helo helodomain
end
rescue Net::ProtocolError
if #esmtp
#esmtp = false
#error_occured = false
retry
end
raise
end
end
def starttls
getok('STARTTLS')
end
def quit
begin
getok('QUIT')
rescue EOFError
end
end

Resources