Sending tons of emails in Ruby on Rails with ar_mailer
Article updated on 1/31/2009 for Rails 2.2.2 compatibility.
So you've had some success using sendmail to send one-off emails like order receipts, password reset confirmations and welcome letters. Now, you need to be able to send 5,000 newsletter emails to your entire contact database.
This tutorial assumes that you are already sending email in Rails. This is a tutorial on implementing queued mailing with ar_mailer.
Introducing ar_mailer
A great way to handle a massive amount of emails that you need to send is simply by queueing the emails and sending them in smaller bursts. I like to use the plugin "ar_mailer" to get this working. How it works is simple: Whenever you attempt to send an email by calling a method like "deliver_welcome_letter," instead of using sendmail to send the email at that moment, ar_mailer will instead store the outgoing email into a database table. Then, in the background, the ar_sendmail executable will periodically query that database table and attempt to deliver the messages.
When you use a shared Ruby on Rails hosting plan, you will typically only be allowed to send out a certain number of emails per hour. The host that we use here at Ameravant actually limits us to 250 outgoing emails per hour (for each of our accounts). If a client of ours wants to send out a newsletter to 1,000 contacts, only the first 250 would be delivered if we used sendmail directly with no queue in place. Therefore, we need to limit the number of emails we send per hour so all 1,000 contacts will eventually receive their emails.
Let's get started
First off, you need to have the ar_mailer plugin installed for your Rails application.ar_mailer is available as a gem, but it is not yet compatible for use with Rails 2.2.2. So, for now you should be using the plugin or you will run into problems. The ar_mailer plugin is maintained on GitHub using git for version control. You can install it with:
$ script/plugin install git://github.com/adzap/ar_mailer.git
We need to setup a model in our application that will be used to store the outgoing emails. There are two commands that ar_sendmail (note that while the plugin is called ar_mailer, the actual executable is ar_sendmail) provides to give us the model and migration. They arear_sendmail --create-migration and ar_sendmail --create-model. Running these commands will print out the migration and model code for you to use. However, you can simply make the model yourself and use the code I give you here, to save some time.
The model and database migration
$ script/generate model email
001_create_emails.rb
class CreateEmails < ActiveRecord::Migration def self.up create_table :emails do |t| t.string :from, :to t.integer :last_send_attempt, :default => 0 t.text :mail t.datetime :created_on # ar_mailer still uses deprecated created_on field end end def self.down drop_table :emails end end
You will notice that ar_mailer still uses the old "created_on" field name as opposed to the newer "created_at" convention. This is the table that will hold all of the outgoing email information. It will store the to and from addresses, the entire MIME email body, and some meta information like when the email was added to the queue and the last timestamp of when the last delivery was attempted. When the ar_sendmail process runs, it uses the "created_on" field to determine if an email is expired. If an email is unable to be delivered for a long period of time, it will simply be removed from the queue (the default expiration time is one week).
email.rb
We only have some simple validations here to ensure that no emails are added to the database that are missing information.
class Email < ActiveRecord::Base validates_presence_of :from, :to, :mail end
environment.rb
We also need change our application's ActionMailer delivery method from sendmail to activerecord. In your production.rb and development.rb environment files, enter the following:
ActionMailer::Base.delivery_method = :activerecord
You should already have a mailer class created for your application. If not, create one like so:
script/generate mailer post_office
Slight tangent — If you are going to have a lot of automated emails sent from your application, I suggest making multiple mailer classes, such as user_mailer.rb, event_mailer.rb, etc. It is also worth looking into Rails observers to trigger your email delivery.
Moving on... the mailer class needs to inherit from ActionMailer's now-available ARMailer subclass instead of Base.
class PostOffice < ActionMailer::ARMailer ... end
Let's test sending some messages. Use your application to trigger the email delivery, then go into your console and look in the Emails table for your queued emails.
$ script/console Loading development environment (Rails 2.1.0) >> Email.all
If you see your email records, it worked properly!
The magic in the background
We've got our emails queued and ready to be sent, but they will not actually be delivered until we start using the ar_mailer executable ar_sendmail. We have two options for making this work: We can use the process in daemon mode so it runs constantly in the background, or we can call it on a recurring schedule by setting up a cron job.
The problem I have with running the process as a daemon is that it can unexpectedly and randomly halt. This is not such a problem locally, as we'll likely be developing and testing our application and will know the process has stopped. We can then simply restart it. However, on a production server, we will likely not be monitoring the processes and therefore will usually only know it has stopped running when a client calls us, frustrated that their newsletter is not being sent.
I suggest running it as a daemon locally, but using a cron job on your production server.
Running ar_sendmail in daemon mode
This command is pretty simple. All we do is run the ar_sendmail command from our terminal. To get a list of all the arguments you can pass to it, simply run ar_sendmail -h. For development purposes right now, I'm going to just have ar_sendmail one a single time, so we can test that everything is configured properly.
First, we can check out our email queue with this:
ar_sendmail --mailq
We will be shown a list of emails in our database that are ready to be sent. If you see emails in there, great! That means that ar_sendmail is properly querying our database. Now let's run it:
ar_sendmail -ov
The arguments instruct it to run one time only (-o), and to be verbose about what it is doing (-v). If all goes well, you should see some emails appearing in your inbox! If you want it to run on a recurring basis on your development machine, set it to run in daemon mode and give it parameters to tell it how many to send in each burst, and how often. This, for example, will send 20 emails every 5 minutes:
ar_sendmail -d --batch-size 20 --delay 300
Running as a cron job on your production server
When we run ar_sendmail on our production server, we need to be a bit more specific in our command, to ensure that the proper application path and environment is used. As explained before, I prefer to run a cron job that commands ar_sendmail to run a single time, on a recurring basis. For our host, we are limited to 250 emails an hour. So, I will setup the cron job to run at 5 minute intervals. This means we can send 20 emails every 5 minutes, giving us the safe number of sending 240 per hour.
Here's my entry in my production server's crontab:
*/5 * * * * /usr/local/bin/ruby /usr/local/bin/ar_sendmail -o --batch-size 20 --chdir /home/myusername/myapplication --environment production
If you've read my cron job post, you'll understand this command pretty easily.
That's it, we're up and rolling with queued emails. But for some extra credit, a few neat things that I like to do is provide a section for the website administrator to manage their email queue. I let them see:
- A list of all emails that are in the queue
- A time estimate of how long it will take the remaining emails to be sent (we know how many we send an hour, so this is cake!)
- The ability to delete a single email from the queue
- The ability to clear the entire queue in case they mistakenly sent something and then realized there was a huge typo in the subject line
This kind of flexibility is easy to add and your customers will appreciate it!


venkat
over 4 years ago
pretty cool feature. I feel it worth giving a try...
thanks kip.
smoothie
over 4 years ago
uninitialized constant ActionMailer::ARMailer::Email
why does this happen after you require action_mailer/ar_mailer ?
On Rails 2.1.1, OS X 10.5.5
Kip
over 4 years ago
smoothie: I apologize for the late response. This error will show if you have not yet created your Email model in your Rails application.
db
over 4 years ago
I think I understand this, but I wanted to check... Does this change the one-off emails so that they also use ar_mailer? In other words, if I send a registration confirmation (single email) will it have to get in line behind potentially a bunch of other messages? If I want to keep using sendmail for one-offs, could I just keep PostOffice class declaration unchanged (i.e. keep it "class PostOffice < ActionMailer::Base")?
Kip
over 4 years ago
db: Yep. All emails delivered using the controller that inherits ARMailer will use the ar_mailer queue. If you want to have a mix of both queued and one-off emails, you could make a second mailer controller that uses ActionMailer instead of ARMailer. I like the idea of queueing all email sent, though, so if the initial delivery attempt fails, it will try again. I think this is pretty crucial for order receipts and "activate your account" emails.
Dave
over 4 years ago
Why not just use a email newsletter provider? Granted it does cost some money, but you don't have to worry about blacklists and getting pushed into spam boxes. The cost isn't that much.
carl
over 4 years ago
i will like to send emails to about 100,000 people and i have been seaching for a free web mailler i don't know if you can direct me.....
Kip
over 4 years ago
Carl: It's highly unlikely you'll be able to find a free web mailer. Due to the amount of spam (and scams) that are done via email, the service would be shut down in a very short amount of time. Unsolicited email has been regulated by US law since 2004's CAN-SPAM act, and it would be almost impossible for the owner of a free web mailer to enforce the rules set forth by the act.
http://www.ftc.gov/bcp/edu/pubs/business/ecommerce/bus61.shtm
Nandan Pramanik
over 4 years ago
how i used it in windows platform?
Kip
over 4 years ago
Nandan: I don't have any experience running Rails on Windows, but as long as you have RubyGems installed, you should be able to install the ar_mailer gem. If you're using an all-in-one solution like InstantRails, you probably will need to consider abandoning it and installing Rails manually.
Instructions are on the RoR site:
http://rubyonrails.org/down
Sijmen
over 4 years ago
I'm having the same problem as one of the users above, but for a different reason:
uninitialized constant ActionMailer::ARMailer::Email
My email class is not named Email but QueuedEmail. So, as the docs suggested, I set the email class. The full section in environment.rb looks like this:
require 'action_mailer/ar_mailer'
ActionMailer::Base.email_class = QueuedEmail
ActionMailer::Base.perform_deliveries = true
ActionMailer::Base.default_charset = 'utf-8'
ActionMailer::Base.delivery_method = :activerecord
For now I'll change my emal model class to Email, but it's still something that irks me.
Sewell
over 4 years ago
@Sijmen:
Your environment setting is wrong if you want to use the QueuedEmail class.
It should the following, which points to the ARMailer class, not Base
ActionMailer::ARMailer::email_class=QueuedEmail
Ancor Cruz
over 4 years ago
Hi,
Thanks for the HowTo, I use this example and i have 3 different problems.
First, in development environment, only queued one mail in emails table. I need restart mongrel for queued another mail.
*****
Second, in production environment, i need put this:
require 'action_mailer/ar_mailer'
ActionMailer::Base.perform_deliveries = true
ActionMailer::Base.default_charset = 'utf-8'
ActionMailer::Base.delivery_method = :activerecord
in config/environments/production.rb instead config/environment.rb or rake db:migrate launch this error:
uninitialized constant ActionMailer::ARMailer
****
Third, in production environment, launch this error:
ActionView::MissingTemplate (Missing template postoffice/welcome.erb in view
when i send a email.
Thanks
Ancor Cruz
over 4 years ago
Last post problems only in Rails 2.2.2, in Rails 2.1.1 works!
Bye!
Sean McGilvray
over 4 years ago
If you want to bypass queuing an email that should be sent now, i.e. subscription_confirmation email, how do you do that?
Thank you,
Sean McGilvray
RK
over 4 years ago
Hi Ancor - are you able to solve this issue, i am facing the same issue. If you solved the issue please share the details here.
ActionView::MissingTemplate (Missing template postoffice/welcome.erb in view
Sean McGilvray
over 4 years ago
I am getting the following error. Can anyone help? I have followed the instructions above and it says nothing about another table?
Mysql::Error: Table 'gcpdev.queued_mails' doesn't exist: SHOW FIELDS FROM `queued_mails`
Thanks,
Sean McGilvray
Sean McGilvray
over 4 years ago
Never mind I figured it out. I had the plugin Mail Que installed and did not know it was still there.
:)
Kip
over 4 years ago
The issues people are running into with ar_mailer and Rails 2.2.2 seem to be related to the ar_mailer gem. I was having problems upgrading some applications to 2.2.2, especially when trying to run them with Passenger in production.
You should use the ar_mailer plugin for Rails 2.2.2, at least until the gem is updated (I'm not sure when that is going to happen). You can get the ar_mailer plugin here from github:
http://github.com/adzap/ar_mailer/tree/master
Install with:
script/plugin install git://github.com/adzap/ar_mailer.git
Simone
over 4 years ago
Nice tutorial, everything works fine. The only problem I had was that I was in fact using sendmail like you were assuming at the beginning, but it seems to me that ar_mailer works only if ActionMailer::Base.smtp_settings = { ... } are specificed, while sendmail works perfectly without them. This caused my mails not to be sent at first.
Is there a way to make it work without specifying the smtp settings like in sendmail?
Kip
over 4 years ago
Simone: I think that has to do with your server's outgoing mail settings. I can simply use sendmail without specifying any outgoing connection information in my settings. You might want to browse your web hosting site's FAQs or forums to figure out if you can simplify your settings.
For my development machine, I just use postfix with sendmail:
http://en.wikipedia.org/wiki/Postfix_(software)
Sean McGilvray
over 4 years ago
RK and Ancor: Did you solve the problem of
ActionView::MissingTemplate (Missing template subscription_notifier/welcome.erb in view path )
It is looking for welcome.erb and not welcome.rhtml that I have.
Thank you,
Kip
over 4 years ago
Sean: Rename welcome.rhtml to welcome.html.erb. That's the new naming since Rails 2.0 I believe. It could be that they are now strictly enforcing the naming convention in 2.2.2.
Sean McGilvray
over 4 years ago
Kip: I still get this error after renaming the .rhtml to .html.erb.
ActionView::MissingTemplate (Missing template subscription_notifier/welcome.erb in view path ):
Kip
over 4 years ago
Sean: Well, I guess the view file must not be there then :-) Double check your folder and filenames.
Sean McGilvray
over 4 years ago
It is there because when I switch to development mode it sends the email to the database just fine. It only does this when I switch to production mode.
Sean McGilvray
over 4 years ago
Does anyone have a solution for this problem. I am running Rails 2.2.2. It only happens when running in production mode.
ActionView::MissingTemplate (Missing template subscription_notifier/welcome.erb in view path )
Thank you,
Sean
Kip
over 4 years ago
Sean: I had problems using the ar_mailer gem with Rails 2.2.2 and Passenger in production. My mailings would work fine in development mode with Mongrel. If you're running Passenger you might consider trying to install the ar_mailer plugin instead of the gem. I have a link to it in the article.
Don't forget to remove your "require" line in your environment.rb if you switch to the plugin.
Sean McGilvray
over 4 years ago
Hello Kip: I am new so bare with me.
I have put the plugin in the vendor/plugin folder on my site. I have removed the gem from the ruby/gems folder. When I send an email it is using the regular base and not ARMailer to send email now. What do I need to do to get it to use ARMailer now. I have the controller set to use ARMailer.
Thank you
Sean McGilvray
over 4 years ago
I figured out that I had require 'action_mailer/ar_mailer' part of the code in config/environments/production.rb. I did a clone git for the address you provided above and put the clone in the plugins folder. When I run it now it still delivers mail via ActionMailer::Base instead of ActionMailer::ARMailer like I have it set in the model/SubscriptionNotifier.rb file. Any thoughts?
chris
over 4 years ago
First off, thanks so much!! Great tutorial, you're the best :)
So the only way I can seem to get ar_mailer to queue all of my emails (900+) is to add everyone to the BCC list and call the deliver_mailing(recipients) method *once* # where recipients gets converted to the bcc list #
I hate doing this, adding everyone to the bcc list, and I figure there will be spam issues, or server rejection issues. If i try to loop over all of the email addresses though, and do a deliver_mailing(recipient) on each one, eventually it dies on itself with the following error:
-----------
undefined method `perform_delivery_activerecord' for #<ExceptionNotifier:0x2aaab1aa9110>
[RAILS_ROOT]/vendor/rails/actionmailer/lib/action_mailer/base.rb:469:in `__send__'
-----------
As a heads up, I needed both :smtp and :activerecord delivery methods, so had to use the solution found here:
http://railsforum.com/viewtopic.php?pid=26970#p26970
Anyone have any ideas or best practices as to actually delivering these? Every doc or tutorial I've come across skips that part :(
Kip
over 4 years ago
Sean: Make sure you're setting the delivery method for ActionMailer to activerecord in your environment (usually in your production.rb file):
ActionMailer::Base.delivery_method = :activerecord
Kip
over 4 years ago
Chris: I would use ar_mailer as your default for delivering mail in your application, and then bypass the delivery for certain emails you need to send immediately (such as an "activate your account" message). You can do this by using the method ActionMailer::ARSendMail.deliver. This is the method that the ar_sendmail executable uses to deliver the email when it's actually doing the sending.
See the documentation here:
http://seattlerb.rubyforge.org/ar_mailer/classes/ActionMailer/ARSendmail.html
Idea and more details from this thread:
http://railsforum.com/viewtopic.php?pid=26900#p26900
chris
over 4 years ago
Heya Kip, thanks so much for the suggestion. I actually tried using ar_mailer as the default, but still have the same problem when attempting to add mails to the queue.
The app eventually dies and I get the "undefined method 'perform_delivery_activerecord' for #<ExceptionNotifier:0x2aaab1aa9110> "
Am I going about it the wrong way? Looping over the email addresses and calling deliver_mailing(email) for each one? It's as if it falls over on itself and dies when adding a bunch of them. I mean...it's the same thing I guess as doing a normal active record insert of 1000 records, which is understandably heavy.
As I mentioned, the only other way I can figure out is to add everybody to the bcc: and deliver_mailing(recipients) just once. There must be a better way?
Kip
over 4 years ago
Chris: You need to forget about Bcc'ing as an option. Looping over the email addresses is how to queue them all properly. You probably need to wrap your call to YourMailerModel.deliver_blah_blah in a begin..escape..end block. I usually use the following:
for recipient in @recipients
PostOffice.deliver_newsletter(@newsletter, recipient) rescue next
end
If the delivery raises an exception, it will simply move on to the next recipient in the array. One example of an exception being raised is when an improper email address is attempted to be used as the receipient (if it is blank or invalid).
Sean McGilvray
over 4 years ago
Any word on getting ar_mailer gem to work with Rails 2.2? I can not use the plugin form of this because I am on a shared hosting that is jailed. Does anyone know how to fix the actual gem. It works fine in development mode just now in production. What are the problems with running my app in development mode?
Thank you,
Sean McGilvray
Sean McGilvray
over 4 years ago
Why would my emails be skipping the queue on production but not in development? Everything works great in development and then I switch to my production server and the emails that are suppose to go in the queue are bypassing the queue and just being sent. Any ideas why this would be happening?
Kenny Johnston
over 4 years ago
For those who are using the gem in 2.2.2 and are wondering why emails aren't saving to the database in development, or are receiving an error complaining about 'create_time_zone_conversion_attribute?', here's a workaround:
http://www.theirishpenguin.com/2009/01/22/bug-of-the-day-nilinclude-error-with-create_time_zone_conversion_attribute/
Sean McGilvray
over 4 years ago
Hey guys there is a new version of adzap-ar_mailer available now that is compatible with Rails 2.2.2 and Ruby 1.8.7
Sean McGilvray
Sean McGilvray
over 4 years ago
I get the following error when trying to send an email from the queue:
Unhandled exception wrong number of arguments (7 for 6)(ArgumentError):
Any ideas on how to fix this?
Thanks
Camilo
over 4 years ago
Hello,
Curious to know how many plain text emails one can hope to send per minute from a VPS with 500mb RAM, using Rails' actionmailer to initiate the emails. Anyone have any performance figures.
Thanks
Tom
over 4 years ago
Hi there,
can anyone tell me what works with Rails 2.3? Gem or plugin?
And, if I have to use the plugin: does Rails really pick it up without any additional things to do? (I mean it's still just a gem in the plugins folder, right - is that enough?)
Thanks a lot for your help!
Tom
Millisami
over 4 years ago
I used this as a plugin but got distracted coz of fuzzy errors. And I tried with this forked gem
http://github.com/adzap/ar_mailer/tree/master
and it did worked like a charm.
Great!!!
Sathish kumar
over 3 years ago
I have finished the all configuration for ar_mailer its working fine. such as adding the record in emails table and delivering the what ever records added into the emails table.
But The problem is IF i trigger the email to send out its adding first time.
If i try second time its not adding the records into the table.
Sometimes it given error "Stack level too deep"
Please give some solution. Thanks in advance.
plog
over 3 years ago
A silly question :
When is the class PostOffice used ?
As soon as the emails (class Email < ActiveRecord::Base) are stored in the DB, ar_sendmail grab them from the DB and send them... no ?
I missed something...
ar_mailer 2.0.2 (as a plugin)
rails 2.2.2
Kip
over 3 years ago
plog:
Check out this tutorial here on the basics of sending mail with Rails:
http://jonathansng.com/ruby-on-rails/rails-send-email-tutorial/
That should clear things up. After that, you can choose to use ARMailer if you want queued mailing.
Kip
over 3 years ago
Sathish kumar:
Try running your delivery method from the Rails console to see if you can get a more specific error message returned.
Run "script/console" (or "ruby script/console" if you're not on OS X) from your application root. Then use your delivery method directly like "PostOffice.deliver_welcome_letter(User.first)".
Sathish Kumar
over 3 years ago
Hi Kip,
I have got fixed that error. Its adding it.
But in rare case when the system gets idle state the ar_mailer throws an error states 'Stack level too deep'
But I restart the mongrel's its again starts sending mails without any problem...
After sometime same problem persist...
Thanks in advance,
Brian Armstrong
over 3 years ago
If you do have control over the production server, would you recommend using something robust like postfix to queue mail instead of this solution? Just curious if this solution is really meant as a work around for those on shared hosts. Thanks!
Brian
russell Roberts
over 3 years ago
Thank you for the wonderful plugin. I am on rails 2.3 and I wish to unpack into vendor. But I get a not found message when I do this.
Any Ideas thank you
Grant V
over 3 years ago
I am trying to get ar_mailer to work but I keep getting:
NameError (uninitialized constant ActionMailer::ARMailer):
I tried all the steps above (including switching from the gem to the plugin under Rails 2.2.2) but with no luck.
I have this line in config/environment.rb:
require 'action_mailer/ar_mailer'
and this in both the development and production configs:
ActionMailer::Base.delivery_method = :activerecord
I also changed my model:
#class Notifier < ActionMailer::Base
class Notifier < ActionMailer::ARMailer
Any thoughts on what is wrong or how to at least trace down the problem would be appreciated.
Thanks,
Grant
Grant V
over 3 years ago
Found out why I got the other problem. I took a look at the vendor directory and found that the plugin was missing. It must have failed while installing or I deleted it at some point.
Eitherway I got past that error but now I have this:
LoadError (Expected vendor/plugins/ar_mailer/lib/action_mailer/ar_mailer.rb to define ActionMailer::ARMailer):
I looked in the code and I don't see where ARMailer is defined.
it defines
class ActionMailer::Base
but I thought that should be something like:
class ActionMailer::ARMailer > ActionMailer::Base
Am I on the right track with this?
Thanks,
Grant
georges
over 3 years ago
mass mailing in rails has always been a trouble spot.
personally, i think the mailing system in rails could use a bunch of simplification.
my company has taken a stab at fixing the mass mailing problem in rails. we think we've come up with a better solution than ar_mailer.
take a look: http://blog.twg.ca/2009/09/rails-mass-mailing-it-shouldnt-be-this-complicated
thanks!
Max Williams
over 3 years ago
Nice article - thanks Kip. We've actually been using ar_mailer for ages, and i read this as part of a conversation where i recommended ar_mailer to someone else. I was interested in your comment about running ar_sendmail as a daemon being problematic - this has been my experience as well.
I restart ar_sendmail on our server as part of my capistrano deploy/restart script, and it seems to often cause the whole script to crash out, because it's told to restart when its not actually running. Why it's stopped running isn't always clear, sometimes it seems like it stops when our mongrels are stopped. Anyway it's kind of a pain in the ass. I'd like to try running it as a cron job, but once a minute so there's not too much of a delay (a lot of our emails are forgot password emails, where you want the mail to go out asap). Would running it once a minute cause any issues do you think?
Max Williams
over 3 years ago
Btw, i couldn't post that last comment under my real email of
toastkid <dot> williams <at> gmail <dot> com
as the site was saying it wasn't valid. Obviously i was trying my actual email, not the deliberately garbelized version above. So i think your email validation is a bit wonky.
Greg B
over 2 years ago
I'm having the same problem as Grant V. There is a closed issue on git about that message. It states to just use ActiveRecord::Base. However, once I do this, it doesn't seem to work at all. E-mails are still being sent off without going into the queue.
Has anyone used this recently and gotten it to work in rails 2.3.5 and up?
PB
over 2 years ago
I am facing the same problem as Grant and Greg. I am on rails 2.3.5.
Error I am getting is
"Expected vendor/plugins/ar_mailer/lib/action_mailer/ar_mailer.rb to define ActionMailer::ARMailer)
Is there a solution to this problem ?
PB
over 2 years ago
ARMailer class has been deprecated since ar_mailer 2.0.
Its no longer required to inherit ARMailer. I reverted it to ActionMailer and this worked just fine.
Thanks for the tutorial.
Santa Barbara SEO Pro
over 2 years ago
This was a great article Michael and Kip - wow I found some very interesting tid bits of information here. It's such a popular article! Great work on this one...
Taylor Reaume
http://www.thesearchenginepros.com
Professional-SEO-Taylor
over 2 years ago
Great article! Thanks for the helpful information! If you want more interesting informations Please visit our site
http://www.thesearchenginepros.com