I want to send an email every day with a different attachment. So I think I should pass the parameter to mail's initialize block. I read some articles about ruby block but I can not find the right way to implement it. How could I do it the right way and why does the mail's initialize method pass a block? Thank you.
require 'mail'
class MailSender
attr_accessor :created_at
def initialize
delivery_options = {
address: 'xxmail.com',
port: 25,
user_name: 'xxx#xxmail.com',
password: 'xxxxxx',
authentication: :login
}
Mail.defaults do
delivery_method :smtp, delivery_options
end
self.created_at = DateTime.now.prev_day.strftime("%F")
end
def notify
mail = Mail.new do
from 'xxx#xxmail.com'
to 'xxx#xxmail.com'
subject 'mailtest'
body 'The first mail.'
add_file :filename => "#{created_at}.txt", :content => File.read("#{created_at}.txt")
end
mail.deliver!
end
end
Related
I'm working on a webscraper that will send out a weekly CSV with new content with Ruby. For the mailing component I decided to use the Mail gem. After a great deal of tinkering I got it to send a few test emails. However, I frequently get this error:
...smtp.rb:541:in `initialize': execution expired (Net::OpenTimeout)...
I have a reasonable internet connection and haven't been able to detect any sort of pattern with the error. Here is my code for the mailer:
require 'mail'
def sendEmail(newEventCount, newEventArray)
if newEventArray.to_a.empty? == true
emailBodyText = "No new events were added this week."
else
newEventString = "The new events are: "
newEventArray.each do |event|
newEventString = newEventString + event + "\n"
end
emailBodyText = "#{newEventCount} events were added this week. #{newEventString}"
end
options = { :address => "smtp.gmail.com",
:port => 587,
:domain => '(my public ip address according to google)',
:user_name => '(my username)',
:password => '(my password)',
:authentication => 'plain',
:enable_starttls_auto => true }
Mail.defaults do
delivery_method :smtp, options
end
mail = Mail.new do
from '(my email)'
to '(recipient email)'
subject 'Weekly Scrape Results'
body emailBodyText
add_file './events.csv'
end
mail.deliver!
end
I am trying to send an email to example#gmail.com with Action Mailer (Ruby on Rails). The method sendactivation is correctly executed and the message "Email sent" is displayed. However, I never receive any email. Actually, the output "Test" is never printed. My webapp is hosted on Heroku Cedar-10.
class UsersController < ApplicationController
def sendactivation
UserMailer.welcome_email()
render :json => {
:result => "Email sent"
}
end
end
end
class UserMailer < ActionMailer::Base
def welcome_email()
mail(to: "example#gmail.com",
body: "Hello",
content_type: "text/html",
subject: "Already rendered!")
puts "Test"
end
end
This is the configuration I have on my config/environment/production.rb. Actually I wanted to send it with Office 365 but I suppose it is easier to debug with a Gmail account.
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
address: 'smtp.gmail.com',
port: 587,
user_name: 'example#gmail.com',
password: '########',
authentication: 'plain',
enable_starttls_auto: true }
What am I doing wrong? Is there anything I need to change on my Gmail configuration?
ANSWER: In addition to the marked answer, I needed to set the "from" address in the welcome_email method.
Call method deliver:
UserMailer.welcome_email.deliver
UserMailer.welcome_email.deliver_now
From the Rails Guide: See section 2.1.4
class SendWeeklySummary
def run
User.find_each do |user|
UserMailer.weekly_summary(user).deliver_now
end
end
end
I have such problem. My test checks whether the Observer called, but does not execute it.
My files:
todo_observer.rb:
class TodoObserver < ActiveRecord::Observer
def after_create(todo)
todo.add_log('creating')
end
end
todo.rb:
class Todo < ActiveRecord::Base
attr_accessible :content, :done, :order
validates :content, :presence => true,
:length => {:minimum => 2}
def add_log(event)
Logdata.start_logging(self.content, event)
end
end
logdata.rb
class Logdata < ActiveRecord::Base
attr_accessible :modification, :event
def self.start_logging(content, event)
Logdata.create!(:modification => content, :event => event)
end
end
todo_observer_spec.rb:
require 'spec_helper'
describe TodoObserver do
before(:each) do
#attr = { :modification => "Example", :event => 'Event' }
#attr_todo = { :content => "Example", :done => :false }
end
describe 'after_create' do
it "should create log about creating task" do
count_log = Logdata.all.size
todo = Todo.new(#attr_todo)
todo.should_receive(:add_log).with('creating')
todo.save!
(Logdata.all.size).should eq(count_log + 1)
end
end
end
When I run test I get such error
Failure/Error: (Logdata.all.size).should eq(count_log + 1)
expected: 1
got: 0
Its mean, that observer called,but doesn't create instance of Logdata. When I comment string(check the call)
todo.should_receive(:add_log).with('creating')
My tests were successful.And accordingly its success when I comment string (Logdata.all.size).should eq(count_log + 1)and uncomment previous string.
How does the function should_receive to create an instance of the class Logdata?
should_receive prevents the actual method from being called.
You should create two separate tests. One to check that the log is added to the todo, and one to check that the log is created.
describe 'after_create' do
it "should add a log to the todo" do
todo = Todo.new(#attr_todo)
todo.should_receive(:add_log).with('creating')
todo.save!
end
it "should create a new logdata" do
todo = Todo.new(#attr_todo)
expect {
todo.save!
}.to change {Logdata.count}.by(1)
end
end
I am trying to use HTTParty in my class FindXYZ extending Thor but it is not working. All I wish to do is use HTTParty get to query couchdb in my method xyz
When I try to run I see error cannot find get
require 'json'
require 'httparty'
require 'thor'
class FindXyz < Thor
include Thor::Actions
include HTTParty
headers 'Accept' => 'application/json'
server = '192.168.5.50:5984'
user = 'uname'
password = 'passo'
couchdb_url = "http://#{user}:#{password}##{server}"
basic_auth user, password
base_uri couchdb_url
default_params :output => 'json'
format :json
desc "xyz", "Find scenarios that contains SSL"
method_option :name, :aliases => "-t", :required => true
method_option :location, :aliases => "-s",:required => true
def xyz
name = options[:name]
loc = options[:location]
file_path = File.join(loc, name)
t_json = JSON.parse(File.read(file_path))
t_json["ids"].each do |temp|
path_to_doc = "/test123/#{temp}"
response = get(path_to_doc)
puts "Found => #{temp}" if response.to_s.include?('Birdy')
end #close the loop
end #close the method xyz
end #close class
Try it this way from outside the class
puts FindXyz.get('....').inspect
and HTTParty.get(...) inside FinXyz class
I'm writing a small Ruby program that will pull records from a database and send an HTML email daily. I'm attempting to use ActionMailer 3.0.3 for this, but I'm running in to issues. All the searching I've done so far on using ActionMailer outside of Rails applies to versions prior to version 3. Could someone point me in the right direction of where to find resources on how to do this? Here's where I am so far on my mailer file:
# lib/bug_mailer.rb
require 'action_mailer'
ActionMailer::Base.delivery_method = :file
class BugMailer < ActionMailer::Base
def daily_email
mail(
:to => "example#mail.com",
:from => "example#mail.com",
:subject => "testing mail"
)
end
end
BugMailer.daily_email.deliver
I'm definitely stuck on where to put my views. Every attempt I've made to tell ActionMailer where my templates are has failed.
I guess I should also ask if there's a different way to go about accomplishing this program. Basically, I'm doing everything from scratch at this point. Obviously what makes Rails awesome is it's convention, so is trying to use parts of Rails on their own a waste of time? Is there a way to get the Rails-like environment without creating a full-blown Rails app?
After some serious debugging, I found how to configure it.
file mailer.rb
require 'action_mailer'
ActionMailer::Base.raise_delivery_errors = true
ActionMailer::Base.delivery_method = :smtp
ActionMailer::Base.smtp_settings = {
:address => "smtp.gmail.com",
:port => 587,
:domain => "domain.com.ar",
:authentication => :plain,
:user_name => "test#domain.com.ar",
:password => "passw0rd",
:enable_starttls_auto => true
}
ActionMailer::Base.view_paths= File.dirname(__FILE__)
class Mailer < ActionMailer::Base
def daily_email
#var = "var"
mail( :to => "myemail#gmail.com",
:from => "test#domain.com.ar",
:subject => "testing mail") do |format|
format.text
format.html
end
end
end
email = Mailer.daily_email
puts email
email.deliver
file mailer/daily_email.html.erb
<p>this is an html email</p>
<p> and this is a variable <%= #var %> </p>
file mailer/daily_email.text.erb
this is a text email
and this is a variable <%= #var %>
Nice question! It helped me to understand a bit more how Rails 3 works :)
It took me a while to get this to work in (non-)Rails 4. I suspect it's just because I have ':require => false' all over my Gemfile, but I needed to add the following to make it work:
require 'action_view/record_identifier'
require 'action_view/helpers'
require 'action_mailer'
Without the above code, I kept getting a NoMethodError with undefined method 'assign_controller'.
After that, I configured ActionMailer as follows:
ActionMailer::Base.smtp_settings = {
address: 'localhost', port: '25', authentication: :plain
}
ActionMailer::Base.default from: 'noreply#example.com'
ActionMailer::Base.raise_delivery_errors = true
ActionMailer::Base.logger = Logger.new(STDOUT)
ActionMailer::Base.logger.level = Logger::DEBUG
ActionMailer::Base.view_paths = [
File.join(File.expand_path("../../", __FILE__), 'views', 'mailers')
# Note that this is an Array
]
The templates go in lib/<GEM_NAME>/views/mailers/<MAILER_CLASS_NAME>/<MAILER_ACTION_NAME>.erb (MAILER_ACTION_NAME is the public instance method of your mailer class that you call to send the email).
Lastly, don't forget to put this in your spec_helper:
ActionMailer::Base.delivery_method = :test