email_api 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +148 -0
- data/.travis.yml +5 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +154 -0
- data/LICENSE.txt +21 -0
- data/README.md +195 -0
- data/Rakefile +7 -0
- data/bin/setup +6 -0
- data/config.ru +4 -0
- data/email_api.gemspec +44 -0
- data/lib/email_api.rb +47 -0
- data/lib/email_api/api/api_parser.rb +100 -0
- data/lib/email_api/email/client/email_client.rb +69 -0
- data/lib/email_api/email/client/mailgun_client.rb +123 -0
- data/lib/email_api/email/client/sendgrid_client.rb +115 -0
- data/lib/email_api/email/data/client_response.rb +40 -0
- data/lib/email_api/email/data/email_address.rb +21 -0
- data/lib/email_api/email/data/email_object.rb +43 -0
- metadata +274 -0
data/Rakefile
ADDED
data/bin/setup
ADDED
data/config.ru
ADDED
data/email_api.gemspec
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
lib = File.expand_path('../lib', __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
|
4
|
+
Gem::Specification.new do |spec|
|
5
|
+
spec.name = 'email_api'
|
6
|
+
spec.version = '1.0.0'
|
7
|
+
spec.authors = ['Vasili Moisiadis']
|
8
|
+
spec.email = ['vasili@moisiadis.com']
|
9
|
+
|
10
|
+
spec.summary = 'Email API'
|
11
|
+
spec.description = 'Backend Email API that accepts necessary information and sends emails using email service providers'
|
12
|
+
spec.homepage = 'https://github.com/VasiliMoisiadis/email-api'
|
13
|
+
spec.license = 'MIT'
|
14
|
+
|
15
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
16
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
17
|
+
unless spec.respond_to?(:metadata)
|
18
|
+
raise 'RubyGems 2.0 or newer is required to protect against ' \
|
19
|
+
'public gem pushes.'
|
20
|
+
end
|
21
|
+
|
22
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
23
|
+
f.match(%r{^(tests|spec|features)/})
|
24
|
+
end
|
25
|
+
spec.bindir = 'exe'
|
26
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
27
|
+
spec.require_paths = ['lib']
|
28
|
+
|
29
|
+
spec.add_development_dependency 'bundler', '~> 1.16'
|
30
|
+
spec.add_development_dependency 'dotenv', '~> 2.2.1'
|
31
|
+
spec.add_development_dependency 'json', '~> 2.1.0'
|
32
|
+
spec.add_development_dependency 'minitest', '~> 5.11.3'
|
33
|
+
spec.add_development_dependency 'minitest-reporters', '~> 1.1.19'
|
34
|
+
spec.add_development_dependency 'mocha', '~> 1.4.0'
|
35
|
+
spec.add_development_dependency 'puma', '~> 3.11.3'
|
36
|
+
spec.add_development_dependency 'rack-test', '~> 0.8.3'
|
37
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
38
|
+
spec.add_development_dependency 'rest-client', '~> 2.0.2'
|
39
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
40
|
+
spec.add_development_dependency 'rspec-rails', '~> 3.7.2'
|
41
|
+
spec.add_development_dependency 'simplecov', '~> 0.16.1'
|
42
|
+
spec.add_development_dependency 'sinatra', '~> 2.0.1'
|
43
|
+
spec.add_development_dependency 'thin', '~> 1.2.5'
|
44
|
+
end
|
data/lib/email_api.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
require 'json'
|
3
|
+
require 'date'
|
4
|
+
require './lib/email_api/api/api_parser'
|
5
|
+
require './lib/email_api/email/client/email_client'
|
6
|
+
require './lib/email_api/email/data/email_object'
|
7
|
+
|
8
|
+
# Main class of Email API Project
|
9
|
+
class EmailApi < Sinatra::Base
|
10
|
+
|
11
|
+
# Ping with current time
|
12
|
+
get '/ping' do
|
13
|
+
puts "Received new Ping Request from #{request.ip}"
|
14
|
+
{ time: Time.now.utc }.to_json
|
15
|
+
end
|
16
|
+
|
17
|
+
# Send Email (Supports calling through a web browser)
|
18
|
+
get '/send' do
|
19
|
+
puts "Received new Email Send GET Request from #{request.ip}"
|
20
|
+
handle_api(params).to_hash.to_json
|
21
|
+
end
|
22
|
+
|
23
|
+
# Send Email (Proper usage, as a POST request)
|
24
|
+
post '/send' do
|
25
|
+
puts "Received new Email Send POST Request from #{request.ip}"
|
26
|
+
handle_api(params).to_hash.to_json
|
27
|
+
end
|
28
|
+
|
29
|
+
# Handle request received through API
|
30
|
+
def handle_api(api_params)
|
31
|
+
return nil if !api_params.respond_to?(:[]) && !api_params.is_a?(Hash)
|
32
|
+
from = api_params['from']
|
33
|
+
to = api_params['to']
|
34
|
+
cc = api_params['cc']
|
35
|
+
bcc = api_params['bcc']
|
36
|
+
subject = api_params['subject']
|
37
|
+
content = api_params['content']
|
38
|
+
email_obj = ApiParser.parse_email(from, to, cc, bcc, subject, content)
|
39
|
+
EmailClient.send_email(email_obj)
|
40
|
+
rescue StandardError => e
|
41
|
+
puts "Error: #{e.class}: #{e.message}"
|
42
|
+
response = ClientResponse.new
|
43
|
+
response.set_internal_err
|
44
|
+
response
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require './lib/email_api/email/data/email_object'
|
2
|
+
require './lib/email_api/email/data/email_address'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
# Parser for Email API
|
6
|
+
class ApiParser
|
7
|
+
@email_delim ||= ','
|
8
|
+
|
9
|
+
# Accessor for the supported email delimiter
|
10
|
+
def self.email_delim
|
11
|
+
@email_delim
|
12
|
+
end
|
13
|
+
|
14
|
+
# Parses raw text into custom EmailAddress object
|
15
|
+
#
|
16
|
+
# @param [String] email_text Raw text denoting email
|
17
|
+
# @return [Email Address] email_address
|
18
|
+
def self.parse_email_text(email_text)
|
19
|
+
return nil if email_text.nil? || !email_text.is_a?(String)
|
20
|
+
|
21
|
+
restricted_chars = ',<>'
|
22
|
+
|
23
|
+
# Try to parse correct format: "DISPLAY NAME <EMAIL ADDRESS>"
|
24
|
+
name = nil
|
25
|
+
email = email_text[/.*<([^>]*)/, 1]
|
26
|
+
name = email_text.gsub(email, '') unless email.nil?
|
27
|
+
name = name.delete(restricted_chars).strip unless name.nil?
|
28
|
+
email = email.delete(restricted_chars).strip unless email.nil?
|
29
|
+
|
30
|
+
# If only one or the other found, assign value to both fields
|
31
|
+
name = email if (!email.nil? && !email.empty?) && (name.nil? || name.empty?)
|
32
|
+
email = name if (!name.nil? && !name.empty?) && (email.nil? || email.empty?)
|
33
|
+
|
34
|
+
# If neither found, take entire String as values
|
35
|
+
name = email = email_text.delete(restricted_chars).strip if name.nil? && email.nil?
|
36
|
+
|
37
|
+
EmailAddress.new(name, email)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Parse a String[] and returns an EmailAddres[]
|
41
|
+
#
|
42
|
+
# @param [String[]] email_text_arr Array of text, each being an email address
|
43
|
+
# @return [EmailAddress[]] email_arr
|
44
|
+
def self.parse_email_text_arr(email_text_arr)
|
45
|
+
return nil if email_text_arr.nil? || !email_text_arr.is_a?(String)
|
46
|
+
|
47
|
+
email_arr = []
|
48
|
+
# Split on email delimiter, parse each email
|
49
|
+
split_arr = email_text_arr.split(/(?<=[#{email_delim}])/, -1)
|
50
|
+
|
51
|
+
# Push value on through even if empty -> handled further down
|
52
|
+
email_arr.push(parse_email_text(email_text_arr)) if split_arr.empty?
|
53
|
+
split_arr.each do |email_text|
|
54
|
+
email_arr.push(parse_email_text(email_text))
|
55
|
+
end
|
56
|
+
|
57
|
+
email_arr = nil if !email_arr.nil? && email_arr.empty?
|
58
|
+
email_arr
|
59
|
+
end
|
60
|
+
|
61
|
+
# Parses parameter inputs into an EmailObject using the supported notation
|
62
|
+
#
|
63
|
+
# @param [Splat] params Raw Email Attribute Values
|
64
|
+
# @return [EmailObject] email_object Parsed email object
|
65
|
+
def self.parse_email(*params)
|
66
|
+
email_object = EmailObject.new
|
67
|
+
|
68
|
+
return email_object if params.nil? || !params.is_a?(Array) || params.empty?
|
69
|
+
|
70
|
+
to = cc = bcc = subject = content = nil
|
71
|
+
from = params[0]
|
72
|
+
to = params[1] if params.count > 1
|
73
|
+
cc = params[2] if params.count > 2
|
74
|
+
bcc = params[3] if params.count > 3
|
75
|
+
subj_raw = params[4] if params.count > 4
|
76
|
+
cont_raw = params[5] if params.count > 5
|
77
|
+
|
78
|
+
subject = nil
|
79
|
+
if !subj_raw.nil? && (subj_raw.is_a?(String) || subj_raw.is_a?(Numeric))
|
80
|
+
subject = subj_raw
|
81
|
+
end
|
82
|
+
|
83
|
+
content = nil
|
84
|
+
if !cont_raw.nil? && (cont_raw.is_a?(String) || cont_raw.is_a?(Numeric))
|
85
|
+
content = cont_raw
|
86
|
+
end
|
87
|
+
|
88
|
+
# Parse and assign Message Attributes
|
89
|
+
email_object.from = parse_email_text(from)
|
90
|
+
email_object.to = parse_email_text_arr(to)
|
91
|
+
email_object.cc = parse_email_text_arr(cc)
|
92
|
+
email_object.bcc = parse_email_text_arr(bcc)
|
93
|
+
email_object.subject = (subject.nil? || subject.empty? ? nil : subject)
|
94
|
+
email_object.content = (content.nil? || content.empty? ? nil : content)
|
95
|
+
|
96
|
+
email_object
|
97
|
+
end
|
98
|
+
|
99
|
+
private_class_method :parse_email_text_arr, :parse_email_text
|
100
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require './lib/email_api/email/client/mailgun_client'
|
2
|
+
require './lib/email_api/email/client/sendgrid_client'
|
3
|
+
require './lib/email_api/email/data/client_response'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
# General client that sends email utilizing multiple service providers
|
7
|
+
class EmailClient
|
8
|
+
|
9
|
+
# Accessor for the OK Code
|
10
|
+
def self.ok_code
|
11
|
+
200
|
12
|
+
end
|
13
|
+
|
14
|
+
# Accessor for the Bad Request Code
|
15
|
+
def self.bad_req_code
|
16
|
+
400
|
17
|
+
end
|
18
|
+
|
19
|
+
# Accessor for the Internal Server Error Code
|
20
|
+
def self.internal_err_code
|
21
|
+
500
|
22
|
+
end
|
23
|
+
|
24
|
+
# Sends email utilizing multiple service providers
|
25
|
+
#
|
26
|
+
# @param [EmailObject] email_object
|
27
|
+
# @return [ClientResponse] response
|
28
|
+
def self.send_email(email_object)
|
29
|
+
return ClientResponse.new if email_object.nil? || !email_object.is_a?(EmailObject)
|
30
|
+
|
31
|
+
puts 'Attempting Email Sending via primary client: SENDGRID'
|
32
|
+
response = use_client_client SendgridClient, email_object
|
33
|
+
|
34
|
+
if response != ok_code
|
35
|
+
puts 'Primary client failed. Attempting secondary client: MAILGUN'
|
36
|
+
response = use_client_client MailgunClient, email_object
|
37
|
+
end
|
38
|
+
|
39
|
+
client_response = ClientResponse.new email_object
|
40
|
+
if response == ok_code
|
41
|
+
client_response.set_ok
|
42
|
+
elsif response == bad_req_code
|
43
|
+
client_response.set_bad_req
|
44
|
+
elsif response == internal_err_code
|
45
|
+
client_response.set_internal_err
|
46
|
+
end
|
47
|
+
|
48
|
+
client_response
|
49
|
+
end
|
50
|
+
|
51
|
+
# Sends email using a single email client
|
52
|
+
#
|
53
|
+
# @param [MailgunClient|SendgridClient] email_client
|
54
|
+
# @param [EmailObject] email_object
|
55
|
+
# @return [Integer] response_code
|
56
|
+
def self.use_client_client(email_client, email_object)
|
57
|
+
begin
|
58
|
+
response = email_client.send_email(email_object)
|
59
|
+
puts 'Successful attempt' if response == ok_code
|
60
|
+
puts 'Bad Request' if response == bad_req_code
|
61
|
+
puts 'Internal Server Error' if response == internal_err_code
|
62
|
+
rescue StandardError => e
|
63
|
+
# Log error and fail send
|
64
|
+
puts "Error: #{e.message}"
|
65
|
+
response = internal_err_code
|
66
|
+
end
|
67
|
+
response
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require './lib/email_api/email/data/email_address'
|
2
|
+
require './lib/email_api/email/data/email_object'
|
3
|
+
require 'rest-client'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
# Client for sending email via Mailgun v3 API
|
7
|
+
class MailgunClient
|
8
|
+
@exp_msg ||= 'Queued. Thank you.'
|
9
|
+
@ok_code ||= 200
|
10
|
+
@bad_req_code ||= 400
|
11
|
+
@internal_err_code ||= 500
|
12
|
+
|
13
|
+
# Accessor for the expected success message
|
14
|
+
def self.exp_msg
|
15
|
+
@exp_msg
|
16
|
+
end
|
17
|
+
|
18
|
+
# Accessor for the OK Code
|
19
|
+
def self.ok_code
|
20
|
+
@ok_code
|
21
|
+
end
|
22
|
+
|
23
|
+
# Accessor for the Bad Request Code
|
24
|
+
def self.bad_req_code
|
25
|
+
@bad_req_code
|
26
|
+
end
|
27
|
+
|
28
|
+
# Accessor for the Internal Server Error Code
|
29
|
+
def self.internal_err_code
|
30
|
+
@internal_err_code
|
31
|
+
end
|
32
|
+
|
33
|
+
# Sends an email over HTTPS
|
34
|
+
#
|
35
|
+
# @param [EmailObject] email_object
|
36
|
+
# @return [Response] rest_client_response
|
37
|
+
def self.send_email(email_object)
|
38
|
+
|
39
|
+
# Build Mailgun-specific URL and POST data
|
40
|
+
api_key = ENV['MAILGUN_PRIVATE_KEY']
|
41
|
+
domain = ENV['MAILGUN_DOMAIN']
|
42
|
+
return internal_err_code if api_key.nil? || domain.nil?
|
43
|
+
|
44
|
+
post_data = parse_post_data(email_object, domain)
|
45
|
+
return bad_req_code if post_data.nil?
|
46
|
+
|
47
|
+
url = "https://api:#{api_key}@api.mailgun.net/v3/#{domain}/messages"
|
48
|
+
|
49
|
+
# Send Email, return response
|
50
|
+
begin
|
51
|
+
response = RestClient.post url, post_data
|
52
|
+
rescue StandardError => e
|
53
|
+
# Log error and fail send -> occurs when Code 400 due to implementation
|
54
|
+
puts "Error: #{e.message}"
|
55
|
+
return bad_req_code
|
56
|
+
end
|
57
|
+
|
58
|
+
puts "Secondary Client Response: #{response}"
|
59
|
+
|
60
|
+
# Handle expected output. Note that it is API specific.
|
61
|
+
return ok_code if JSON.parse(response)['message'] == exp_msg
|
62
|
+
|
63
|
+
bad_req_code
|
64
|
+
end
|
65
|
+
|
66
|
+
# Parses email address into proper, supported text format
|
67
|
+
#
|
68
|
+
# @param [EmailAddress] email_address
|
69
|
+
# @return [String] email_address_text
|
70
|
+
def self.parse_addr_text(email_address)
|
71
|
+
return nil if email_address.nil? || !email_address.is_a?(EmailAddress)
|
72
|
+
"#{email_address.name} <#{email_address.email}>"
|
73
|
+
end
|
74
|
+
|
75
|
+
# Parses array of email addresses into proper, supported text format
|
76
|
+
#
|
77
|
+
# @param [EmailAddress[]] email_address_arr
|
78
|
+
# @return [String] email_field
|
79
|
+
def self.parse_addr_arr(email_address_arr)
|
80
|
+
return '' if email_address_arr.nil? || !email_address_arr.is_a?(Array)
|
81
|
+
|
82
|
+
# Convert array of multiple email addresses to proper text format
|
83
|
+
email_field = ''
|
84
|
+
email_address_arr.each do |email_address|
|
85
|
+
addr_text = parse_addr_text(email_address)
|
86
|
+
unless addr_text.nil?
|
87
|
+
email_field += ', ' unless email_field.empty?
|
88
|
+
email_field += addr_text
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
email_field
|
93
|
+
end
|
94
|
+
|
95
|
+
# Parses an EmailObject into POST data for use in an API call
|
96
|
+
#
|
97
|
+
# @param [EmailObject] email_object
|
98
|
+
# @return [String] post_data
|
99
|
+
def self.parse_post_data(email_object, domain)
|
100
|
+
# Handle missing or unsupported input parameter
|
101
|
+
return nil if email_object.nil? || domain.nil? || !email_object.is_a?(EmailObject)
|
102
|
+
|
103
|
+
# Handle missing mandatory Email Attributes
|
104
|
+
return nil if email_object.from.nil? || email_object.to.nil? ||
|
105
|
+
email_object.subject.nil? || email_object.content.nil?
|
106
|
+
|
107
|
+
# Parse environment value and build Mailgun-specific FROM email
|
108
|
+
from_email = EmailAddress.new(email_object.from.name, "mailgun@#{domain}")
|
109
|
+
|
110
|
+
# Build Message Attributes
|
111
|
+
post_data = {}
|
112
|
+
post_data[:from] = parse_addr_text(from_email)
|
113
|
+
post_data[:to] = parse_addr_arr(email_object.to)
|
114
|
+
post_data[:cc] = parse_addr_arr(email_object.cc) unless email_object.cc.nil?
|
115
|
+
post_data[:bcc] = parse_addr_arr(email_object.bcc) unless email_object.bcc.nil?
|
116
|
+
post_data[:subject] = email_object.subject.to_s
|
117
|
+
post_data[:text] = email_object.content.to_s
|
118
|
+
|
119
|
+
post_data
|
120
|
+
end
|
121
|
+
|
122
|
+
private_class_method :parse_addr_text, :parse_addr_arr, :parse_post_data
|
123
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require './lib/email_api/email/data/email_object'
|
2
|
+
require 'rest-client'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
# Client for sending email via Sendgrid v2 API
|
6
|
+
class SendgridClient
|
7
|
+
@exp_msg ||= 'success'
|
8
|
+
@ok_code ||= 200
|
9
|
+
@bad_req_code ||= 400
|
10
|
+
@internal_err_code ||= 500
|
11
|
+
|
12
|
+
# Accessor for the expected success message
|
13
|
+
def self.exp_msg
|
14
|
+
@exp_msg
|
15
|
+
end
|
16
|
+
|
17
|
+
# Accessor for the OK Code
|
18
|
+
def self.ok_code
|
19
|
+
@ok_code
|
20
|
+
end
|
21
|
+
|
22
|
+
# Accessor for the Bad Request Code
|
23
|
+
def self.bad_req_code
|
24
|
+
@bad_req_code
|
25
|
+
end
|
26
|
+
|
27
|
+
# Accessor for the Internal Server Error Code
|
28
|
+
def self.internal_err_code
|
29
|
+
@internal_err_code
|
30
|
+
end
|
31
|
+
|
32
|
+
# Sends an email over HTTPS
|
33
|
+
#
|
34
|
+
# @param [EmailObject] email_object
|
35
|
+
# @return [int] status_code
|
36
|
+
def self.send_email(email_object)
|
37
|
+
|
38
|
+
# Parse Environment Values
|
39
|
+
api_user = ENV['SENDGRID_API_USER']
|
40
|
+
api_key = ENV['SENDGRID_API_KEY']
|
41
|
+
return internal_err_code if api_user.nil? || api_key.nil?
|
42
|
+
|
43
|
+
# Build Sendgrid-specific URL and POST data
|
44
|
+
url = 'https://api.sendgrid.com/api/mail.send.json'
|
45
|
+
post_data = parse_post_data(email_object, api_user, api_key)
|
46
|
+
return bad_req_code if post_data.nil?
|
47
|
+
|
48
|
+
# Send Email, return response
|
49
|
+
begin
|
50
|
+
response = RestClient.post url, post_data
|
51
|
+
rescue StandardError => e
|
52
|
+
# Log error and fail send -> occurs when Code 400 due to implementation
|
53
|
+
puts "Error: #{e.message}"
|
54
|
+
return bad_req_code
|
55
|
+
end
|
56
|
+
|
57
|
+
puts "Primary Client Response: #{response}"
|
58
|
+
|
59
|
+
return bad_req_code if response.nil? || !JSON.parse(response).respond_to?(:[])
|
60
|
+
|
61
|
+
# Handle expected output. Note that it is API specific.
|
62
|
+
json_response = JSON.parse(response)
|
63
|
+
if !json_response.key?('message').nil? && json_response['message'] == exp_msg
|
64
|
+
return ok_code
|
65
|
+
end
|
66
|
+
|
67
|
+
internal_err_code # Unhandled response
|
68
|
+
end
|
69
|
+
|
70
|
+
# Parses an EmailObject into POST data for use in an API call
|
71
|
+
#
|
72
|
+
# @param [EmailObject] email_object
|
73
|
+
# @return [String] post_data
|
74
|
+
def self.parse_post_data(email_object, api_user, api_key)
|
75
|
+
|
76
|
+
# Handle missing Environment Variables
|
77
|
+
return nil if api_user.nil? || api_key.nil?
|
78
|
+
|
79
|
+
# Handle missing or unsupported input parameter
|
80
|
+
return nil if email_object.nil? || !email_object.is_a?(EmailObject)
|
81
|
+
|
82
|
+
# Handle missing mandatory Email Attributes
|
83
|
+
return nil if email_object.from.nil? || email_object.to.nil? ||
|
84
|
+
email_object.subject.nil? || email_object.content.nil?
|
85
|
+
|
86
|
+
|
87
|
+
# Build Message Attributes
|
88
|
+
post_data = "api_user=#{api_user}"
|
89
|
+
post_data += "&api_key=#{api_key}"
|
90
|
+
post_data += "&subject=#{email_object.subject}"
|
91
|
+
post_data += "&text=#{email_object.content}"
|
92
|
+
post_data += "&from=#{email_object.from.email}"
|
93
|
+
post_data += "&fromname[]=#{email_object.from.name}"
|
94
|
+
email_object.to.each do |address|
|
95
|
+
post_data += "&to[]=#{address.email}"
|
96
|
+
post_data += "&toname[]=#{address.name}"
|
97
|
+
end
|
98
|
+
unless email_object.cc.nil?
|
99
|
+
email_object.cc.each do |address|
|
100
|
+
post_data += "&cc[]=#{address.email}"
|
101
|
+
post_data += "&ccname[]=#{address.name}"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
unless email_object.bcc.nil?
|
105
|
+
email_object.bcc.each do |address|
|
106
|
+
post_data += "&bcc[]=#{address.email}"
|
107
|
+
post_data += "&bccname[]=#{address.name}"
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
post_data
|
112
|
+
end
|
113
|
+
|
114
|
+
private_class_method :parse_post_data
|
115
|
+
end
|