mailgun-ruby 1.3.6 → 1.3.7

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d95de7e9d0beb5c9abeafdef8f05c7413566102807dedc3d8aa47236eeecf100
4
- data.tar.gz: f1678c985501ecc657c2163f55f1a8073bca3990a84894ed4b914886d9a0f5d2
3
+ metadata.gz: 0041dce1e0fc1dc9f5166d4095a8d39dadf26be5b5b7892f1b8005b60a471a1f
4
+ data.tar.gz: 4356cf2e9093a066e28ff7fab036af94294eb4515137d0f802f001093b2d477f
5
5
  SHA512:
6
- metadata.gz: 46af44b97dd11918113681f366489b8640de80efa05e08dea0102f4e97635634d241739be47d63107342400af8712b079d8360326697e81a78ca94cb6526e42f
7
- data.tar.gz: 9b72d7230d1c14f9f9515f9e740e7c002436675e14dda9302234ad263ff586cd3a7d1cd9759913a14e1a180f692b505a197308fa78299446906c57a9c007da55
6
+ metadata.gz: 3420a656e1d4ef615a665743190b593a46a5ea13f778bf65a2b1d32746a30fb2ed08adde9d6651aeaacfa7fc8e815cc0cf51a510fd7c2b83e8a20c8b3cb34391
7
+ data.tar.gz: 864f0bfc57d6e06112eb410870bd88d6a7aa81a1b8f71bbb88206a6b768fcc1346635d76c2ffa059469911baed7e911e4f96e3cb6793192794511719e31dba99
data/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [1.3.6] - 2025-05-30
6
+
7
+ ### Fixed
8
+
9
+ - Fix Suppressions paging not working (https://github.com/mailgun/mailgun-ruby/pull/355)
10
+ - CI improvements
11
+
5
12
  ## [1.3.5] - 2025-04-07
6
13
 
7
14
  ### Fixed
data/README.md CHANGED
@@ -19,7 +19,7 @@ gem install mailgun-ruby
19
19
  Gemfile:
20
20
 
21
21
  ```ruby
22
- gem 'mailgun-ruby', '~>1.3.6'
22
+ gem 'mailgun-ruby', '~>1.3.7'
23
23
  ```
24
24
 
25
25
  Usage
@@ -87,9 +87,9 @@ and replace `api-myapikey` and `mydomain.com` with your secret API key and domai
87
87
 
88
88
  To specify Mailgun options such as campaign or tags:
89
89
  ```ruby
90
- class UserMailer < ApplicationMailer
91
- def welcome_email
92
- mail(to: params[:to], subject: "Welcome!").tap do |message|
90
+ class UserNotifier < ApplicationMailer
91
+ def welcome_email(current_user)
92
+ mail(to: current_user.email, subject: "Welcome!").tap do |message|
93
93
  message.mailgun_options = {
94
94
  "tag" => ["abtest-option-a", "beta-user"],
95
95
  "tracking-opens" => true,
@@ -193,6 +193,7 @@ This SDK includes the following components:
193
193
  - [Templates](docs/Templates.md)
194
194
  - [EmailValidation](docs/EmailValidation.md)
195
195
  - [Metrics](docs/Metrics.md)
196
+ - [Logs](docs/Logs.md)
196
197
 
197
198
  Message Builder allows you to quickly create the array of parameters, required
198
199
  to send a message, by calling a methods for each parameter.
data/docs/Events.md CHANGED
@@ -1,6 +1,8 @@
1
1
  Mailgun - Events
2
2
  ====================
3
3
 
4
+ _WARNING: This API is deprecated in favor of our Logs API._
5
+
4
6
  This is the Mailgun Ruby *Events* utility.
5
7
 
6
8
  The below assumes you've already installed the Mailgun Ruby SDK in your project.
data/docs/Logs.md ADDED
@@ -0,0 +1,67 @@
1
+ Mailgun - Logs
2
+ ====================
3
+
4
+ This is the Mailgun Ruby *Logs* 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 credentials.
9
+
10
+ ---
11
+
12
+ Mailgun collects many different events and generates event logs which are available
13
+ in your Control Panel. This data is also available via our analytics logs API endpoint.
14
+
15
+ You can view additional samples in the [logs_spec.rb](/spec/integration/logs_spec.rb)
16
+ or the Logs client API in [logs.rb](/lib/logs/logs.rb).
17
+
18
+ Usage
19
+ -----
20
+
21
+ To get an instance of the Logs client:
22
+
23
+ ```ruby
24
+ require 'mailgun'
25
+
26
+ mg_client = Mailgun::Client.new('your-api-key', 'mailgun-api-host', 'v1')
27
+ logs = Mailgun::Logs.new(mg_client)
28
+ ````
29
+ ---
30
+ Get filtered logs for an account:
31
+ ```ruby
32
+ options = {
33
+ {
34
+ start: 'Mon, 08 Jul 2024 00:00:00 -0000',
35
+ end: 'Fri, 12 Jul 2024 00:00:00 -0000',
36
+ filter: {
37
+ AND: [
38
+ {
39
+ attribute: 'domain',
40
+ comparator: '=',
41
+ values: [
42
+ {
43
+ label: 'example.com',
44
+ value: 'example.com'
45
+ }
46
+ ]
47
+ }
48
+ ]
49
+ },
50
+ include_subaccounts: true,
51
+ pagination: {
52
+ sort: 'timestamp:asc',
53
+ token: 'cjsijbijewbu78t678tVTYUYU76754fyuiksin865g',
54
+ limit: 50
55
+ }
56
+ }
57
+ }
58
+
59
+ logs.account_logs(options)
60
+ ```
61
+
62
+ ---
63
+
64
+ More Documentation
65
+ ------------------
66
+ See the official [Mailgun Domain Docs](https://documentation.mailgun.com/docs/mailgun/api-reference/openapi-final/tag/Logs/)
67
+ for more information
@@ -4,8 +4,8 @@ module Mailgun
4
4
 
5
5
  # Mailgun::Address is a simple interface to the Email Validation API.
6
6
  class Address
7
- def initialize
8
- @client = Mailgun::Client.new(Mailgun.api_key, Mailgun.api_host || 'api.mailgun.net', 'v4')
7
+ def initialize(api_key = Mailgun.api_key, api_host = Mailgun.api_host)
8
+ @client = Mailgun::Client.new(api_key, api_host || 'api.mailgun.net', 'v4')
9
9
  end
10
10
 
11
11
  # Given an arbitrary address, validates it based on defined checks.
@@ -4,7 +4,7 @@ require 'mailgun/exceptions/exceptions'
4
4
 
5
5
  module Mailgun
6
6
  # A Mailgun::Client object is used to communicate with the Mailgun API. It is a
7
- # wrapper around RestClient so you don't have to worry about the HTTP aspect
7
+ # wrapper around Faraday so you don't have to worry about the HTTP aspect
8
8
  # of communicating with our API.
9
9
  #
10
10
  # See the Github documentation for full examples.
@@ -23,7 +23,7 @@ module Mailgun
23
23
 
24
24
  request_options = {
25
25
  url: endpoint,
26
- proxy: Mailgun.proxy_url,
26
+ proxy: proxy_url,
27
27
  ssl: {verify: ssl},
28
28
  headers: {
29
29
  'User-Agent' => "mailgun-sdk-ruby/#{Mailgun::VERSION}",
@@ -76,6 +76,7 @@ module Mailgun
76
76
  #
77
77
  # Returns a Mailgun.Response object.
78
78
  def get_events(params = {}, paging = nil)
79
+ warn('WARN: This API is deprecated in favor of our Logs API')
79
80
  response = @client.get(construct_url(paging), params)
80
81
  extract_paging(response)
81
82
  response
@@ -1,5 +1,4 @@
1
1
  require 'uri'
2
- require 'base64'
3
2
  require 'openssl'
4
3
 
5
4
  module Mailgun
@@ -20,14 +19,14 @@ module Mailgun
20
19
  def self.generate_hash(mailing_list, secret_app_id, recipient_address)
21
20
  inner_payload = { 'l' => mailing_list, 'r' => recipient_address }
22
21
 
23
- inner_payload_encoded = Base64.encode64(JSON.generate(inner_payload))
22
+ inner_payload_encoded = base64_encode(JSON.generate(inner_payload))
24
23
 
25
24
  sha1_digest = OpenSSL::Digest.new('sha1')
26
25
  digest = OpenSSL::HMAC.hexdigest(sha1_digest, secret_app_id, inner_payload_encoded)
27
26
 
28
27
  outer_payload = { 'h' => digest, 'p' => inner_payload_encoded }
29
28
 
30
- outer_payload_encoded = Base64.encode64(JSON.generate(outer_payload))
29
+ outer_payload_encoded = base64_encode(JSON.generate(outer_payload))
31
30
 
32
31
  CGI.escape(outer_payload_encoded)
33
32
  end
@@ -38,12 +37,12 @@ module Mailgun
38
37
  # @param [Hash] unique_hash The hash from the user. Likely via link click.
39
38
  # @return [Hash or Boolean] A hash with 'recipient_address' and 'mailing_list', if validates. Otherwise, boolean false.
40
39
  def self.validate_hash(secret_app_id, unique_hash)
41
- outer_payload = JSON.parse(Base64.decode64(CGI.unescape(unique_hash)))
40
+ outer_payload = JSON.parse(base64_decode(CGI.unescape(unique_hash)))
42
41
 
43
42
  sha1_digest = OpenSSL::Digest.new('sha1')
44
43
  generated_hash = OpenSSL::HMAC.hexdigest(sha1_digest, secret_app_id, outer_payload['p'])
45
44
 
46
- inner_payload = JSON.parse(Base64.decode64(CGI.unescape(outer_payload['p'])))
45
+ inner_payload = JSON.parse(base64_decode(CGI.unescape(outer_payload['p'])))
47
46
 
48
47
  hash_provided = outer_payload['h']
49
48
 
@@ -53,6 +52,22 @@ module Mailgun
53
52
  false
54
53
  end
55
54
 
55
+ # Equivalent to Base64.encode64
56
+ def self.base64_encode(input)
57
+ [input].pack('m')
58
+ end
59
+
60
+ # Equivalent to Base64.decode64
61
+ def self.base64_decode(input)
62
+ # TODO: Condition can be droped if Ruby >= 2.4.0
63
+ if input.respond_to?(:unpack1)
64
+ input.unpack1('m')
65
+ else
66
+ input.unpack('m').first
67
+ end
68
+ end
69
+
70
+ private_class_method :base64_encode, :base64_decode
56
71
  end
57
72
 
58
73
  end
@@ -0,0 +1,39 @@
1
+ require 'mailgun/exceptions/exceptions'
2
+
3
+ module Mailgun
4
+ # A Mailgun::Logs object is a simple interface to Mailgun Logs.
5
+ # Uses Mailgun
6
+ class Logs
7
+ # Public: creates a new Mailgun::Logs instance.
8
+ # Defaults to Mailgun::Client
9
+ def initialize(client = Mailgun::Client.new(Mailgun.api_key, Mailgun.api_host || 'api.mailgun.net', 'v1'))
10
+ @client = client
11
+ end
12
+
13
+ # Public: Post query to get account logs
14
+ #
15
+ # options - [Hash] of
16
+ # start - [String] The start date (default: 1 day before current time). Must be in RFC 2822 format.
17
+ # end - [String] The end date (default: current time). Must be in RFC 2822 format.
18
+ # events - [Array] The set of events to include.
19
+ # metric_events - [Array] Optional set of analytics metric events. Will be converted into corresponding events.
20
+ # filter - [Object]
21
+ # AND: - [Array] of objects
22
+ # attribute - [String]
23
+ # comparator - [String]
24
+ # values - [Array] of objects
25
+ # label - [String]
26
+ # value - [String]
27
+ # include_subaccounts - [Boolean] Include logs from all subaccounts.
28
+ # include_totals - [Boolean] Include total number of log entries.
29
+ # pagination - [Object]
30
+ # sort - [String] Colon-separated value indicating column name and sort direction e.g. 'timestamp:desc'.
31
+ # token - [String] A token to the requested page.
32
+ # limit - [Integer] The maximum number of items returned (100 max).
33
+ #
34
+ # Returns [Hash] Logs
35
+ def account_logs(options={})
36
+ @client.post('analytics/logs', options.to_json, { "Content-Type" => "application/json" }).to_h!
37
+ end
38
+ end
39
+ end
@@ -1,4 +1,4 @@
1
1
  # It's the version. Yeay!
2
2
  module Mailgun
3
- VERSION = '1.3.6'
3
+ VERSION = '1.3.7'
4
4
  end
data/lib/mailgun.rb CHANGED
@@ -19,6 +19,7 @@ require 'mailgun/templates/templates'
19
19
  require 'mailgun/subaccounts/subaccounts'
20
20
  require 'mailgun/tags/tags'
21
21
  require 'mailgun/metrics/metrics'
22
+ require 'mailgun/logs/logs'
22
23
 
23
24
  # Module for interacting with the sweet Mailgun API.
24
25
  #
@@ -0,0 +1,103 @@
1
+ require 'spec_helper'
2
+ require 'mailgun'
3
+
4
+ vcr_opts = { cassette_name: 'logs' }
5
+
6
+ describe Mailgun::Logs, vcr: vcr_opts do
7
+ let(:logs) { Mailgun::Logs.new(Mailgun::Client.new(APIKEY, APIHOST, 'v1')) }
8
+
9
+ describe '#account_logs' do
10
+ let(:options) do
11
+ {
12
+ start: 'Wed, 25 Jun 2025 00:00:00 -0000',
13
+ end: 'Wed, 25 Jun 2025 23:00:00 -0000',
14
+ filter: {
15
+ AND: [
16
+ {
17
+ attribute: 'domain',
18
+ comparator: '!=',
19
+ values: [
20
+ {
21
+ label: 'example.com',
22
+ value: 'example.com'
23
+ }
24
+ ]
25
+ }
26
+ ]
27
+ },
28
+ include_subaccounts: true,
29
+ pagination: {
30
+ sort: 'timestamp:asc',
31
+ token: '123',
32
+ limit: 50
33
+ }
34
+ }
35
+ end
36
+
37
+ it 'responds with account logs' do
38
+ expect(logs.account_logs(options)).to eq(
39
+ {
40
+ "start" => "Wed, 25 Jun 2025 00:00:00 -0000",
41
+ "end" => "Wed, 25 Jun 2025 23:00:00 -0000",
42
+ "items" => [
43
+ {
44
+ "id" => "123",
45
+ "event" => "accepted",
46
+ "@timestamp" => "2025-06-25T17:19:51.166Z",
47
+ "account" => {
48
+ "id" => "123"
49
+ },
50
+ "method" => "HTTP",
51
+ "originating-ip" => "123.123.12.123",
52
+ "api-key-id" => "xxx",
53
+ "domain" => {
54
+ "name" => "example.mailgun.org"
55
+ },
56
+ "recipient" => "alex@example.com",
57
+ "recipient-domain" => "example.com",
58
+ "envelope" => {
59
+ "sender" => "example.mailgun.org",
60
+ "transport" => "smtp",
61
+ "targets" => "alex@example.com"
62
+ },
63
+ "storage" => {
64
+ "region" => "us-east4",
65
+ "env" => "production",
66
+ "key" => "xxx",
67
+ "url" => ["https://storage.api.mailgun.net/v3/domains/example.mailgun.org/messages/123"]
68
+ },
69
+ "log-level" => "info",
70
+ "user-variables" => "{}",
71
+ "message" => {
72
+ "headers" => {
73
+ "to" => "alex@example.com",
74
+ "message-id" => "123@example.mailgun.org",
75
+ "from" => "bob@sending_domain.com+4",
76
+ "subject" => "The Ruby SDK is awesome!"
77
+ },
78
+ "attachments" => [
79
+ {
80
+ "filename" => "image.jpg",
81
+ "content-type" => "image/jpeg",
82
+ "size" => 16712
83
+ }
84
+ ],
85
+ "size" => 23476
86
+ },
87
+ "flags" => {
88
+ "is-authenticated" => true,
89
+ "is-system-test" => false,
90
+ "is-routed" => false,
91
+ "is-test-mode" => false,
92
+ "is-delayed-bounce" => false,
93
+ "is-callback" => false
94
+ }
95
+ }
96
+ ],
97
+ "pagination" => {},
98
+ "aggregates" => {}
99
+ }
100
+ )
101
+ end
102
+ end
103
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  require 'rubygems'
2
- require 'base64'
3
2
  require 'bundler'
4
3
  require 'bundler/setup'
5
4
  Bundler.setup(:development)
@@ -0,0 +1,53 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://api.mailgun.net/v1/analytics/logs
6
+ body:
7
+ encoding: UTF-8
8
+ string: '{"start":"Wed, 25 Jun 2025 00:00:00 -0000","end":"Wed, 25 Jun 2025
9
+ 23:00:00 -0000","filter":{"AND":[{"attribute":"domain","comparator":"!=","values":[{"label":"example.com","value":"example.com"}]}]},"include_subaccounts":true,"pagination":{"sort":"timestamp:asc","limit":50}}'
10
+ headers:
11
+ User-Agent:
12
+ - mailgun-sdk-ruby/1.3.7
13
+ Accept:
14
+ - "*/*"
15
+ Content-Type:
16
+ - application/json
17
+ Authorization:
18
+ - Basic xxx
19
+ Accept-Encoding:
20
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
21
+ response:
22
+ status:
23
+ code: 200
24
+ message: OK
25
+ headers:
26
+ Access-Control-Allow-Credentials:
27
+ - 'true'
28
+ Access-Control-Allow-Origin:
29
+ - "*"
30
+ Cache-Control:
31
+ - no-store
32
+ Content-Type:
33
+ - application/json; charset=utf-8
34
+ Date:
35
+ - Wed, 25 Jun 2025 17:47:38 GMT
36
+ Strict-Transport-Security:
37
+ - max-age=63072000; includeSubDomains
38
+ X-Mailgun-Key-Id:
39
+ - XXX
40
+ X-Xss-Protection:
41
+ - 1; mode=block
42
+ Transfer-Encoding:
43
+ - chunked
44
+ body:
45
+ encoding: UTF-8
46
+ string: '{"start":"Wed, 25 Jun 2025 00:00:00 -0000","end":"Wed, 25 Jun 2025
47
+ 23:00:00 -0000","items":[{"id":"123","event":"accepted","@timestamp":"2025-06-25T17:19:51.166Z","account":{"id":"123"},"method":"HTTP","originating-ip":"123.123.12.123","api-key-id":"xxx","domain":{"name":"example.mailgun.org"},"recipient":"alex@example.com","recipient-domain":"example.com","envelope":{"sender":"example.mailgun.org","transport":"smtp","targets":"alex@example.com"},"storage":{"region":"us-east4","env":"production","key":"xxx","url":["https://storage.api.mailgun.net/v3/domains/example.mailgun.org/messages/123"]},"log-level":"info","user-variables":"{}","message":{"headers":{"to":"alex@example.com","message-id":"123@example.mailgun.org","from":"bob@sending_domain.com+4","subject":"The
48
+ Ruby SDK is awesome!"},"attachments":[{"filename":"image.jpg","content-type":"image/jpeg","size":16712}],"size":23476},"flags":{"is-authenticated":true,"is-system-test":false,"is-routed":false,"is-test-mode":false,"is-delayed-bounce":false,"is-callback":false}}],"pagination":{},"aggregates":{}}
49
+
50
+ '
51
+ http_version:
52
+ recorded_at: Wed, 25 Jun 2025 17:47:38 GMT
53
+ recorded_with: VCR 3.0.3
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mailgun-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.6
4
+ version: 1.3.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mailgun
8
8
  - Travis Swientek
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-05-29 00:00:00.000000000 Z
11
+ date: 2025-06-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -197,6 +197,7 @@ files:
197
197
  - docs/Domains.md
198
198
  - docs/EmailValidation.md
199
199
  - docs/Events.md
200
+ - docs/Logs.md
200
201
  - docs/MessageBuilder.md
201
202
  - docs/Metrics.md
202
203
  - docs/OptInHandler.md
@@ -217,6 +218,7 @@ files:
217
218
  - lib/mailgun/events/events.rb
218
219
  - lib/mailgun/exceptions/exceptions.rb
219
220
  - lib/mailgun/lists/opt_in_handler.rb
221
+ - lib/mailgun/logs/logs.rb
220
222
  - lib/mailgun/messages/batch_message.rb
221
223
  - lib/mailgun/messages/message_builder.rb
222
224
  - lib/mailgun/metrics/metrics.rb
@@ -242,6 +244,7 @@ files:
242
244
  - spec/integration/events_spec.rb
243
245
  - spec/integration/list_members_spec.rb
244
246
  - spec/integration/list_spec.rb
247
+ - spec/integration/logs_spec.rb
245
248
  - spec/integration/mailer_spec.rb
246
249
  - spec/integration/mailgun_spec.rb
247
250
  - spec/integration/messages/sample_data/mime.txt
@@ -279,6 +282,7 @@ files:
279
282
  - vcr_cassettes/exceptions-not-allowed.yml
280
283
  - vcr_cassettes/exceptions.yml
281
284
  - vcr_cassettes/list_members.yml
285
+ - vcr_cassettes/logs.yml
282
286
  - vcr_cassettes/mailer_invalid_domain.yml
283
287
  - vcr_cassettes/mailing_list.todo.yml
284
288
  - vcr_cassettes/mailing_list.yml
@@ -325,6 +329,7 @@ test_files:
325
329
  - spec/integration/events_spec.rb
326
330
  - spec/integration/list_members_spec.rb
327
331
  - spec/integration/list_spec.rb
332
+ - spec/integration/logs_spec.rb
328
333
  - spec/integration/mailer_spec.rb
329
334
  - spec/integration/mailgun_spec.rb
330
335
  - spec/integration/messages/sample_data/mime.txt