paubox 0.2.3 → 0.3.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/Rakefile CHANGED
@@ -1,6 +1,8 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
3
-
4
- RSpec::Core::RakeTask.new(:spec)
5
-
6
- task :default => :spec
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
@@ -1,14 +1,15 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "bundler/setup"
4
- require "paubox_ruby"
5
-
6
- # You can add fixtures and/or initialization code here to make experimenting
7
- # with your gem easier. You can also use a different console, if you like.
8
-
9
- # (If you use this, don't forget to add pry to your Gemfile!)
10
- # require "pry"
11
- # Pry.start
12
-
13
- require "irb"
14
- IRB.start(__FILE__)
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'paubox_ruby'
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require 'irb'
15
+ IRB.start(__FILE__)
data/bin/setup CHANGED
@@ -1,8 +1,8 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
5
-
6
- bundle install
7
-
8
- # Do any other automated setup that you need to do here
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -1,19 +1,21 @@
1
- module Mail
2
- class Paubox
3
- attr_accessor :settings
4
-
5
- def initialize(settings)
6
- @settings = settings
7
- end
8
-
9
- def deliver!(mail)
10
- client = ::Paubox::Client.new(settings)
11
- response = client.send_mail(mail)
12
- puts response
13
- end
14
- end
15
-
16
- class Message
17
- attr_accessor :source_tracking_id, :status, :allow_non_tls
18
- end
19
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Mail
4
+ class Paubox
5
+ attr_accessor :settings
6
+
7
+ def initialize(settings)
8
+ @settings = settings
9
+ end
10
+
11
+ def deliver!(mail)
12
+ client = ::Paubox::Client.new(settings)
13
+ response = client.send_mail(mail)
14
+ puts response
15
+ end
16
+ end
17
+
18
+ class Message
19
+ attr_accessor :source_tracking_id, :status, :allow_non_tls, :force_secure_notification
20
+ end
21
+ end
@@ -1,22 +1,24 @@
1
- require 'paubox/version'
2
- require 'paubox/client'
3
- require 'paubox/format_helper'
4
- require 'paubox/mail_to_message'
5
- require 'paubox/message'
6
- require 'paubox/email_disposition'
7
- require 'mail/paubox'
8
-
9
- module Paubox
10
- class << self
11
- attr_accessor :configuration
12
- end
13
-
14
- def self.configure
15
- self.configuration ||= Configuration.new
16
- yield(configuration)
17
- end
18
-
19
- class Configuration
20
- attr_accessor :api_key, :api_user
21
- end
22
- end
1
+ # frozen_string_literal: true
2
+
3
+ require 'paubox/version'
4
+ require 'paubox/client'
5
+ require 'paubox/format_helper'
6
+ require 'paubox/mail_to_message'
7
+ require 'paubox/message'
8
+ require 'paubox/email_disposition'
9
+ require 'mail/paubox'
10
+
11
+ module Paubox
12
+ class << self
13
+ attr_accessor :configuration
14
+ end
15
+
16
+ def self.configure
17
+ self.configuration ||= Configuration.new
18
+ yield(configuration)
19
+ end
20
+
21
+ class Configuration
22
+ attr_accessor :api_key, :api_user
23
+ end
24
+ end
@@ -1,81 +1,85 @@
1
- module Paubox
2
- # Client sends API requests to Paubox API
3
- class Client
4
- require 'rest-client'
5
- require 'ostruct'
6
- attr_reader :api_key, :api_user, :api_host, :api_protocol, :api_version
7
-
8
- def initialize(args = {})
9
- args = defaults.merge(args)
10
- @api_key = args[:api_key]
11
- @api_user = args[:api_user]
12
- @api_host = args[:api_host]
13
- @api_protocol = args[:api_protocol]
14
- @api_version = args[:api_version]
15
- @test_mode = args[:test_mode]
16
- @api_base_endpoint = api_base_endpoint
17
- @allow_non_tls = args.fetch(:allow_non_tls, false)
18
- end
19
-
20
- def api_status
21
- url = request_endpoint('status')
22
- RestClient.get(url, accept: :json)
23
- end
24
-
25
- def send_mail(mail)
26
- case mail
27
- when Mail::Message
28
- payload = MailToMessage.new(mail, { allow_non_tls: @allow_non_tls })
29
- .send_message_payload
30
- when Hash
31
- payload = Message.new(mail).send_message_payload
32
- end
33
- url = request_endpoint('messages')
34
- response = RestClient.post(url, payload, auth_header)
35
- if mail.class == Mail::Message
36
- mail.source_tracking_id = JSON.parse(response.body)['sourceTrackingId']
37
- end
38
- JSON.parse(response.body)
39
- end
40
- alias deliver_mail send_mail
41
-
42
- def email_disposition(source_tracking_id)
43
- url = "#{request_endpoint('message_receipt')}?sourceTrackingId=#{source_tracking_id}"
44
- response = RestClient.get(url, auth_header)
45
- email_disposition = Paubox::EmailDisposition.new(JSON.parse(response.body))
46
- end
47
- alias message_receipt email_disposition
48
-
49
- private
50
-
51
- def auth_header
52
- { accept: :json,
53
- content_type: :json,
54
- :Authorization => "Token token=#{@api_key}" }
55
- end
56
-
57
- def api_base_endpoint
58
- "#{api_protocol}#{api_host}/#{api_version}/#{api_user}"
59
- end
60
-
61
- def request_endpoint(endpoint)
62
- "#{api_base_endpoint}/#{endpoint}"
63
- end
64
-
65
- def defaults
66
- { api_key: Paubox.configuration.api_key,
67
- api_user: Paubox.configuration.api_user,
68
- api_host: 'api.paubox.net',
69
- api_protocol: 'https://',
70
- api_version: 'v1',
71
- test_mode: false }
72
- end
73
-
74
- # recursively converts a nested Hash into OpenStruct
75
- def to_open_struct(hash)
76
- OpenStruct.new(hash.each_with_object({}) do |(key, val), memo|
77
- memo[key] = val.is_a?(Hash) ? to_open_struct(val) : val
78
- end)
79
- end
80
- end
81
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Paubox
4
+ # Client sends API requests to Paubox API
5
+ class Client
6
+ require 'rest-client'
7
+ require 'ostruct'
8
+ attr_reader :api_key, :api_user, :api_host, :api_protocol, :api_version
9
+
10
+ def initialize(args = {})
11
+ args = defaults.merge(args)
12
+ @api_key = args[:api_key]
13
+ @api_user = args[:api_user]
14
+ @api_host = args[:api_host]
15
+ @api_protocol = args[:api_protocol]
16
+ @api_version = args[:api_version]
17
+ @test_mode = args[:test_mode]
18
+ @api_base_endpoint = api_base_endpoint
19
+ end
20
+
21
+ def api_status
22
+ url = request_endpoint('status')
23
+ RestClient.get(url, accept: :json)
24
+ end
25
+
26
+ def send_mail(mail)
27
+ case mail
28
+ when Mail::Message
29
+ allow_non_tls = mail.allow_non_tls.nil? ? false : mail.allow_non_tls
30
+ payload = MailToMessage.new(mail, allow_non_tls: allow_non_tls)
31
+ .send_message_payload
32
+ when Hash
33
+ payload = Message.new(mail).send_message_payload
34
+ when Paubox::Message
35
+ payload = mail.send_message_payload
36
+ end
37
+ url = request_endpoint('messages')
38
+ response = RestClient.post(url, payload, auth_header)
39
+ if mail.class == Mail::Message
40
+ mail.source_tracking_id = JSON.parse(response.body)['sourceTrackingId']
41
+ end
42
+ JSON.parse(response.body)
43
+ end
44
+ alias deliver_mail send_mail
45
+
46
+ def email_disposition(source_tracking_id)
47
+ url = "#{request_endpoint('message_receipt')}?sourceTrackingId=#{source_tracking_id}"
48
+ response = RestClient.get(url, auth_header)
49
+ email_disposition = Paubox::EmailDisposition.new(JSON.parse(response.body))
50
+ end
51
+ alias message_receipt email_disposition
52
+
53
+ private
54
+
55
+ def auth_header
56
+ { accept: :json,
57
+ content_type: :json,
58
+ Authorization: "Token token=#{@api_key}" }
59
+ end
60
+
61
+ def api_base_endpoint
62
+ "#{api_protocol}#{api_host}/#{api_version}/#{api_user}"
63
+ end
64
+
65
+ def request_endpoint(endpoint)
66
+ "#{api_base_endpoint}/#{endpoint}"
67
+ end
68
+
69
+ def defaults
70
+ { api_key: Paubox.configuration.api_key,
71
+ api_user: Paubox.configuration.api_user,
72
+ api_host: 'api.paubox.net',
73
+ api_protocol: 'https://',
74
+ api_version: 'v1',
75
+ test_mode: false }
76
+ end
77
+
78
+ # recursively converts a nested Hash into OpenStruct
79
+ def to_open_struct(hash)
80
+ OpenStruct.new(hash.each_with_object({}) do |(key, val), memo|
81
+ memo[key] = val.is_a?(Hash) ? to_open_struct(val) : val
82
+ end)
83
+ end
84
+ end
85
+ end
@@ -1,57 +1,62 @@
1
- module Paubox
2
- # Parses email dispositions from /v1/message_reciept response to friendly Ruby
3
- class EmailDisposition
4
- require 'time'
5
- attr_reader :response, :raw_json_response, :source_tracking_id, :message_id,
6
- :message_deliveries, :errors
7
- MessageDelivery = Struct.new(:recipient, :status)
8
- MessageDeliveryStatus = Struct.new(:delivery_status, :delivery_time,
9
- :opened_status, :opened_time)
10
- MessageMultiDeliveryStatus = Struct.new(:delivery_status, :delivery_time)
11
- ResponseError = Struct.new(:code, :status, :title, :details)
12
-
13
- def initialize(response)
14
- @response = response
15
- @raw_json_response = response.to_json
16
- @source_tracking_id = response.dig('sourceTrackingId')
17
- @message_data = response.dig('data', 'message')
18
- @message_id = @message_data ? @message_data['id'] : nil
19
- @message_deliveries ||= build_message_deliveries
20
- @errors ||= build_errors
21
- end
22
-
23
- def errors?
24
- errors.any?
25
- end
26
-
27
- def build_errors
28
- return [] unless response['errors']
29
- errors = response['errors']
30
- errors.map { |e| ResponseError.new(e['code'], e['status'], e['title'], e['details']) }
31
- end
32
-
33
- private
34
-
35
- def build_message_deliveries
36
- return [] unless @message_data
37
- deliveries = @message_data.fetch('message_deliveries', [])
38
- deliveries.map do |delivery|
39
- status = build_message_delivery_status(delivery['status'])
40
- MessageDelivery.new(delivery['recipient'], status)
41
- end
42
- end
43
-
44
- def build_message_delivery_status(stat)
45
- delivery_status = stat['deliveryStatus']
46
- delivery_time = stat['deliveryTime'].to_s.empty? ? nil : DateTime.parse(stat['deliveryTime'])
47
- opened_status = stat['openedStatus'].to_s.empty? ? 'unopened' : stat['openedStatus']
48
- opened_time = stat['openedTime'].to_s.empty? ? nil : DateTime.parse(stat['openedTime'])
49
- return MessageMultiDeliveryStatus.new(delivery_status, delivery_time) if multi_recipient?
50
- MessageDeliveryStatus.new(delivery_status, delivery_time, opened_status, opened_time)
51
- end
52
-
53
- def multi_recipient?
54
- @message_data.fetch('message_deliveries', []).length > 1
55
- end
56
- end
57
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Paubox
4
+ # Parses email dispositions from /v1/message_reciept response to friendly Ruby
5
+ class EmailDisposition
6
+ require 'time'
7
+ attr_reader :response, :raw_json_response, :source_tracking_id, :message_id,
8
+ :message_deliveries, :errors
9
+ MessageDelivery = Struct.new(:recipient, :status)
10
+ MessageDeliveryStatus = Struct.new(:delivery_status, :delivery_time,
11
+ :opened_status, :opened_time)
12
+ MessageMultiDeliveryStatus = Struct.new(:delivery_status, :delivery_time)
13
+ ResponseError = Struct.new(:code, :status, :title, :details)
14
+
15
+ def initialize(response)
16
+ @response = response
17
+ @raw_json_response = response.to_json
18
+ @source_tracking_id = response.dig('sourceTrackingId')
19
+ @message_data = response.dig('data', 'message')
20
+ @message_id = @message_data ? @message_data['id'] : nil
21
+ @message_deliveries ||= build_message_deliveries
22
+ @errors ||= build_errors
23
+ end
24
+
25
+ def errors?
26
+ errors.any?
27
+ end
28
+
29
+ def build_errors
30
+ return [] unless response['errors']
31
+
32
+ errors = response['errors']
33
+ errors.map { |e| ResponseError.new(e['code'], e['status'], e['title'], e['details']) }
34
+ end
35
+
36
+ private
37
+
38
+ def build_message_deliveries
39
+ return [] unless @message_data
40
+
41
+ deliveries = @message_data.fetch('message_deliveries', [])
42
+ deliveries.map do |delivery|
43
+ status = build_message_delivery_status(delivery['status'])
44
+ MessageDelivery.new(delivery['recipient'], status)
45
+ end
46
+ end
47
+
48
+ def build_message_delivery_status(stat)
49
+ delivery_status = stat['deliveryStatus']
50
+ delivery_time = stat['deliveryTime'].to_s.empty? ? nil : DateTime.parse(stat['deliveryTime'])
51
+ opened_status = stat['openedStatus'].to_s.empty? ? 'unopened' : stat['openedStatus']
52
+ opened_time = stat['openedTime'].to_s.empty? ? nil : DateTime.parse(stat['openedTime'])
53
+ return MessageMultiDeliveryStatus.new(delivery_status, delivery_time) if multi_recipient?
54
+
55
+ MessageDeliveryStatus.new(delivery_status, delivery_time, opened_status, opened_time)
56
+ end
57
+
58
+ def multi_recipient?
59
+ @message_data.fetch('message_deliveries', []).length > 1
60
+ end
61
+ end
62
+ end
@@ -1,55 +1,60 @@
1
- module Paubox
2
- # Utility methods for Message and MailToMessage
3
- module FormatHelper
4
- require 'base64'
5
- BASE64_REGEX = %r(/^(?:[A-Za-z0-9+\/]{4}\n?)*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$/)
6
-
7
- def base64_encoded?(value)
8
- return false unless value.is_a?(String)
9
- !value.strip.match(BASE64_REGEX).nil?
10
- end
11
-
12
- def base64_encode_if_needed(str)
13
- return str if base64_encoded?(str.to_s)
14
- Base64.encode64(str.to_s)
15
- end
16
-
17
- # Converts hash keys to strings and maps them to expected JSON key.
18
- # Also converts hashes in shallow arrays.
19
- def convert_keys_to_json_version(hash)
20
- converted = {}
21
- hash.each_pair do |key, val|
22
- converted[ruby_to_json_key(key)] = val.is_a?(Hash) ? convert_keys_to_json_version(val) : val
23
- next unless val.is_a?(Array)
24
- val.each_with_index { |el, i| val[i] = convert_keys_to_json_version(el) if el.is_a?(Hash) }
25
- end
26
- converted
27
- end
28
-
29
- def ruby_to_json_key(key)
30
- { reply_to: 'reply-to', html_content: 'text/html', text_content: 'text/plain',
31
- filename: 'fileName', file_name: 'fileName', content_type: 'contentType',
32
- allow_non_tls: 'allowNonTLS' }[key] || key.to_s
33
- end
34
-
35
- # def get_values_whitelist(*vals)
36
- # vals.map { |k| next unless mail[k]; [ruby_to_json_key(k), mail[k]] }.to_h
37
- # end
38
-
39
- def string_or_array_to_array(object)
40
- case object
41
- when String
42
- a = object.split(',').map { |str| squish(str) }
43
- when Array
44
- a = object.map { |s| squish(s) }
45
- else
46
- return []
47
- end
48
- a.reject(&:empty?)
49
- end
50
-
51
- def squish(str)
52
- str.to_s.split.join(' ')
53
- end
54
- end
55
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Paubox
4
+ # Utility methods for Message and MailToMessage
5
+ module FormatHelper
6
+ require 'base64'
7
+ BASE64_REGEX = %r(/^(?:[A-Za-z0-9+\/]{4}\n?)*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$/).freeze
8
+
9
+ def base64_encoded?(value)
10
+ return false unless value.is_a?(String)
11
+
12
+ !value.strip.match(BASE64_REGEX).nil?
13
+ end
14
+
15
+ def base64_encode_if_needed(str)
16
+ return str if base64_encoded?(str.to_s)
17
+
18
+ Base64.encode64(str.to_s)
19
+ end
20
+
21
+ # Converts hash keys to strings and maps them to expected JSON key.
22
+ # Also converts hashes in shallow arrays.
23
+ def convert_keys_to_json_version(hash)
24
+ converted = {}
25
+ hash.each_pair do |key, val|
26
+ converted[ruby_to_json_key(key)] = val.is_a?(Hash) ? convert_keys_to_json_version(val) : val
27
+ next unless val.is_a?(Array)
28
+
29
+ val.each_with_index { |el, i| val[i] = convert_keys_to_json_version(el) if el.is_a?(Hash) }
30
+ end
31
+ converted
32
+ end
33
+
34
+ def ruby_to_json_key(key)
35
+ { reply_to: 'reply-to', html_content: 'text/html', text_content: 'text/plain',
36
+ filename: 'fileName', file_name: 'fileName', content_type: 'contentType',
37
+ allow_non_tls: 'allowNonTLS', force_secure_notification: 'forceSecureNotification' }[key] || key.to_s
38
+ end
39
+
40
+ # def get_values_whitelist(*vals)
41
+ # vals.map { |k| next unless mail[k]; [ruby_to_json_key(k), mail[k]] }.to_h
42
+ # end
43
+
44
+ def string_or_array_to_array(object)
45
+ case object
46
+ when String
47
+ a = object.split(',').map { |str| squish(str) }
48
+ when Array
49
+ a = object.map { |s| squish(s) }
50
+ else
51
+ return []
52
+ end
53
+ a.reject(&:empty?)
54
+ end
55
+
56
+ def squish(str)
57
+ str.to_s.split.join(' ')
58
+ end
59
+ end
60
+ end