Usando o Amazon Simple E-mail Service com ActionMailer no Rails
Leia em 3 minutos
Enviar e-mail em aplicações web é uma tarefa comum, mas sempre temos que decidir como elas serão enviadas: servidor SMTP, GMail, Sendmail, serviços como Postmark e Mad Mimi… Todos eles são alternativas viáveis, algumas mais simples, outras nem tanto assim.
No final de 2010 a Amazon lançou o Amazon SES (Simple E-mail Service), um serviço que permite enviar e-mails usando um webservice da Amazon. Obviamente o serviço é pago, mas com um preço muito justo: apenas 0.10 USD por cada mil mensagens enviadas.
Mesmo sendo pago o Amazon SES tem um modelo um pouco diferente. Você precisa solicitar acesso para envio em massa. Neste processo é necessário informar o site que usará o webservice e quantidade de mensagens que você espera enviar diariamente. Após a aprovação, que no meu caso não demorou muito mais que 30 minutos, você ainda não poderá enviar a quantidade de e-mails solicitada; a quota diária é aumentada com o passar do tempo, seguindo a tabela abaixo:
- 1000 mensagens: assim que você recebe acesso à produção
- 10.000 mensagens: depois de 3 dias
- 100.000 mensagens: depois de 10 dias
- 1.000.000 mensagens: depois de 2 semanas
Note que você precisa efetivamente consumir sua quota para que os valores sejam aumentados.
Configurando o Amazon SES
O primeiro passo é baixar os arquivos que você usará na linha de comando. Acesse o endereço http://aws.amazon.com/developertools/Amazon-SES, baixe os scripts e descompacte o arquivo baixado.
No diretório, terão alguns scripts (sic) Perl para configurar o Amazon SES. Mas antes de usá-los, você precisa criar um arquivo contendo suas credenciais da Amazon. Acesse o endereço http://aws-portal.amazon.com/gp/aws/developer/account/index.html?action=access-key para ver suas chaves de acesso (Access Key e Secret Key). Crie um arquivo chamado aws-credentials
utilizando o formato abaixo.
AWSAccessKeyId=022QF06E7MXBSH9DHM02
AWSSecretKey=kWcrlUX5JEDGM/LtmEENI/aVmYvHNif5zB+d9+ct
O próximo passo é verificar o e-mail que será utilizado para enviar as mensagens. Vá ao diretório contendo os scripts e execute o seguinte comando:
$ ./ses-verify-email-address.pl -k aws-credentials -v seu@email.com.br
Você receberá uma mensagem da Amazon com um endereço para confirmar esse e-mail cadastrado. Depois que você fez esta confirmação, já poderá enviar e-mail de testes apenas para os endereços confirmados. Você pode testar o e-mail com o comando abaixo:
$ echo Hello Amazon SES | ./ses-send-email.pl -k aws-credentials -s \
"Testando Amazon SES" -f seu@email.com.br seu@email.com.br
Se tudo deu certo, você receberá a mensagem em pouco tempo.
Configurando o Ruby on Rails
Para usar o Amazon SES no Ruby precisaremos de uma biblioteca chamada Amazon SES Mailer. Para instalá-la, execute o comando abaixo.
$ gem install amazon-ses-mailer
Depois de instalado, você pode criar um arquivo de configuração contendo suas credenciais usadas naquele arquivo aws-credentials
. Crie um arquivo config/aws.yml
com o seguinte conteúdo:
secret_key: "kWcrlUX5JEDGM/LtmEENI/aVmYvHNif5zB+d9+ct"
access_key: "022QF06E7MXBSH9DHM02"
Agora, você não vai querer configurar o ambiente de desenvolvimento com o Amazon SES. Mesmo sendo barato, não faz sentido pagar por algo que pode ser feito gratuitamente. Então, no arquivo config/environments/production.rb
, adicione as seguintes linhas:
config.after_initialize do
ActionMailer::Base.tap do |am|
credentials = YAML.load_file(config.root.join("config/aws.yml")).symbolize_keys
am.delivery_method = AmazonSes::Mailer.new(credentials)
am.perform_deliveries = true
end
end
No trecho acima estamos definindo o método de envio como sendo uma instância da classe AmazonSes::Mailer
, que implementa a interface do ActionMailer. Na prática, só é preciso definir os métodos SomeClass#initialize(options)
e SomeClass#deliver!(mail)
.
Para o ambiente de desenvolvimento, eu uso o Sendmail como método de envio. Eu gosto de receber os e-mails enquanto desenvolvo. Neste caso, faço duas coisas. Primeiro, adiciono as configurações ao arquivo config/environments/development.rb
.
config.after_initialize do
ActionMailer::Base.tap do |am|
am.register_interceptor(MyApp::MailerInterceptor)
am.delivery_method = :sendmail
am.perform_deliveries = true
am.raise_delivery_errors = true
end
end
Perceba que estou definindo a opção ActionMailer::Base.register_interceptor
. Este é um excelente modo de interceptar os e-mails que serão enviados, permitindo manipular os cabeçalhos e remetentes, por exemplo. Antes de criar a classe MyApp::MailerInterceptor
, vamos adicionar o diretório lib
ao load path; isso permitirá organizar nosso código sem muito esforço. No arquivo config/application.rb
, adicione algo como isto:
module MyApp
class Application < Rails::Application
config.autoload_paths << config.root.join("lib")
end
end
Agora, crie o arquivo lib/my_app/mailer_interceptor.rb
. Ele será responsável por interceptar as mensagens, alterando o remetente para o seu próprio e-mail. O objeto que será usado como interceptador só precisa implementar o método delivering_email
.
module MyApp
module MailerInterceptor
def self.delivering_email(email)
email.body.raw_source << "\n\nEnviado originalmente para #{email.to.to_sentence}\n\n"
email.to = "dev@email.com"
end
end
end
Pronto! Agora você tem uma aplicação que envia e-mails utilizando o Amazon SES e, de quebra, ainda consegue visualizar as mensagens enviadas em modo de desenvolvimento sem gastar nenhum centavo.