app/actions/accounts/prevalidate_email.rb
# frozen_string_literal: true
module Accounts
class PrevalidateEmail < Action
class EmailableError < StandardError; end
HTTP_TIMEOUT = 10.seconds
API_KEY = ENV.fetch('EMAILABLE_API_KEY', nil)
URL = 'https://api.emailable.com/v1/verify'
URL_TEMPLATE = Addressable::Template.new("#{URL}?api_key=#{API_KEY}{&email}").freeze
parameter :email, required: true
def call
{ result:, reason: }
end
private
def reason
ActiveSupport::StringInquirer.new(response_data['reason'] || '')
end
def result
ActiveSupport::StringInquirer.new(response_data['state'] || '')
end
def response_data
return @response_data if @response_data
return @response_data = default_unknown_response_for('unauthorized') unless API_KEY
response = HTTP.timeout(HTTP_TIMEOUT.to_i).get(url)
if response.status == 200
@response_data = response.parse
else
Sentry.capture_exception(EmailableError.new, extra: {
response_status: response.status,
response_data: response.parse
})
@response_data = default_unknown_response_for('bad_gateway')
end
rescue HTTP::TimeoutError => e
Sentry.capture_exception(e)
@response_data = default_unknown_response_for('timeout')
end
def default_unknown_response_for(reason)
{
'state' => 'unknown',
'reason' => reason,
'email' => email
}
end
def url
@url ||= URL_TEMPLATE.expand(email:)
end
end
end