mailgun-ruby 1.0.3 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.rubocop.yml +8 -0
  4. data/.rubocop_todo.yml +22 -0
  5. data/.ruby-env.yml.example +12 -0
  6. data/.travis.yml +6 -12
  7. data/Domains.md +36 -0
  8. data/MessageBuilder.md +14 -14
  9. data/Messages.md +44 -30
  10. data/OptInHandler.md +34 -34
  11. data/README.md +74 -24
  12. data/Rakefile +22 -20
  13. data/Snippets.md +26 -26
  14. data/Webhooks.md +40 -0
  15. data/lib/mailgun.rb +26 -228
  16. data/lib/mailgun/chains.rb +16 -0
  17. data/lib/mailgun/client.rb +143 -0
  18. data/lib/mailgun/domains/domains.rb +84 -0
  19. data/lib/mailgun/events/events.rb +53 -35
  20. data/lib/mailgun/exceptions/exceptions.rb +43 -10
  21. data/lib/mailgun/lists/opt_in_handler.rb +18 -19
  22. data/lib/mailgun/messages/batch_message.rb +31 -48
  23. data/lib/mailgun/messages/message_builder.rb +160 -144
  24. data/lib/mailgun/response.rb +55 -0
  25. data/lib/mailgun/version.rb +2 -3
  26. data/lib/mailgun/webhooks/webhooks.rb +101 -0
  27. data/mailgun.gemspec +16 -10
  28. data/spec/integration/bounces_spec.rb +44 -0
  29. data/spec/integration/campaign_spec.rb +60 -0
  30. data/spec/integration/complaints_spec.rb +38 -0
  31. data/spec/integration/domains_spec.rb +39 -0
  32. data/spec/integration/email_validation_spec.rb +29 -0
  33. data/spec/integration/events_spec.rb +20 -0
  34. data/spec/integration/list_members_spec.rb +63 -0
  35. data/spec/integration/list_spec.rb +58 -0
  36. data/spec/integration/mailgun_spec.rb +26 -550
  37. data/spec/integration/routes_spec.rb +74 -0
  38. data/spec/integration/stats_spec.rb +15 -0
  39. data/spec/integration/unsubscribes_spec.rb +42 -0
  40. data/spec/integration/webhook_spec.rb +54 -0
  41. data/spec/spec_helper.rb +37 -7
  42. data/spec/unit/connection/test_client.rb +15 -95
  43. data/spec/unit/events/events_spec.rb +9 -6
  44. data/spec/unit/lists/opt_in_handler_spec.rb +6 -4
  45. data/spec/unit/mailgun_spec.rb +25 -19
  46. data/spec/unit/messages/batch_message_spec.rb +47 -38
  47. data/spec/unit/messages/message_builder_spec.rb +282 -111
  48. data/vcr_cassettes/bounces.yml +175 -0
  49. data/vcr_cassettes/complaints.yml +175 -0
  50. data/vcr_cassettes/domains.todo.yml +42 -0
  51. data/vcr_cassettes/domains.yml +360 -0
  52. data/vcr_cassettes/email_validation.yml +104 -0
  53. data/vcr_cassettes/events.yml +61 -0
  54. data/vcr_cassettes/list_members.yml +320 -0
  55. data/vcr_cassettes/mailing_list.todo.yml +43 -0
  56. data/vcr_cassettes/mailing_list.yml +390 -0
  57. data/vcr_cassettes/routes.yml +359 -0
  58. data/vcr_cassettes/send_message.yml +107 -0
  59. data/vcr_cassettes/stats.yml +44 -0
  60. data/vcr_cassettes/unsubscribes.yml +191 -0
  61. data/vcr_cassettes/webhooks.yml +276 -0
  62. metadata +114 -10
data/Rakefile CHANGED
@@ -1,33 +1,35 @@
1
- begin
2
- require 'bundler/gem_tasks'
3
- rescue LoadError
4
- end
5
-
1
+ require 'bundler/gem_tasks'
6
2
  require 'rake'
7
3
  require 'rspec/core/rake_task'
8
- require 'bundler/gem_tasks'
9
-
10
- desc "Build Gem"
11
- task :default do
12
- system "gem build mailgun.gemspec"
13
- end
14
4
 
15
- desc "Run default unit specs"
16
- RSpec::Core::RakeTask.new('spec') do |t|
17
- t.rspec_opts = %w{--colour --format progress}
18
- t.pattern = 'spec/unit/*_spec.rb', 'spec/unit/*/*_spec.rb'
5
+ desc 'Build Gem'
6
+ task :build do
7
+ system 'gem build mailgun.gemspec'
19
8
  end
20
9
 
21
- desc "Run unit specs"
10
+ desc 'Run unit specs'
22
11
  RSpec::Core::RakeTask.new('spec:unit') do |t|
23
- t.rspec_opts = %w{--colour --format progress}
12
+ t.rspec_opts = %w(--colour --format documentation)
24
13
  t.pattern = 'spec/unit/*_spec.rb', 'spec/unit/*/*_spec.rb'
25
14
  end
26
15
 
27
- desc "Run integration specs"
16
+ desc 'Run integration specs'
28
17
  # Before running integration tests, you need to specify
29
18
  # a valid API KEY in the spec/spec_helper.rb file.
30
19
  RSpec::Core::RakeTask.new('spec:integration') do |t|
31
- t.rspec_opts = %w{--colour --format progress}
20
+ t.rspec_opts = %w(--colour --format documentation)
32
21
  t.pattern = 'spec/integration/*_spec.rb'
33
- end
22
+ end
23
+
24
+ desc 'Run all tests'
25
+ RSpec::Core::RakeTask.new('spec:all') do |t|
26
+ t.rspec_opts = %w(--colour --format documentation)
27
+ t.pattern = 'spec/**/*_spec.rb'
28
+ end
29
+
30
+ task default: 'spec:unit'
31
+ task spec: 'spec:unit'
32
+
33
+ task :console do
34
+ sh 'pry --gem'
35
+ end
@@ -1,15 +1,15 @@
1
1
  Mailgun-Ruby Snippets
2
2
  =====================
3
3
 
4
- This page is filled with snippets that cover almost every API endpoint and action. Copy, Paste, Go! There will be little inline documentation in these samples, please consult Mailgun's official documentation for detailed information.
4
+ This page is filled with snippets that cover almost every API endpoint and action. Copy, Paste, Go! There will be little inline documentation in these samples, please consult Mailgun's official documentation for detailed information.
5
5
 
6
- If you haven't already installed the SDK, go to the README and follow the installation instructions.
6
+ If you haven't already installed the SDK, go to the README and follow the installation instructions.
7
7
 
8
8
  These snippets require that you pipe in a few parameters. "mg_client" is instantiated like so:
9
9
 
10
10
  ```ruby
11
11
  require 'mailgun'
12
- mg_client = Mailgun::Client.new "your-api-key"
12
+ mg_client = Mailgun::Client.new "your-api-key"
13
13
  ```
14
14
 
15
15
  ### Messages:
@@ -17,9 +17,9 @@ ____________________________________________________
17
17
  **Send a basic message: **
18
18
 
19
19
  ```ruby
20
- data = {:from => 'bob@sending_domain.com',
21
- :to => 'sally@example.com',
22
- :subject => 'The Ruby SDK is awesome!',
20
+ data = {:from => 'bob@sending_domain.com',
21
+ :to => 'sally@example.com',
22
+ :subject => 'The Ruby SDK is awesome!',
23
23
  :text => 'It is really easy to send a message!'}
24
24
 
25
25
  mg_client.send_message "sending_domain.com", data
@@ -28,9 +28,9 @@ mg_client.send_message "sending_domain.com", data
28
28
  **Send a multipart text/html message:**
29
29
 
30
30
  ```ruby
31
- data = {:from => 'bob@sending_domain.com',
32
- :to => 'sally@example.com',
33
- :subject => 'The Ruby SDK is awesome!',
31
+ data = {:from => 'bob@sending_domain.com',
32
+ :to => 'sally@example.com',
33
+ :subject => 'The Ruby SDK is awesome!',
34
34
  :text => 'This is the text part.',
35
35
  :html => '<html><body><p>This is the HTML part.</p></body></html>'}
36
36
 
@@ -68,10 +68,10 @@ mg_client.send_message "sending_domain.com", data
68
68
  ```ruby
69
69
  mb_obj = Mailgun::MessageBuilder.new
70
70
 
71
- mb_obj.set_from_address :from, "sender@example.com", {'first' => 'Sending', 'last' => 'User'}
71
+ mb_obj.set_from_address "sender@example.com", {'first' => 'Sending', 'last' => 'User'}
72
72
  mb_obj.add_recipient :to, "recipient@example.com", {'first' => 'Recipient', 'last' => 'User'}
73
- mb_obj.set_subject :subject, "This is the subject!"
74
- mb_obj.set_text_body :text, "This is the text body."
73
+ mb_obj.set_subject "This is the subject!"
74
+ mb_obj.set_text_body "This is the text body."
75
75
 
76
76
  mg_client.send_message "sending_domain.com", mb_obj
77
77
  ```
@@ -82,10 +82,10 @@ mg_client.send_message "sending_domain.com", mb_obj
82
82
  bm_obj = Mailgun::BatchMessage.new
83
83
 
84
84
  # Build message using Message Builder
85
- bm_obj.set_from_address :from, "sender@example.com", {'first' => 'Sending', 'last' => 'User'}
85
+ bm_obj.set_from_address "sender@example.com", {'first' => 'Sending', 'last' => 'User'}
86
86
  bm_obj.set_message_id("<20141014000000.11111.11111@example.com>") # optional
87
- bm_obj.set_subject :subject, "This is the subject!"
88
- bm_obj.set_text_body :text, "This is the text body."
87
+ bm_obj.set_subject "This is the subject!"
88
+ bm_obj.set_text_body "This is the text body."
89
89
 
90
90
  # Loop and add unlimited recipients (batch jobs will fire when thresholds reached)
91
91
  bm_obj.add_recipient :to, "a_user@example.com"
@@ -108,10 +108,10 @@ result = @mg_client.get "domains", {:limit => 5, :skip => 0}
108
108
  result = @mg_client.get "domains/#{domain}"
109
109
  ```
110
110
 
111
- **Add a domain:**
111
+ **Add a domain:**
112
112
 
113
113
  ```ruby
114
- result = @mg_client.post "domains", {:name => 'anothersample.mailgun.org',
114
+ result = @mg_client.post "domains", {:name => 'anothersample.mailgun.org',
115
115
  :smtp_password => 'super_secret',
116
116
  :spam_action => 'tag'}
117
117
  ```
@@ -210,7 +210,7 @@ ____________________________________________________
210
210
  **Get Statistics: **
211
211
 
212
212
  ```ruby
213
- result = @mg_client.get "#{domain}/stats", {:limit => 50,
213
+ result = @mg_client.get "#{domain}/stats", {:limit => 50,
214
214
  :skip => 10,
215
215
  :event => 'sent',
216
216
  "start-date" => 'Mon, 13 Feb 2015 00:00:00 GMT'}
@@ -300,7 +300,7 @@ result = @mg_client.delete "#{domain}/campaigns/#{campaign_id}"
300
300
  **Get Campaign Events: **
301
301
 
302
302
  ```ruby
303
- result = @mg_client.get "#{domain}/campaigns/#{campaign_id}/events", {:event => 'clicked',
303
+ result = @mg_client.get "#{domain}/campaigns/#{campaign_id}/events", {:event => 'clicked',
304
304
  :recipient => 'test@example.com',
305
305
  :country => 'US',
306
306
  :region => 'TX',
@@ -488,7 +488,7 @@ result = @mg_client.get "address/validate", {:address => 'test@example.com'}
488
488
  **Parse Addresses: **
489
489
 
490
490
  ```ruby
491
- result = @mg_client.get "address/parse", {:addresses => 'test@example.com, "First Last <first.last@example.com>',
491
+ result = @mg_client.get "address/parse", {:addresses => 'test@example.com, "First Last <first.last@example.com>',
492
492
  :syntax_only => true}
493
493
  ```
494
494
 
@@ -496,12 +496,12 @@ result = @mg_client.get "address/parse", {:addresses => 'test@example.com, "Firs
496
496
  Support and Feedback
497
497
  --------------------
498
498
 
499
- Be sure to visit the Mailgun official
500
- [documentation website](http://documentation.mailgun.com/) for additional
501
- information about our API.
499
+ Be sure to visit the Mailgun official
500
+ [documentation website](https://documentation.mailgun.com/) for additional
501
+ information about our API.
502
502
 
503
- If you find a bug, please submit the issue in Github directly.
503
+ If you find a bug, please submit the issue in Github directly.
504
504
  [Mailgun-Ruby Issues](https://github.com/mailgun/Mailgun-PHP/issues)
505
505
 
506
- As always, if you need additional assistance, drop us a note at
507
- [support@mailgun.com](mailto:support@mailgun.com).
506
+ As always, if you need additional assistance, drop us a note at
507
+ [support@mailgun.com](mailto:support@mailgun.com).
@@ -0,0 +1,40 @@
1
+ Mailgun - Webhooks
2
+ ====================
3
+
4
+ This is the Mailgun Ruby *Webhook* utilities.
5
+
6
+ The below assumes you've already installed the Mailgun Ruby SDK in to your
7
+ project. If not, go back to the master README for instructions. It currently supports
8
+ all calls except updating webhooks.
9
+
10
+ Usage - Webhooks
11
+ -----------------------
12
+
13
+ ```ruby
14
+ # First, instantiate the Mailgun Client with your API key
15
+ mg_client = Mailgun::Client.new('your-api-key')
16
+ hook = Mailgun::Webhooks.new(mg_client)
17
+
18
+ # Get a list webhooks for a domain.
19
+ hook.list 'my.perfect.domain'
20
+
21
+ # View a single webhook detail
22
+ hook.info 'my.perfect.domain', 'deliver'
23
+
24
+ # Add a single url for all webhooks
25
+ hook.create_all 'my.perfect.domain', 'https://the.webhook.url/'
26
+
27
+ # Add a url for a specific webhook
28
+ hook.create 'my.perfect.domain', 'deliver', 'https://the.webhook.url/'
29
+
30
+ # Remove a url for a specific webhook
31
+ hook.remove 'my.perfect.domain', 'deliver'
32
+
33
+ # Remove all webhooks for a domain
34
+ hook.remove 'my.perfect.domain'
35
+ ```
36
+
37
+ More Documentation
38
+ ------------------
39
+ See the official [Mailgun Domain Docs](https://documentation.mailgun.com/api-webhooks.html)
40
+ for more information
@@ -3,238 +3,36 @@ require 'rest_client'
3
3
  require 'yaml'
4
4
  require 'json'
5
5
 
6
- require "mailgun/version"
7
- require "mailgun/lists/opt_in_handler"
8
- require "mailgun/messages/batch_message"
9
- require "mailgun/events/events"
10
- require "mailgun/messages/message_builder"
11
- require "mailgun/exceptions/exceptions"
12
-
6
+ require 'mailgun/version'
7
+ require 'mailgun/client'
8
+ require 'mailgun/response'
9
+ require 'mailgun/chains'
10
+ require 'mailgun/lists/opt_in_handler'
11
+ require 'mailgun/messages/batch_message'
12
+ require 'mailgun/messages/message_builder'
13
+ require 'mailgun/events/events'
14
+ require 'mailgun/exceptions/exceptions'
15
+ require 'mailgun/domains/domains'
16
+ require 'mailgun/webhooks/webhooks'
17
+
18
+ # Module for interacting with the sweet Mailgun API.
19
+ #
20
+ # See the Github documentation for full examples.
13
21
  module Mailgun
14
22
 
15
- # A Mailgun::Client object is used to communicate with the Mailgun API. It is a
16
- # wrapper around RestClient so you don't have to worry about the HTTP aspect
17
- # of communicating with our API.
18
- #
19
- # See the Github documentation for full examples.
20
-
21
- class Client
22
-
23
- def initialize(api_key,
24
- api_host="api.mailgun.net",
25
- api_version="v2",
26
- ssl=true)
27
-
28
- endpoint = endpoint_generator(api_host, api_version, ssl)
29
- @http_client = RestClient::Resource.new(endpoint,
30
- :user => "api",
31
- :password => api_key,
32
- :user_agent => "mailgun-sdk-ruby/#{Mailgun::VERSION}")
33
- end
34
-
35
- # Simple Message Sending
36
- #
37
- # @param [String] working_domain This is the domain you wish to send from.
38
- # @param [Hash] data This should be a standard Hash
39
- # containing required parameters for the requested resource.
40
- # @return [Mailgun::Response] A Mailgun::Response object.
41
-
42
- def send_message(working_domain, data)
43
- case data
44
- when Hash
45
- if data.has_key?(:message)
46
- if data[:message].is_a?(String)
47
- data[:message] = convert_string_to_file(data[:message])
48
- end
49
- post("#{working_domain}/messages.mime", data)
50
- else
51
- post("#{working_domain}/messages", data)
52
- end
53
- when MessageBuilder
54
- post("#{working_domain}/messages", data.message)
55
- else
56
- raise ParameterError.new("Unknown data type for data parameter.", data)
57
- end
58
- end
59
-
60
- # Generic Mailgun POST Handler
61
- #
62
- # @param [String] resource_path This is the API resource you wish to interact
63
- # with. Be sure to include your domain, where necessary.
64
- # @param [Hash] data This should be a standard Hash
65
- # containing required parameters for the requested resource.
66
- # @return [Mailgun::Response] A Mailgun::Response object.
67
-
68
- def post(resource_path, data)
69
- begin
70
- response = @http_client[resource_path].post(data)
71
- Response.new(response)
72
- rescue Exception => e
73
- communication_error e
74
- end
75
- end
76
-
77
- # Generic Mailgun GET Handler
78
- #
79
- # @param [String] resource_path This is the API resource you wish to interact
80
- # with. Be sure to include your domain, where necessary.
81
- # @param [Hash] query_string This should be a standard Hash
82
- # containing required parameters for the requested resource.
83
- # @return [Mailgun::Response] A Mailgun::Response object.
23
+ class << self
24
+ attr_accessor :api_key,
25
+ :api_version,
26
+ :protocol,
27
+ :mailgun_host,
28
+ :test_mode,
29
+ :domain
84
30
 
85
- def get(resource_path, params=nil, accept="*/*")
86
- begin
87
- if params
88
- response = @http_client[resource_path].get(:params => params, :accept => accept)
89
- else
90
- response = @http_client[resource_path].get(:accept => accept)
91
- end
92
- Response.new(response)
93
- rescue Exception => e
94
- communication_error e
95
- end
31
+ def configure
32
+ yield self
33
+ true
96
34
  end
97
-
98
- # Generic Mailgun PUT Handler
99
- #
100
- # @param [String] resource_path This is the API resource you wish to interact
101
- # with. Be sure to include your domain, where necessary.
102
- # @param [Hash] data This should be a standard Hash
103
- # containing required parameters for the requested resource.
104
- # @return [Mailgun::Response] A Mailgun::Response object.
105
-
106
- def put(resource_path, data)
107
- begin
108
- response = @http_client[resource_path].put(data)
109
- Response.new(response)
110
- rescue Exception => e
111
- communication_error e
112
- end
113
- end
114
-
115
- # Generic Mailgun DELETE Handler
116
- #
117
- # @param [String] resource_path This is the API resource you wish to interact
118
- # with. Be sure to include your domain, where necessary.
119
- # @return [Mailgun::Response] A Mailgun::Response object.
120
-
121
- def delete(resource_path)
122
- begin
123
- response = @http_client[resource_path].delete()
124
- Response.new(response)
125
- rescue Exception => e
126
- communication_error e
127
- end
128
- end
129
-
130
- private
131
-
132
- # Converts MIME string to file for easy uploading to API
133
- #
134
- # @param [String] string MIME string to post to API
135
- # @return [File] File object
136
-
137
- def convert_string_to_file(string)
138
- file = Tempfile.new('MG_TMP_MIME')
139
- file.write(string)
140
- file
141
- end
142
-
143
- # Generates the endpoint URL to for the API. Allows overriding
144
- # API endpoint, API versions, and toggling SSL.
145
- #
146
- # @param [String] api_host URL endpoint the library will hit
147
- # @param [String] api_version The version of the API to hit
148
- # @param [Boolean] ssl True, SSL. False, No SSL.
149
- # @return [string] concatenated URL string
150
-
151
- def endpoint_generator(api_host, api_version, ssl)
152
- ssl ? scheme = 'https' : scheme = 'http'
153
- if api_version
154
- "#{scheme}://#{api_host}/#{api_version}"
155
- else
156
- "#{scheme}://#{api_host}"
157
- end
158
- end
159
-
160
- # Raises CommunicationError and stores response in it if present
161
- #
162
- # @param [Exception] e upstream exception object
163
-
164
- def communication_error(e)
165
- if e.respond_to? :response
166
- raise CommunicationError.new(e.message, e.response)
167
- else
168
- raise CommunicationError.new(e.message)
169
- end
170
- end
171
- end
172
-
173
- # A Mailgun::Response object is instantiated for each response generated
174
- # by the Client request. The Response object supports deserialization of
175
- # the JSON result. Or, if you prefer JSON or YAML formatting, call the
176
- # method for conversion.
177
- #
178
- # See the Github documentation for full examples.
179
-
180
- class Response
181
-
182
- attr_accessor :body
183
- attr_accessor :code
184
-
185
- def initialize(response)
186
- @body = response.body
187
- @code = response.code
188
- end
189
-
190
- # Return response as Ruby Hash
191
- #
192
- # @return [Hash] A standard Ruby Hash containing the HTTP result.
193
-
194
- def to_h
195
- begin
196
- JSON.parse(@body)
197
- rescue Exception => e
198
- raise ParseError.new(e), e
199
- end
200
- end
201
-
202
- # Replace @body with Ruby Hash
203
- #
204
- # @return [Hash] A standard Ruby Hash containing the HTTP result.
205
-
206
- def to_h!
207
- begin
208
- @body = JSON.parse(@body)
209
- rescue Exception => e
210
- raise ParseError.new(e), e
211
- end
212
- end
213
-
214
- # Return response as Yaml
215
- #
216
- # @return [String] A string containing response as YAML
217
-
218
- def to_yaml
219
- begin
220
- YAML::dump(JSON.parse(@body))
221
- rescue Exception => e
222
- raise ParseError.new(e), e
223
- end
224
- end
225
-
226
- # Replace @body with YAML
227
- #
228
- # @return [String] A string containing response as YAML
229
-
230
- def to_yaml!
231
- begin
232
- @body = YAML::dump(JSON.parse(@body))
233
- rescue Exception => e
234
- raise ParseError.new(e), e
235
- end
236
- end
237
-
35
+ alias_method :config, :configure
238
36
  end
239
37
 
240
38
  end