2017-11-14 5 views
1

としてというユーザーに電子メールを送信するために使用するサードパーティの電子メール統合ライブラリがあります。メールを送信するには、ユーザーごとに保存するaccess_tokenを使用してAPI呼び出しを行います。カスタムアクションに追加情報を渡すメーラー配信クラス

まだアクションメーラーを使用するには、私はこのようなカスタム配信クラスを作成しました:

module Mail 
    class CustomMailDelivery 
    attr_reader :settings 

    def initialize(settings) 
     @settings = settings 
    end 

    def deliver!(mail) 
     # use 3rd party client here 
    end 
    end 
end 

私はイニシャライザでこれを構成していますが:

ActionMailer::Base.add_delivery_method :custom, Mail::CustomMailDelivery, { 
    app_id: ENV.fetch('3RDPARTY_APP_ID'), 
    app_secret: ENV.fetch('3RDPARTY_APP_SECRET'), 
} 

これは私が設定することができますメーラー単位での配送方法:

class LeadMailer < ApplicationMailer 
    self.delivery_method = :custom 

    ... 
end 

問題は、私はtを送信しているユーザーを渡す必要があります彼のメッセージは、私は彼らのaccess_tokenを得ることができます。道路を打破することができ、このように思えるので、私は、送信者の電子メールアドレスを使用してEmailAccountのフェッチに依存したくない

は、(それがこのメールアドレス送信ユーザーと同じではないかもしれませんが可能です)。 つまり、明示的に渡したいので分かりやすく混乱を避けます。

カスタムアクションメーラー配信クラスにメールごとのコンテキストを提供する方法はありますか?

答えて

0

メッセージを処理するときに後で削除するカスタムメッセージヘッダーでこのデータを渡してしまいました。

class CustomMailer < ApplicationMailer 
    self.delivery_method = :custom 

    attr_reader :sending_account 

    def mail(params) 
    raise 'You must call set_sending_account before calling mail.' unless sending_email_account 
    super(params.merge({ 
     Mail::CustomMailDelivery::ACCOUNT_ID_HEADER => sending_account.id 
     })) 
    end 

    def set_sending_account(account) 
    @sending_account = account 
    end 
end 

このように、このクラスからこの動作サブクラスを必要とするメーラは、カスタムデータを提供する必要があります。

私は、ヘッダーのうち、この値をヤンク出荷クラスで

module Mail 
    class CustomMailDelivery 
    attr_reader :settings 

    # we'll hijack email headers in order to pass over some required data from the mailer to this class 
    ACCOUNT_ID_HEADER = '__account_id' 

    def initialize(settings) 
     @settings = settings 
    end 

    def deliver!(mail) 
     account = account_for(mail) 
     client = third_party_api_client(account.access_token) 
     client.send_message(...) 
    end 

    private 

    def third_party_api_client(access_token) 
     # ... 
    end 

    def account_for(mail) 
     header_field = mail[ACCOUNT_ID_HEADER] 
     missing_account_id_header! unless header_field 
     email_account = Account.find(header_field.value) 

     # remove the header field so it doesn't show up in the actual email 
     mail[ACCOUNT_ID_HEADER] = nil 

     account 
    end 

    def missing_account_id_header! 
     raise "Missing required header: #{ACCOUNT_ID_HEADER}" 
    end 
    end 
end 

このソリューションは非常にエレガントではありませんが、動作します。

関連する問題