How to switch between multiple Gmail accounts for sending emails in Rails?

Hey everyone,

I’m working on a Rails app where I need to send emails using different Gmail accounts. I’ve set up ActionMailer with TLS support and configured it for one account in my environment.rb file. But now I’m stuck on how to dynamically switch between multiple accounts.

Here’s what I want to do:
We have 10 admins who need to send notices to customers. Each admin has their own Gmail account. When they fill out a form on our site, I want Rails to use their specific account to send the email.

I’ve tried looking for ways to override the username and password fields on the fly, but I’m not sure how to do it properly. Has anyone done something similar before? Any tips or code examples would be super helpful!

Thanks a bunch for your help!

# Current setup in environment.rb
ActionMailer::Base.smtp_settings = {
  enable_starttls_auto: true,
  address: 'smtp.gmail.com',
  port: 587,
  domain: 'myapp.com',
  authentication: :plain,
  user_name: '[email protected]',
  password: 'default_password'
}

How can I modify this to work with multiple accounts?

hey there! i’ve dealt with this b4. instead of messing with environment.rb, try using the mail gem. you can set up different delivery methods for each account. something like:

mail = Mail.new(to: ‘[email protected]’, from: admin.email)
mail.delivery_method :smtp, address: ‘smtp.gmail.com’, port: 587, user_name: admin.email, password: admin.password
mail.deliver!

Hope that helps!

I’ve encountered this issue in a previous project. One effective approach is to utilize the ‘interceptor’ feature of ActionMailer. You can create a custom interceptor that dynamically sets the SMTP settings based on the sender’s email address just before the message is delivered. Here’s a basic implementation:

class DynamicSmtpInterceptor
  def self.delivering_email(message)
    admin = Admin.find_by(email: message.from.first)
    if admin
      message.delivery_method.settings.merge!(
        user_name: admin.email,
        password: admin.smtp_password
      )
    end
  end
end

# In an initializer
ActionMailer::Base.register_interceptor(DynamicSmtpInterceptor)

This method keeps your global SMTP settings intact while allowing per-message customization. Remember to securely store and retrieve admin credentials, possibly using Rails’ encrypted credentials or a dedicated service.

I’ve worked on a similar problem before. Instead of configuring ActionMailer globally, I ended up creating a custom mailer for each admin session. In my project, I stored each admin’s Gmail credentials in a dedicated table and used a service object to generate a mailer instance on the fly. This allowed me to configure the SMTP settings just before sending an email. For example:

def send_email(admin, message)
  mailer = AdminMailer.new
  mailer.smtp_settings = {
    address: 'smtp.gmail.com',
    port: 587,
    user_name: admin.email,
    password: admin.email_password,
    # other settings...
  }
  mailer.custom_email(message).deliver_now
end

This method ensures that the correct account is used each time, and you can secure the credentials with Rails’ encrypted credentials feature.