mailgun-tracking 2.0.0 → 3.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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/mailgun/tracking/templates/mailgun_tracking.rb.erb +1 -1
  3. data/lib/mailgun-tracking.rb +3 -0
  4. data/lib/mailgun/tracking.rb +65 -33
  5. data/lib/mailgun/tracking/auth.rb +52 -0
  6. data/lib/mailgun/tracking/configuration.rb +5 -9
  7. data/lib/mailgun/tracking/fanout.rb +18 -0
  8. data/lib/mailgun/tracking/middleware.rb +10 -47
  9. data/lib/mailgun/tracking/railtie.rb +2 -2
  10. data/lib/mailgun/tracking/version.rb +8 -7
  11. data/spec/dummy/logs/test.log +77 -0
  12. data/spec/dummy/rails/logs/test.log +19 -11
  13. data/spec/mailgun/tracking/auth_spec.rb +31 -0
  14. data/spec/mailgun/tracking/middleware_spec.rb +43 -51
  15. data/spec/mailgun/tracking_spec.rb +11 -4
  16. data/spec/support/shared_examples/integration/acts_as_rack.rb +6 -4
  17. metadata +18 -53
  18. data/lib/mailgun/tracking/exceptions.rb +0 -11
  19. data/lib/mailgun/tracking/listener.rb +0 -55
  20. data/lib/mailgun/tracking/notifier.rb +0 -61
  21. data/lib/mailgun/tracking/payload.rb +0 -96
  22. data/lib/mailgun/tracking/request.rb +0 -47
  23. data/lib/mailgun/tracking/signature.rb +0 -48
  24. data/lib/mailgun/tracking/subscriber.rb +0 -26
  25. data/lib/mailgun/tracking/subscriber/all_messages.rb +0 -37
  26. data/lib/mailgun/tracking/subscriber/evented.rb +0 -40
  27. data/lib/mailgun/tracking/util.rb +0 -67
  28. data/spec/mailgun/tracking/listener_spec.rb +0 -48
  29. data/spec/mailgun/tracking/notifier_spec.rb +0 -66
  30. data/spec/mailgun/tracking/payload_spec.rb +0 -73
  31. data/spec/mailgun/tracking/request_spec.rb +0 -63
  32. data/spec/mailgun/tracking/signature_spec.rb +0 -65
  33. data/spec/mailgun/tracking/subscriber/all_messages_spec.rb +0 -13
  34. data/spec/mailgun/tracking/subscriber/evented_spec.rb +0 -14
  35. data/spec/mailgun/tracking/subscriber_spec.rb +0 -15
  36. data/spec/mailgun/tracking/util_spec.rb +0 -155
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cffbc8bee4968f3230841a2a75da150ef6d17bb2e4d860d05897aef61e55f2e1
4
- data.tar.gz: be71a2d5a143a49d4ada8d050ffd402e09917e31cacc83da954654adfeae358d
3
+ metadata.gz: 6b812299fdcd198f08dd868a8b7c19f862637d68cad9be5af788867b98f53522
4
+ data.tar.gz: 705758e31e1ce4e8527edba0c2d172627298aacf0d156363f5ccb6ed02466556
5
5
  SHA512:
6
- metadata.gz: 4451ebb90204a5a887ad09afaac2187b0e86591e880a1bf944a7c671056c93999a8d6ec89920c38928a230e0b86a161eb472f0d57e320085865f12f33dcde843
7
- data.tar.gz: efda62e3aa07d4fbe150dbfb48d2f2cbaa6204b49de9f0bb7278e473723ed85515dc56cfe84b503bf9c94b18a70cdfec5e94642ed5b927942381852babceb37e
6
+ metadata.gz: 84e5e69c832f3c3f19f775c47d35d675d2a150e5564e41899bc8a7e79858e25c70fabd27e4c20e49543c65a4c423e0cd2406ca70fafefd898b6bcbb5c29bf08e
7
+ data.tar.gz: a341aec22ff80fa7c0edb22706aa4f72631155e4fe8606cd0493043aed9c72f5830655c82373d5976064e159f91b96ac5cd6de1c5399b0f3ef6813b391481b2e
@@ -6,7 +6,7 @@ Mailgun::Tracking.configure do |config|
6
6
  config.api_key = ENV['MAILGUN_API_KEY']
7
7
  <% end -%>
8
8
 
9
- # Mailgun Webhook API endpoint. Default is '/mailgun'.
9
+ # Mailgun callback URL. Default is '/mailgun-tracking'.
10
10
  <% if endpoint -%>
11
11
  config.endpoint = <%= endpoint %>
12
12
  <% else -%>
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'mailgun/tracking'
@@ -1,66 +1,98 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'tracking/configuration'
4
- require_relative 'tracking/exceptions'
5
- require_relative 'tracking/listener'
6
- require_relative 'tracking/middleware'
7
- require_relative 'tracking/notifier'
8
- require_relative 'tracking/payload'
9
- require_relative 'tracking/signature'
10
- require_relative 'tracking/subscriber'
11
- require_relative 'tracking/util'
12
- require_relative 'tracking/version'
13
- require_relative 'tracking/railtie' if defined?(Rails)
14
- require_relative 'tracking/request'
3
+ require 'mailgun/tracking/configuration'
4
+ require 'mailgun/tracking/middleware'
5
+ require 'mailgun/tracking/version'
6
+ require 'mailgun/tracking/railtie' if defined?(::Rails)
7
+ require 'mailgun/tracking/fanout'
15
8
 
16
- # Module for interacting with the Mailgun.
17
9
  module Mailgun
18
- # Namespace for classes and modules that handle Mailgun Webhooks.
10
+ # The namespace for classes and modules that handle Mailgun webhooks.
19
11
  module Tracking
20
12
  module_function
21
13
 
22
- # Default way to setup Mailgun Tracking.
14
+ # The default way to set up Mailgun Tracking.
15
+ #
16
+ # @yield [self] block yields itself.
23
17
  #
24
18
  # @example
25
19
  # Mailgun::Tracking.configure do |config|
26
20
  # config.api_key = ENV['MAILGUN_API_KEY']
21
+ #
27
22
  # config.endpoint = '/mailgun-tracking'
28
23
  #
29
- # config.notifier.subscribe :delivered do |payload|
24
+ # config.on 'delivered' do |payload|
30
25
  # # Do something with the incoming data.
31
26
  # end
32
27
  #
33
- # config.notifier.subscribe :bounced, Bounced.new
28
+ # # The object should respond to #call
29
+ # config.on 'bounced', Bounced.new
34
30
  #
35
- # config.notifier.all do |payload|
36
- # # Handle all event types.
31
+ # config.all do |payload|
32
+ # # Do something with the incoming data.
37
33
  # end
38
34
  # end
39
- #
40
- # @return [void]
41
35
  def configure
42
36
  yield(self)
43
37
  end
44
38
 
45
- # A Notifier instance.
39
+ # Subscribe to an event.
46
40
  #
47
- # @return [Mailgun::Tracking::Notifier]
48
- def notifier
49
- @notifier ||= Notifier.new
41
+ # @param event [Symbol, String] the event identifier.
42
+ # @param callable [#call] the event handler.
43
+ #
44
+ # @example
45
+ # Mailgun::Tracking.configure do |config|
46
+ # config.on 'delivered' do |payload|
47
+ # # Do something with the incoming data.
48
+ # end
49
+ #
50
+ # # The object should respond to #call
51
+ # config.on 'bounced', Bounced.new
52
+ # end
53
+ def on(event, callable = nil, &block)
54
+ ::Mailgun::Tracking::Fanout.on(
55
+ event.to_s.dup.freeze,
56
+ callable || block
57
+ )
50
58
  end
51
59
 
52
- # Delegate other missing methods to configuration.
60
+ # Subscribe to all events.
61
+ #
62
+ # @param callable [#call] the event handler.
63
+ #
64
+ # @example
65
+ # Mailgun::Tracking.configure do |config|
66
+ # config.all do |payload|
67
+ # # Do something with the incoming data.
68
+ # end
69
+ #
70
+ # # The object should respond to #call
71
+ # config.all, All.new
72
+ # end
73
+ def all(callable = nil, &block)
74
+ ::Mailgun::Tracking::Fanout.all(
75
+ callable || block
76
+ )
77
+ end
78
+
79
+ # Delegate any missing method call to the configuration.
53
80
  def method_missing(method_name, *arguments, &block)
54
- if Configuration.instance.respond_to?(method_name)
55
- Configuration.instance.public_send(method_name, *arguments, &block)
56
- else
57
- super
58
- end
81
+ return super unless configuration.respond_to?(method_name)
82
+
83
+ configuration.public_send(method_name, *arguments, &block)
59
84
  end
60
85
 
61
- # Replaces the Object.respond_to?() method.
86
+ # Replace the Object.respond_to?() method.
62
87
  def respond_to_missing?(method_name, include_private = false)
63
- Configuration.instance.respond_to?(method_name) || super
88
+ configuration.respond_to?(method_name) || super
64
89
  end
90
+
91
+ # @return [Mailgun::Tracking::Configuration]
92
+ def configuration
93
+ ::Mailgun::Tracking::Configuration.instance
94
+ end
95
+
96
+ private_class_method :configuration
65
97
  end
66
98
  end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'openssl'
4
+
5
+ module Mailgun
6
+ module Tracking
7
+ # Used to ensure the authenticity of event requests.
8
+ class Auth
9
+ SIGNATURE = 'signature'
10
+
11
+ # @param payload [Hash] webhook payload.
12
+ #
13
+ # @return [Boolean]
14
+ def self.call(payload, _env = nil)
15
+ new(payload).valid?
16
+ end
17
+
18
+ # Initialize a Mailgun::Tracking::Auth object.
19
+ #
20
+ # @param payload [Hash] webhook payload.
21
+ #
22
+ # @return [Mailgun::Tracking::Auth]
23
+ def initialize(payload)
24
+ @payload = payload
25
+ end
26
+
27
+ # Compare the resulting hexdigest to the signature.
28
+ #
29
+ # @return [Boolean]
30
+ def valid?
31
+ @payload.dig(SIGNATURE, SIGNATURE) == \
32
+ ::OpenSSL::HMAC.hexdigest(
33
+ ::OpenSSL::Digest::SHA256.new,
34
+ ::Mailgun::Tracking.api_key,
35
+ data
36
+ )
37
+ end
38
+
39
+ private
40
+
41
+ # Concatenate timestamp and token values.
42
+ #
43
+ # @return [String]
44
+ def data
45
+ [
46
+ @payload.dig(SIGNATURE, 'timestamp'),
47
+ @payload.dig(SIGNATURE, 'token')
48
+ ].join
49
+ end
50
+ end
51
+ end
52
+ end
@@ -4,23 +4,19 @@ require 'singleton'
4
4
 
5
5
  module Mailgun
6
6
  module Tracking
7
- # Stores configuration information.
7
+ # Configuration for Mailgun Tracking.
8
8
  class Configuration
9
- include Singleton
9
+ include ::Singleton
10
10
 
11
11
  DEFAULT_ENDPOINT = '/mailgun'
12
12
 
13
- # Mailgun API public key.
14
- #
15
- # @return [String]
13
+ # @return [String] Mailgun API public key.
16
14
  attr_accessor :api_key
17
15
 
18
- # Mailgun Webhook API endpoint.
19
- #
20
- # @return [String]
16
+ # @return [String] Mailgun callback URL.
21
17
  attr_accessor :endpoint
22
18
 
23
- # Initializes a new Configuration object.
19
+ # Initialize a Mailgun::Tracking::Configuration object.
24
20
  def initialize
25
21
  @endpoint = DEFAULT_ENDPOINT
26
22
  end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'catch_box/fanout'
4
+ require 'mailgun/tracking/auth'
5
+
6
+ module Mailgun
7
+ module Tracking
8
+ # It broadcast the payload to all callable based on event type. Also, there is an authenticity
9
+ # of the webhook before each broadcast.
10
+ class Fanout
11
+ extend ::CatchBox::Fanout
12
+
13
+ event 'event-data.event'
14
+
15
+ auth ::Mailgun::Tracking::Auth
16
+ end
17
+ end
18
+ end
@@ -1,55 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'catch_box/middleware'
4
+
3
5
  module Mailgun
4
6
  module Tracking
5
- # Rack-based middleware to handle event notifications.
6
- class Middleware
7
- # Initializes a new Middleware object.
8
- #
9
- # @param app the next Rack middleware in the stack.
7
+ # Rack middleware to handle an HTTP POST to the callback URL when events occur with a message.
8
+ class Middleware < ::CatchBox::Middleware
9
+ # Initialize a Mailgun::Tracking::Middleware object.
10
10
  def initialize(app)
11
- @app = app
12
- end
13
-
14
- # Thread-safe {call!}.
15
- #
16
- # @param env [Hash] Environment hash.
17
- #
18
- # @return [Array(Numeric,Hash,Array)] The Rack-style response.
19
- def call(env)
20
- dup.call!(env)
21
- end
22
-
23
- # Responds to Rack requests.
24
- #
25
- # @param env [Hash] Environment hash.
26
- #
27
- # @return [Array(Numeric,Hash,Array)] The Rack-style response.
28
- def call!(env)
29
- @request = Request.new(env)
30
-
31
- return @app.call(env) unless @request.mailgun_tracking?
32
-
33
- handle_event
34
- end
35
-
36
- private
37
-
38
- # @return [Array(Numeric,Hash,Array)] The Rack-style response.
39
- def null_response
40
- [200, {}, []]
41
- end
42
-
43
- # @return [Array(Numeric,Hash,Array)] The Rack-style response.
44
- def bad_request
45
- [400, {}, []]
46
- end
47
-
48
- def handle_event
49
- Mailgun::Tracking.notifier.broadcast(@request.payload.event_data.event, @request.payload)
50
- null_response
51
- rescue InvalidSignature
52
- bad_request
11
+ super(
12
+ app,
13
+ fanout: ::Mailgun::Tracking::Fanout,
14
+ endpoint: ::Mailgun::Tracking.endpoint
15
+ )
53
16
  end
54
17
  end
55
18
  end
@@ -3,9 +3,9 @@
3
3
  module Mailgun
4
4
  module Tracking
5
5
  # Mailgun Tracking Railtie.
6
- class Railtie < Rails::Railtie
6
+ class Railtie < ::Rails::Railtie
7
7
  initializer 'mailgun-tracking.insert_middleware' do |app|
8
- app.config.middleware.use(Mailgun::Tracking::Middleware)
8
+ app.config.middleware.use(::Mailgun::Tracking::Middleware)
9
9
  end
10
10
  end
11
11
  end
@@ -2,17 +2,18 @@
2
2
 
3
3
  module Mailgun
4
4
  module Tracking
5
- # This module holds the Mailgun Tracking version information.
5
+ # The module which hold version data.
6
6
  module Version
7
7
  module_function
8
8
 
9
9
  KEYS = %i[major minor patch].freeze
10
+ DOT = '.'
10
11
 
11
12
  # Major version.
12
13
  #
13
14
  # @return [Integer]
14
15
  def major
15
- 2
16
+ 3
16
17
  end
17
18
 
18
19
  # Minor version.
@@ -29,25 +30,25 @@ module Mailgun
29
30
  0
30
31
  end
31
32
 
32
- # Returns a hash representation of version.
33
+ # Return a hash representation of version.
33
34
  #
34
35
  # @return [Hash]
35
36
  def to_h
36
- Hash[KEYS.zip(to_a)]
37
+ ::Hash[KEYS.zip(to_a)]
37
38
  end
38
39
 
39
- # Returns a string representation of version.
40
+ # Return an array representation of version.
40
41
  #
41
42
  # @return [Array]
42
43
  def to_a
43
44
  [major, minor, patch]
44
45
  end
45
46
 
46
- # Returns an array representation of version.
47
+ # Return a string representation of version.
47
48
  #
48
49
  # @return [String]
49
50
  def to_s
50
- to_a.join('.')
51
+ to_a.join(DOT)
51
52
  end
52
53
  end
53
54
  end
@@ -0,0 +1,77 @@
1
+ # Logfile created on 2019-12-20 14:25:19 +0200 by logger.rb/66358
2
+ I, [2019-12-20T14:25:20.156536 #32357] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 14:25:20 +0200
3
+ F, [2019-12-20T14:25:20.159019 #32357] FATAL -- :
4
+ RSpec::Mocks::ExpiredTestDoubleError (#<InstanceDouble(Delivered) (anonymous)> was originally created in one example but has leaked into another example and can no longer be used. rspec-mocks' doubles are designed to only last for one example, and you need to create a new one in each example you wish to use it for.):
5
+ lib/mailgun/tracking/subscriber/evented.rb:26:in `call'
6
+ lib/mailgun/tracking/listener.rb:39:in `block in broadcast'
7
+ lib/mailgun/tracking/listener.rb:39:in `each'
8
+ lib/mailgun/tracking/listener.rb:39:in `broadcast'
9
+ lib/mailgun/tracking/notifier.rb:52:in `broadcast'
10
+ lib/mailgun/tracking/middleware.rb:49:in `handle_event'
11
+ lib/mailgun/tracking/middleware.rb:33:in `call!'
12
+ lib/mailgun/tracking/middleware.rb:20:in `call'
13
+
14
+
15
+ I, [2019-12-20T14:25:20.196642 #32357] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 14:25:20 +0200
16
+ I, [2019-12-20T14:25:20.244510 #32357] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 14:25:20 +0200
17
+ F, [2019-12-20T14:25:20.245802 #32357] FATAL -- :
18
+ RSpec::Mocks::ExpiredTestDoubleError (#<InstanceDouble(Delivered) (anonymous)> was originally created in one example but has leaked into another example and can no longer be used. rspec-mocks' doubles are designed to only last for one example, and you need to create a new one in each example you wish to use it for.):
19
+ lib/mailgun/tracking/subscriber/evented.rb:26:in `call'
20
+ lib/mailgun/tracking/listener.rb:39:in `block in broadcast'
21
+ lib/mailgun/tracking/listener.rb:39:in `each'
22
+ lib/mailgun/tracking/listener.rb:39:in `broadcast'
23
+ lib/mailgun/tracking/notifier.rb:52:in `broadcast'
24
+ lib/mailgun/tracking/middleware.rb:49:in `handle_event'
25
+ lib/mailgun/tracking/middleware.rb:33:in `call!'
26
+ lib/mailgun/tracking/middleware.rb:20:in `call'
27
+
28
+
29
+ I, [2019-12-20T14:25:20.248316 #32357] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 14:25:20 +0200
30
+ I, [2019-12-20T14:25:20.260350 #32357] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 14:25:20 +0200
31
+ F, [2019-12-20T14:25:20.261696 #32357] FATAL -- :
32
+ RSpec::Mocks::ExpiredTestDoubleError (#<InstanceDouble(Delivered) (anonymous)> was originally created in one example but has leaked into another example and can no longer be used. rspec-mocks' doubles are designed to only last for one example, and you need to create a new one in each example you wish to use it for.):
33
+ lib/mailgun/tracking/subscriber/evented.rb:26:in `call'
34
+ lib/mailgun/tracking/listener.rb:39:in `block in broadcast'
35
+ lib/mailgun/tracking/listener.rb:39:in `each'
36
+ lib/mailgun/tracking/listener.rb:39:in `broadcast'
37
+ lib/mailgun/tracking/notifier.rb:52:in `broadcast'
38
+ lib/mailgun/tracking/middleware.rb:49:in `handle_event'
39
+ lib/mailgun/tracking/middleware.rb:33:in `call!'
40
+ lib/mailgun/tracking/middleware.rb:20:in `call'
41
+
42
+
43
+ I, [2019-12-20T14:25:20.264988 #32357] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 14:25:20 +0200
44
+ I, [2019-12-20T14:25:58.135206 #32391] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 14:25:58 +0200
45
+ I, [2019-12-20T14:25:58.150294 #32391] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 14:25:58 +0200
46
+ I, [2019-12-20T14:26:03.646734 #32397] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 14:26:03 +0200
47
+ I, [2019-12-20T14:26:03.650724 #32397] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 14:26:03 +0200
48
+ I, [2019-12-20T14:26:08.150452 #32407] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 14:26:08 +0200
49
+ I, [2019-12-20T14:26:08.154891 #32407] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 14:26:08 +0200
50
+ I, [2019-12-20T14:26:11.908915 #32414] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 14:26:11 +0200
51
+ I, [2019-12-20T14:26:11.914969 #32414] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 14:26:11 +0200
52
+ I, [2019-12-20T14:26:16.436839 #32421] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 14:26:16 +0200
53
+ I, [2019-12-20T14:26:16.443137 #32421] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 14:26:16 +0200
54
+ I, [2019-12-20T14:30:17.817726 #32588] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 14:30:17 +0200
55
+ I, [2019-12-20T14:30:17.821355 #32588] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 14:30:17 +0200
56
+ I, [2019-12-20T14:30:22.836667 #32594] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 14:30:22 +0200
57
+ I, [2019-12-20T14:30:22.844164 #32594] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 14:30:22 +0200
58
+ I, [2019-12-20T14:30:32.888089 #32611] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 14:30:32 +0200
59
+ I, [2019-12-20T14:30:32.890907 #32611] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 14:30:32 +0200
60
+ I, [2019-12-20T14:30:36.327917 #32616] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 14:30:36 +0200
61
+ I, [2019-12-20T14:30:36.332494 #32616] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 14:30:36 +0200
62
+ I, [2019-12-20T14:30:39.691402 #32622] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 14:30:39 +0200
63
+ I, [2019-12-20T14:30:39.705041 #32622] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 14:30:39 +0200
64
+ I, [2019-12-20T14:30:43.148966 #32628] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 14:30:43 +0200
65
+ I, [2019-12-20T14:30:43.154670 #32628] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 14:30:43 +0200
66
+ I, [2019-12-20T14:30:47.047963 #32633] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 14:30:47 +0200
67
+ I, [2019-12-20T14:30:47.051108 #32633] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 14:30:47 +0200
68
+ I, [2019-12-20T14:30:50.559295 #32639] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 14:30:50 +0200
69
+ I, [2019-12-20T14:30:50.566124 #32639] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 14:30:50 +0200
70
+ I, [2019-12-20T14:31:22.457376 #32659] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 14:31:22 +0200
71
+ I, [2019-12-20T14:31:22.464730 #32659] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 14:31:22 +0200
72
+ I, [2019-12-20T14:31:44.337243 #32670] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 14:31:44 +0200
73
+ I, [2019-12-20T14:31:44.345211 #32670] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 14:31:44 +0200
74
+ I, [2019-12-20T14:33:25.161614 #32696] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 14:33:25 +0200
75
+ I, [2019-12-20T14:33:25.171927 #32696] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 14:33:25 +0200
76
+ I, [2019-12-20T14:33:33.415794 #32700] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 14:33:33 +0200
77
+ I, [2019-12-20T14:33:33.422618 #32700] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 14:33:33 +0200