messagebus-sdk 4.1.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.
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use ruby-1.9.2-p290 --create
data/Gemfile ADDED
@@ -0,0 +1,15 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem 'activesupport'
4
+
5
+ gem 'multipart-post'
6
+
7
+ group :test, :development do
8
+ gem 'rspec', '2.5.0'
9
+ gem 'rr', '1.0.2'
10
+ gem 'fakeweb'
11
+ gem 'actionmailer'
12
+ end
13
+
14
+ # Specify your gem's dependencies in messagebus.gemspec
15
+ gemspec
data/README.md ADDED
@@ -0,0 +1,183 @@
1
+ ![MB icon](https://www.messagebus.com/wp-content/themes/msg/images/Message-Bus_LOGO.png)
2
+
3
+ ###Message Bus Ruby SDK
4
+
5
+ Message Bus is a cloud-based platform for easily sending email at scale and with complete insight into your messaging traffic and how recipients are responding to it. All platform functions are available via [REST API](http://www.messagebus.com/documentation) as well as the language-specific documentation, sample code, libraries, and/or compiled binaries contained in this SDK.
6
+
7
+ Samples include how to:
8
+
9
+ * Create sessions
10
+ * Send messages
11
+ * Use templates
12
+ * Check email stats
13
+
14
+ If you have questions not answered by the samples or the online documentation, please contact [support](mailto:support@messagebus.com).
15
+
16
+
17
+ ####Installing the module
18
+
19
+ gem install messagebus-sdk
20
+
21
+ If running the examples from the project without installing the gem, you will
22
+ need to set RUBYLIB path.
23
+
24
+ Example: export RUBYLIB=/Users/<user_name>/workspace/messagebus-ruby-sdk/lib/messagebus-sdk
25
+
26
+ ####Sending emails
27
+
28
+ require 'messagebus-sdk/api_client'
29
+
30
+ api_key="12345678934628542E2599F7ED712345"
31
+ api_host="https://api-v4.messagebus.com"
32
+
33
+ client = MessagebusApiClient.new(api_key, api_host)
34
+
35
+ session_key = "DEFAULT"
36
+
37
+ messages = [
38
+ {:toEmail => 'bobby@example.com',
39
+ :toName => 'Bobby Flay',
40
+ :fromEmail => 'alice@example.com',
41
+ :fromName => 'Alice Waters',
42
+ :subject => 'Sample Message with HTML body.',
43
+ :customHeaders => {"x-messagebus-sdk"=>"ruby-sdk"},
44
+ :plaintextBody => 'This is the plain text body.',
45
+ :htmlBody => 'This is the <b>HTML</b>body.',
46
+ :sessionKey => session_key},
47
+ {:toEmail => 'jamie@example.com',
48
+ :toName => 'Jamie Lauren',
49
+ :fromEmail => 'alice@example.com',
50
+ :fromName => 'Alice Waters',
51
+ :subject => 'Simple Example with no HTML body.',
52
+ :customHeaders => {"x-messagebus-sdk"=>"ruby-sdk"},
53
+ :plaintextBody => 'This is the plaintext example.',
54
+ :sessionKey => session_key}
55
+ ]
56
+
57
+ begin
58
+ response = client.send_messages(messages)
59
+ if response[:statusCode] == 202
60
+ puts "Email send results"
61
+ response[:results].each do |message|
62
+ puts "To: #{message[:toEmail]} Message Id: #{message[:messageId]} Message Status: #{message[:messageStatus]}"
63
+ end
64
+ else
65
+ puts "#{response[:statusMessage]}"
66
+ end
67
+ rescue Exception=>e
68
+ puts "Exception thrown. Error during send: #{e.message}"
69
+ end
70
+
71
+ ####Sending emails with ActionMailer
72
+
73
+ require 'action_mailer'
74
+ require 'messagebus-sdk/actionmailer_client'
75
+
76
+ class MessagebusMailer < MessagebusActionMailerClient
77
+ def initialize(*args)
78
+ api_key = "12345678934628542E2599F7ED712345"
79
+ api_endpoint = "https://api-v4.messagebus.com"
80
+ super(api_key, api_endpoint)
81
+ end
82
+ end
83
+
84
+ ActionMailer::Base.add_delivery_method :messagebus, MessagebusMailer
85
+ ActionMailer::Base.delivery_method = :messagebus
86
+
87
+ class MessageBusActionMailerTest < ActionMailer::Base
88
+ default :from => "no-reply@messagebus.com",
89
+ :body => "This is a test",
90
+ :subject => "Unit Test",
91
+ :return_path => "bounce@bounces.example.com"
92
+
93
+ def test_message(to_email, session_key)
94
+ headers[MessagebusSDK::MessagebusBase::HEADER_SESSION_KEY] = session_key
95
+ mail(:to => to_email)
96
+ end
97
+ end
98
+
99
+ to_email = "hello@example.com"
100
+ session_key = "DEFAULT"
101
+ message = MessageBusActionMailerTest.test_message(to_email, session_key)
102
+ message.deliver
103
+
104
+ ####Checking email statistics
105
+
106
+ require 'messagebus-sdk/stats_client'
107
+
108
+ api_key = "12345678934628542E2599F7ED712345"
109
+ api_host = "https://api-v4.messagebus.com"
110
+
111
+ client = MessagebusStatsClient.new(api_key, api_host)
112
+
113
+ begin
114
+ response = client.stats
115
+ if response[:statusCode] == 200
116
+ stats = response[:stats]
117
+ puts "Stats"
118
+ puts "\tMessages Attempted: #{stats[:msgsAttemptedCount]}"
119
+ puts "\tComplaint Count: #{stats[:complaintCount]}"
120
+ puts "\tUnsubscribe Count: #{stats[:unsubscribeCount]}"
121
+ puts "\tOpen Count: #{stats[:openCount]}"
122
+ puts "\tUnique Open Count: #{stats[:uniqueOpenCount]}"
123
+ puts "\tClick Count: #{stats[:clickCount]}"
124
+
125
+ smtp = response[:smtp]
126
+ puts "SMTP"
127
+ puts "\tAccept Count: #{smtp[:acceptCount]}"
128
+ puts "\tBounce Count: #{smtp[:bounceCount]}"
129
+ puts "\tReject Count: #{smtp[:rejectCount]}"
130
+ puts "\tError Count: #{smtp[:errorCount]}"
131
+
132
+ filter = response[:filter]
133
+ puts "Filter"
134
+ puts "\tBad Mailbox Count: #{filter[:rcptBadMailboxCount]}"
135
+ puts "\tChannel Block Count: #{filter[:rcptChannelBlockCount]}"
136
+
137
+ else
138
+ puts "#{response[:statusMessage]}"
139
+ end
140
+ rescue Exception=>e
141
+ puts "Exception thrown. Error during stats retrieval: #{e.message}"
142
+ end
143
+
144
+ #### Checking email feedback data
145
+
146
+ require 'messagebus-sdk/feedback_client'
147
+
148
+ api_key = "12345678934628542E2599F7ED712345"
149
+ api_host = "https://api-v4.messagebus.com"
150
+
151
+ client = MessagebusFeedbackClient.new(api_key, api_host)
152
+
153
+ begin
154
+ response = client.feedback
155
+ if response[:statusCode] == 200
156
+ puts "Bounces"
157
+ response[:bounces].each do |bounce|
158
+ puts "Email: #{bounce[:email]} Count: #{bounce[:count]} BounceCode: #{bounce[:bounceCode]} LastEventTime: #{bounce[:lastEventTime]}"
159
+ end
160
+ puts "Clicks"
161
+ response[:clicks].each do |click|
162
+ puts "Email: #{click[:email]} Count: #{click[:count]} LastEventTime: #{click[:lastEventTime]}"
163
+ end
164
+ else
165
+ puts "#{response[:statusMessage]}"
166
+ end
167
+ rescue Exception=>e
168
+ puts "Exception thrown. Error during feedback retrieval: #{e.message}"
169
+ end
170
+
171
+ #### License
172
+
173
+
174
+ Copyright (c) 2013 Mail Bypass, Inc.
175
+
176
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
177
+ with the License. You may obtain a copy of the License at
178
+
179
+ http://www.apache.org/licenses/LICENSE-2.0
180
+
181
+ Unless required by applicable law or agreed to in writing, software distributed under the License is
182
+ distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
183
+ See the License for the specific language governing permissions and limitations under the License
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+ require 'rspec/core/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new(:spec) do |task|
6
+ task.rspec_opts = '-c -f d'
7
+ end
8
+ task :default => :spec
@@ -0,0 +1,88 @@
1
+ # Copyright 2013 Message Bus, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may
4
+ # not use this file except in compliance with the License. You may obtain
5
+ # a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
+ # License for the specific language governing permissions and limitations
13
+ # under the License.
14
+
15
+ require 'api_client'
16
+
17
+ class MessagebusActionMailerClient < MessagebusApiClient
18
+
19
+ #used by ActionMailer
20
+ def deliver(message)
21
+ deliver!(message)
22
+ end
23
+
24
+ def deliver!(message)
25
+ #minimum required headers
26
+ if message.to.first.nil? ||message.subject.nil? || message.from.first.nil? then
27
+ raise "Messagebus API error=Missing required header: :toEmail => #{message.to.first} :subject => #{message.subject} :fromEmail => #{message.from.first}"
28
+ end
29
+
30
+ message_from_email = from_email_with_name(message.header[:from].to_s)
31
+
32
+ from_name = ""
33
+ from_email = message.from.first
34
+ if !message_from_email.nil?
35
+ from_name = message_from_email[1]
36
+ end
37
+
38
+ if !well_formed_address?(from_email)
39
+ raise "Messagebus API error=From Address is invalid :toEmail => #{message.to.first} :subject => #{message.subject} :fromEmail => #{message.from.first}"
40
+ end
41
+
42
+ custom_headers = {}
43
+
44
+ custom_headers["envelope-sender"] = message.return_path if !message.return_path.nil?
45
+ custom_headers["bcc"] = message.bcc[0] if !message.bcc.nil?
46
+
47
+ session_key = DEFAULT
48
+ message.header.fields.each do |f|
49
+ if f.name == HEADER_SESSION_KEY
50
+ session_key = f.value
51
+ else
52
+ if f.name =~ /x-.*/i
53
+ custom_headers[f.name] = f.value
54
+ end
55
+ end
56
+ end
57
+
58
+ msg = {
59
+ :toEmail => message.to.first,
60
+ :toName => "",
61
+ :subject => message.subject,
62
+ :fromEmail => from_email,
63
+ :fromName => from_name,
64
+ :sessionKey => session_key,
65
+ :customHeaders => custom_headers
66
+ }
67
+
68
+ msg[:plaintextBody] = ( message.body ) ? "#{message.body}" : "No plaintext version was supplied."
69
+
70
+ if message.multipart?
71
+ msg[:plaintextBody] = (message.text_part) ? message.text_part.body.to_s : "No plaintext version was supplied."
72
+ msg[:htmlBody] = message.html_part.body.to_s if message.html_part
73
+ end
74
+
75
+ begin
76
+ send_messages([msg])
77
+ rescue => message_bus_api_error
78
+ raise "Messagebus API error=#{message_bus_api_error}, message=#{msg.inspect}"
79
+ end
80
+
81
+ end
82
+
83
+ private
84
+ def from_email_with_name(address)
85
+ address.match(/^(.*)\s<(.*?)>/)
86
+ end
87
+ end
88
+
@@ -0,0 +1,69 @@
1
+ # Copyright 2013 Message Bus, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may
4
+ # not use this file except in compliance with the License. You may obtain
5
+ # a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
+ # License for the specific language governing permissions and limitations
13
+ # under the License.
14
+
15
+ require 'messagebus_base'
16
+
17
+ class MessagebusApiClient < MessagebusSDK::MessagebusBase
18
+
19
+ def initialize(api_key, api_endpoint = DEFAULT_API_ENDPOINT)
20
+ super(api_key, api_endpoint)
21
+ @rest_endpoints = define_rest_endpoints
22
+ end
23
+
24
+ def send_messages(params)
25
+ path = @rest_endpoints[:message_emails_send]
26
+ json = {:messages => params}.to_json
27
+ make_api_request(path, HTTP_POST, json)
28
+ end
29
+
30
+ def channels
31
+ path = "#{@rest_endpoints[:channels]}"
32
+ make_api_request(path, HTTP_GET)
33
+ end
34
+
35
+ def channel_config(channel_key)
36
+ path = replace_channel_key("#{@rest_endpoints[:channel_config]}", channel_key)
37
+ make_api_request(path, HTTP_GET)
38
+ end
39
+
40
+ def channel_sessions(channel_key)
41
+ path = replace_channel_key("#{@rest_endpoints[:channel_sessions]}", channel_key)
42
+ make_api_request(path, HTTP_GET)
43
+ end
44
+
45
+ def channel_create_session(channel_key, session_name)
46
+ path = replace_channel_key("#{@rest_endpoints[:channel_sessions]}", channel_key)
47
+ json = {:sessionName => session_name}.to_json
48
+ make_api_request(path, HTTP_POST, json)
49
+ end
50
+
51
+ def channel_rename_session(channel_key, session_key, session_name)
52
+ path = replace_channel_and_session_key("#{@rest_endpoints[:channel_session_rename]}", channel_key, session_key)
53
+ json = {:sessionName => session_name}.to_json
54
+ make_api_request(path, HTTP_PUT, json)
55
+ end
56
+
57
+ private
58
+
59
+ def define_rest_endpoints
60
+ {
61
+ :message_emails_send => "/api/v4/message/email/send",
62
+ :channels => "/api/v4/channels",
63
+ :channel_config => "/api/v4/channel/%CHANNEL_KEY%/config",
64
+ :channel_sessions => "/api/v4/channel/%CHANNEL_KEY%/sessions",
65
+ :channel_session_rename => "/api/v4/channel/%CHANNEL_KEY%/session/%SESSION_KEY%/rename"
66
+ }
67
+ end
68
+ end
69
+
@@ -0,0 +1,104 @@
1
+ # Copyright 2013 Message Bus, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may
4
+ # not use this file except in compliance with the License. You may obtain
5
+ # a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
+ # License for the specific language governing permissions and limitations
13
+ # under the License.
14
+
15
+ require 'messagebus_base'
16
+
17
+ class MessagebusFeedbackClient < MessagebusSDK::MessagebusBase
18
+
19
+ def initialize(api_key, api_endpoint = DEFAULT_API_ENDPOINT)
20
+ super(api_key, api_endpoint)
21
+ @rest_endpoints = define_rest_endpoints
22
+ end
23
+
24
+ def feedback(start_date = '', end_date = '', scope = SCOPE_ALL, use_send_time = TRUE_VALUE)
25
+ path = "#{@rest_endpoints[:feedback]}#{feedback_query_args(start_date, end_date, use_send_time, scope)}"
26
+ make_api_request(path)
27
+ end
28
+
29
+ def feedback_by_channel(channel_key, start_date = '', end_date = '', scope = SCOPE_ALL, use_send_time = TRUE_VALUE)
30
+ path = "#{replace_channel_key(@rest_endpoints[:feedback_channel], channel_key)}#{feedback_query_args(start_date, end_date, use_send_time, scope)}"
31
+ make_api_request(path)
32
+ end
33
+
34
+ def feedback_by_session(channel_key, session_key, start_date = '', end_date = '', scope = SCOPE_ALL, use_send_time = TRUE_VALUE)
35
+ path = "#{replace_channel_and_session_key(@rest_endpoints[:feedback_session], channel_key, session_key)}#{feedback_query_args(start_date, end_date, use_send_time, scope)}"
36
+ make_api_request(path)
37
+ end
38
+
39
+ def unsubs(start_date = '', end_date = '')
40
+ path = "#{@rest_endpoints[:unsubs]}?#{date_range(start_date, end_date)}"
41
+ make_api_request(path)
42
+ end
43
+
44
+ def unsubs_by_channel(channel_key, start_date = '', end_date = '')
45
+ path = "#{replace_channel_key(@rest_endpoints[:unsubs_channel], channel_key)}?#{date_range(start_date, end_date)}"
46
+ make_api_request(path)
47
+ end
48
+
49
+ def unsubs_by_session(channel_key, session_key, start_date = '', end_date = '')
50
+ path = "#{replace_channel_and_session_key(@rest_endpoints[:unsubs_session], channel_key, session_key)}?#{date_range(start_date, end_date)}"
51
+ make_api_request(path)
52
+ end
53
+
54
+ def complaints(start_date = '', end_date = '')
55
+ path = "#{@rest_endpoints[:complaints]}?#{date_range(start_date, end_date)}"
56
+ make_api_request(path)
57
+ end
58
+
59
+ def complaints_by_channel(channel_key, start_date = '', end_date = '')
60
+ path = "#{replace_channel_key(@rest_endpoints[:complaints_channel], channel_key)}?#{date_range(start_date, end_date)}"
61
+ make_api_request(path)
62
+ end
63
+
64
+ def complaints_by_session(channel_key, session_key, start_date = '', end_date = '')
65
+ path = "#{replace_channel_and_session_key(@rest_endpoints[:complaints_session], channel_key, session_key)}?#{date_range(start_date, end_date)}"
66
+ make_api_request(path)
67
+ end
68
+
69
+ def bounces(start_date = '', end_date = '')
70
+ path = "#{@rest_endpoints[:bounces]}?#{date_range(start_date, end_date)}"
71
+ make_api_request(path)
72
+ end
73
+
74
+ def bounces_by_channel(channel_key, start_date = '', end_date = '')
75
+ path = "#{replace_channel_key(@rest_endpoints[:bounces_channel], channel_key)}?#{date_range(start_date, end_date)}"
76
+ make_api_request(path)
77
+ end
78
+
79
+ def bounces_by_session(channel_key, session_key, start_date = '', end_date = '')
80
+ path = "#{replace_channel_and_session_key(@rest_endpoints[:bounces_session], channel_key, session_key)}?#{date_range(start_date, end_date)}"
81
+ make_api_request(path)
82
+ end
83
+
84
+ private
85
+
86
+ def define_rest_endpoints
87
+ {
88
+ :feedback => "/api/v4/feedback",
89
+ :feedback_channel => "/api/v4/feedback/channel/%CHANNEL_KEY%",
90
+ :feedback_session => "/api/v4/feedback/channel/%CHANNEL_KEY%/session/%SESSION_KEY%",
91
+ :unsubs => "/api/v4/unsubs",
92
+ :unsubs_channel => "/api/v4/unsubs/channel/%CHANNEL_KEY%",
93
+ :unsubs_session => "/api/v4/unsubs/channel/%CHANNEL_KEY%/session/%SESSION_KEY%",
94
+ :complaints => "/api/v4/complaints",
95
+ :complaints_channel => "/api/v4/complaints/channel/%CHANNEL_KEY%",
96
+ :complaints_session => "/api/v4/complaints/channel/%CHANNEL_KEY%/session/%SESSION_KEY%",
97
+ :bounces => "/api/v4/bounces",
98
+ :bounces_channel => "/api/v4/bounces/channel/%CHANNEL_KEY%",
99
+ :bounces_session => "/api/v4/bounces/channel/%CHANNEL_KEY%/session/%SESSION_KEY%"
100
+ }
101
+ end
102
+
103
+ end
104
+