tolliver 2.1.2 → 2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5a1110eda739a5bb9763c51608a6a251c356962bc02690b2b5b81d06239d0893
4
- data.tar.gz: 4ab466afccc3086a66c4d50ecc7c87214b89aa734553f64b8e7f73c93ec491a5
3
+ metadata.gz: 071baa1e13612b56607c74a22057e7a35dff214916a5cb6f8cf2a7640a54facf
4
+ data.tar.gz: d1b9e7e25cc83abc2ca03e2382dfd965fa8eb2bebd872696aa0e2f578247a7ef
5
5
  SHA512:
6
- metadata.gz: 5901317de7117ceca9fcc6396706d018d62d99ebaf69b7361fe2118766c9bf87a6ac684c8169815818b9ac66fe06e9cd6c0326d86ea6f46202abc6352f7d9365
7
- data.tar.gz: 65913171587f3632ed28e43a00827b109a84b8497ffd39651f1002da4ce7cc0a57a8ccaa43982ecf1ef949e3e0e45f7b9fc85328009784c2b88e51a29d2a6d3f
6
+ metadata.gz: 165fb812806151315d58b2482ac909d06dfbff0796d6d35eb19640b736988547f89dae17c71aadbfc01603cff4cdbdc82c2f7d9ee94a6d3c9f7a2439858a4f5b
7
+ data.tar.gz: 7d2ae9b7a4117cffa8f8baa260e338a890d3f9fc6b1a16a046a1b8d803369390179e12263cd46138a653758acf9cd873a31ee3d88100a0c02f3a4518f6cfada7
data/README.md CHANGED
@@ -5,9 +5,10 @@ send it in a batch with different delivery methods:
5
5
 
6
6
  - E-mail with SMTP aor Mailgun provider
7
7
  - SMS with Plivo provider
8
+ - Slack
8
9
  - Whatever custom delivery method
9
10
 
10
- ## Installation
11
+ ## 1. Installation
11
12
 
12
13
  Add gem to your Gemfile:
13
14
 
@@ -20,23 +21,29 @@ Add database migrations to you application (you can modify DB structure accordin
20
21
  $ rake tolliver:install:migrations
21
22
  $ rake db:migrate
22
23
 
23
- ### Plivo support
24
+ ### 1.1. Plivo support
24
25
 
25
26
  Add gem to your Gemfile:
26
27
 
27
28
  ```ruby
28
29
  gem 'plivo'
29
30
  ```
30
-
31
- ### Mailgun support
31
+ ### 1.2. Mailgun support
32
32
 
33
33
  Add gem to your Gemfile:
34
34
 
35
35
  ```ruby
36
36
  gem 'mailgun-ruby'
37
37
  ```
38
+ ### 1.3. Slack support
39
+
40
+ Add gem to your Gemfile:
41
+
42
+ ```ruby
43
+ gem 'slack-ruby-client'
44
+ ````
38
45
 
39
- ## Configuration
46
+ ## 2. Configuration
40
47
 
41
48
  You can configure module through `config/initializers/tolliver.rb` file:
42
49
 
@@ -63,9 +70,10 @@ Available options:
63
70
  - sms_sender
64
71
  - sms_provider
65
72
  - sms_provider_params
73
+ - slack_params
66
74
  - delivery_methods
67
75
 
68
- ### Plivo support
76
+ ### 2.1. Plivo support
69
77
 
70
78
  Set Plivo as SMS provider and add Plivo auth ID and token into Tolliver configuration file:
71
79
 
@@ -80,7 +88,7 @@ Tolliver.setup do |config|
80
88
  end
81
89
  ```
82
90
 
83
- ### Mailgun support
91
+ ### 2.2. Mailgun support
84
92
 
85
93
  Set Mailgun as e-mail provider and add Mailgun API key and domain into Tolliver configuration file:
86
94
 
@@ -95,7 +103,7 @@ Tolliver.setup do |config|
95
103
  end
96
104
  ```
97
105
 
98
- ## Usage
106
+ ## 3. Usage
99
107
 
100
108
  To enter new notification into the system, just call `notify` method:
101
109
 
@@ -107,8 +115,8 @@ Tolliver.notify(
107
115
  {key: :key_2, value: :value_2}
108
116
  ],
109
117
  receivers: [
110
- {ref: :receiver_1, contact: "receiver_1@domain.tld"},
111
- {ref: :receiver_2, contact: "receiver_2@domain.tld"},
118
+ {ref: :receiver_1, email: "receiver_1@domain.tld"},
119
+ {ref: :receiver_2, email: "receiver_2@domain.tld"},
112
120
  ]
113
121
  )
114
122
  ```
@@ -0,0 +1,12 @@
1
+ class AddShortMessageAndPhone < ActiveRecord::Migration[6.0]
2
+ def change
3
+ add_column :notification_templates, :short_message, :string
4
+ add_column :notifications, :short_message, :string
5
+
6
+ rename_column :notification_deliveries, :sender_contact, :sender_email
7
+ add_column :notification_deliveries, :sender_phone, :string
8
+
9
+ rename_column :notification_receivers, :receiver_contact, :receiver_email
10
+ add_column :notification_receivers, :receiver_phone, :string
11
+ end
12
+ end
@@ -0,0 +1,5 @@
1
+ class AddSlackId < ActiveRecord::Migration[6.0]
2
+ def change
3
+ add_column :notification_receivers, :receiver_slack_id, :string
4
+ end
5
+ end
@@ -33,7 +33,7 @@ module Tolliver
33
33
  end
34
34
 
35
35
  # Mail
36
- mail(from: @sender_email, to: @notification_receiver.receiver_contact.to_s, subject: @notification.subject)
36
+ mail(from: @sender_email, to: @notification_receiver.receiver_email.to_s, subject: @notification.subject)
37
37
  end
38
38
 
39
39
  end
@@ -23,13 +23,7 @@ module Tolliver
23
23
  has_many :notification_deliveries, class_name: Tolliver.notification_delivery_model.to_s, dependent: :destroy
24
24
  has_many :notification_receivers, class_name: Tolliver.notification_receiver_model.to_s, through: :notification_deliveries
25
25
  has_many :notification_attachments, class_name: Tolliver.notification_attachment_model.to_s, dependent: :destroy
26
- belongs_to :notification_template, class_name: Tolliver.notification_template_model.to_s
27
-
28
- # *********************************************************************
29
- # Validators
30
- # *********************************************************************
31
-
32
- validates_presence_of :subject
26
+ belongs_to :notification_template, class_name: Tolliver.notification_template_model.to_s, optional: true
33
27
 
34
28
  end
35
29
 
@@ -32,11 +32,11 @@ module Tolliver
32
32
 
33
33
  def read
34
34
  if @data.nil?
35
- unless notification_attachment.attachment.blank?
36
- @data = Base64.strict_decode64(notification_attachment.attachment) rescue nil
35
+ unless self.attachment.blank?
36
+ @data = Base64.strict_decode64(self.attachment) rescue nil
37
37
  end
38
- unless notification_attachment.url.blank?
39
- @data = open(notification_attachment.url) { |f| f.read }
38
+ unless self.url.blank?
39
+ @data = open(self.url) { |f| f.read }
40
40
  end
41
41
  end
42
42
  @data
@@ -26,7 +26,7 @@ module Tolliver
26
26
  # Validators
27
27
  # *********************************************************************
28
28
 
29
- validates_presence_of :notification_delivery_id, :receiver_ref, :receiver_contact
29
+ validates_presence_of :notification_delivery_id, :receiver_ref
30
30
 
31
31
  # *********************************************************************
32
32
  # State
@@ -29,17 +29,19 @@ module Tolliver
29
29
  # Sender
30
30
  raise Tolliver::Errors::StandardError.new("Please specify e-mail sender.") if Tolliver.email_sender.nil?
31
31
 
32
- # Message builder
32
+ # Build message
33
33
  message = ::Mailgun::MessageBuilder.new
34
34
  message.from(Tolliver.email_sender, {'full_name' => Tolliver.email_sender_name})
35
- message.add_recipient(:to, notification_receiver.receiver_contact.to_s)
36
- message.reply_to(notification_receiver.notification_delivery.sender_contact.to_s) unless notification_receiver.notification_delivery.sender_contact.blank?
35
+ message.add_recipient(:to, notification_receiver.receiver_email.to_s)
36
+ message.reply_to(notification_receiver.notification_delivery.sender_email.to_s) unless notification_receiver.notification_delivery.sender_email.blank?
37
37
  message.subject(notification.subject)
38
38
  message.body_text(ActionController::Base.helpers.strip_tags(notification.message.to_s))
39
39
  message.body_html(notification.message)
40
40
  notification.notification_attachments.each do |notification_attachment|
41
41
  message.add_attachment(StringIO.new(notification_attachment.read), notification_attachment.name) if notification_attachment.read
42
42
  end
43
+
44
+ # Request API
43
45
  response = @client.send_message(@domain, message)
44
46
  if response.code != 200
45
47
  raise Tolliver::Errors::StandardError.new(response.body)
@@ -14,6 +14,23 @@ module Tolliver
14
14
  module Methods
15
15
  class Email
16
16
 
17
+ def is_notification_valid?(notification)
18
+ return false if notification.subject.blank?
19
+ return false if notification.message.blank?
20
+ true
21
+ end
22
+
23
+ def is_notification_delivery_valid?(notification_delivery)
24
+ return false if !notification_delivery.sender_email.blank? && !(notification_delivery.sender_email =~ URI::MailTo::EMAIL_REGEXP)
25
+ true
26
+ end
27
+
28
+ def is_notification_receiver_valid?(notification_receiver)
29
+ return false if notification_receiver.receiver_email.blank?
30
+ return false unless notification_receiver.receiver_email =~ URI::MailTo::EMAIL_REGEXP
31
+ true
32
+ end
33
+
17
34
  def deliver(notification_receiver)
18
35
  return false if provider.nil?
19
36
 
@@ -0,0 +1,90 @@
1
+ # *****************************************************************************
2
+ # * Copyright (c) 2019 Matěj Outlý
3
+ # *****************************************************************************
4
+ # *
5
+ # * Notification method - Slack
6
+ # *
7
+ # * Author: Matěj Outlý
8
+ # * Date : 21. 1. 2016
9
+ # *
10
+ # *****************************************************************************
11
+
12
+ module Tolliver
13
+ module Services
14
+ module Methods
15
+ class Slack
16
+
17
+ def is_notification_valid?(notification)
18
+ return false if notification.message.blank?
19
+ true
20
+ end
21
+
22
+ def is_notification_delivery_valid?(_)
23
+ true
24
+ end
25
+
26
+ def is_notification_receiver_valid?(notification_receiver)
27
+ return false if notification_receiver.receiver_slack_id.blank? && notification_receiver.receiver_email.blank?
28
+ true
29
+ end
30
+
31
+ def deliver(notification_receiver)
32
+
33
+ # Prepare notification
34
+ notification = notification_receiver.notification_delivery.notification
35
+
36
+ # Send message
37
+ begin
38
+ ensure_slack_id(notification_receiver)
39
+ client.chat_postMessage(channel: notification_receiver.receiver_slack_id, text: notification.message)
40
+ notification_receiver.status = 'sent'
41
+ rescue StandardError => e
42
+ notification_receiver.status = 'error'
43
+ notification_receiver.error_message = e.message
44
+ end
45
+
46
+ # Mark as sent
47
+ notification_receiver.sent_at = Time.current
48
+
49
+ # Save
50
+ notification_receiver.save
51
+
52
+ true
53
+ end
54
+
55
+ private
56
+
57
+ def ensure_slack_id(notification_receiver)
58
+ if notification_receiver.receiver_slack_id.blank?
59
+ unless notification_receiver.receiver_email.blank?
60
+ response = client.users_lookupByEmail(email: notification_receiver.receiver_email)
61
+ if response.ok
62
+ notification_receiver.receiver_slack_id = response.user.id
63
+ notification_receiver.save(validate: false)
64
+ end
65
+ end
66
+ end
67
+ if notification_receiver.receiver_slack_id.blank?
68
+ raise Tolliver::Errors::StandardError.new('Receiver Slack ID not recognized.')
69
+ end
70
+ end
71
+
72
+ def client
73
+ if @client.nil?
74
+ require 'slack'
75
+ api_token = Tolliver.slack_params[:api_token]
76
+ if api_token.blank?
77
+ raise Tolliver::Errors::StandardError.new('Please provide API Token in Slack params.')
78
+ end
79
+ ::Slack.configure do |config|
80
+ config.token = api_token
81
+ end
82
+ @client = ::Slack::Web::Client.new
83
+ end
84
+ @client
85
+ end
86
+
87
+ end
88
+ end
89
+ end
90
+ end
@@ -22,23 +22,18 @@ module Tolliver
22
22
  end
23
23
  @auth_id = params[:auth_id]
24
24
  @auth_token = params[:auth_token]
25
- @api = ::Plivo::RestAPI.new(@auth_id, @auth_token)
25
+ @client = ::Plivo::RestClient.new(@auth_id, @auth_token)
26
26
  end
27
27
 
28
28
  def deliver(notification, notification_receiver)
29
29
 
30
- # Check message length.
31
- if message.bytesize > 200
32
- raise 'Message too long.'
33
- end
30
+ # Sender
31
+ raise Tolliver::Errors::StandardError.new("Please specify SMS sender.") if Tolliver.sms_sender.nil?
34
32
 
35
33
  # Request API
36
- response = @api.send_message({
37
- 'src' => Tolliver.sms_sender, # TODO: This should be improved to take sender from number pool and remember number / message mapping
38
- 'dst' => notification_receiver.receiver_contact.to_s,
39
- 'text' => ActionController::Base.helpers.strip_tags(notification.message.to_s),
40
- 'method' => 'POST'
41
- })
34
+ @client.message.create(Tolliver.sms_sender, # TODO: This should be improved to take sender from number pool and remember number / message mapping
35
+ [notification_receiver.receiver_phone.to_s],
36
+ ActionController::Base.helpers.strip_tags(notification.short_message.to_s))
42
37
 
43
38
  true
44
39
  end
@@ -14,6 +14,20 @@ module Tolliver
14
14
  module Methods
15
15
  class Sms
16
16
 
17
+ def is_notification_valid?(notification)
18
+ return false if notification.short_message.blank?
19
+ true
20
+ end
21
+
22
+ def is_notification_delivery_valid?(_)
23
+ true
24
+ end
25
+
26
+ def is_notification_receiver_valid?(notification_receiver)
27
+ return false if notification_receiver.receiver_phone.blank?
28
+ true
29
+ end
30
+
17
31
  def deliver(notification_receiver)
18
32
  return false if provider.nil?
19
33
 
@@ -29,17 +29,23 @@ module Tolliver
29
29
  raise Tolliver::Errors::BadRequest.new('Missing template.') if template.blank?
30
30
  notification_template = Tolliver.notification_template_model.where(ref: template).first
31
31
  notification_template = Tolliver.notification_template_model.where(id: template).first if notification_template.nil?
32
+ if notification_template.nil? && template.to_s == 'common'
33
+ notification_template = Tolliver.notification_template_model.new(subject: '%{subject}',
34
+ message: '%{message}', short_message: '%{message}',
35
+ is_disabled: false, is_dry: false)
36
+ end
32
37
  raise Tolliver::Errors::NotFound.new("Template #{template.to_s} not found.") if notification_template.nil?
33
38
 
34
- if !notification_template.is_disabled && !notification_template.message.blank?
39
+ if !notification_template.is_disabled
35
40
 
36
41
  # Interpret params and store it in DB
37
42
  params = map_params(options[:params] || {})
38
- notification.message = eval_expressions(interpret_named_params(notification_template.message, params))
39
- notification.subject = eval_expressions(interpret_named_params(notification_template.subject, params))
43
+ notification.subject = eval_expressions(interpret_named_params(notification_template.subject.to_s, params))
44
+ notification.message = eval_expressions(interpret_named_params(notification_template.message.to_s, params))
45
+ notification.short_message = eval_expressions(interpret_named_params(notification_template.short_message.to_s, params))
40
46
 
41
47
  # Notification template
42
- notification.notification_template = notification_template
48
+ notification.notification_template = notification_template unless notification_template.new_record?
43
49
 
44
50
  # Signature
45
51
  unless options[:signature].blank?
@@ -47,7 +53,7 @@ module Tolliver
47
53
  end
48
54
 
49
55
  # Save to DB
50
- notification.save
56
+ notification.save!
51
57
 
52
58
  # Attachments
53
59
  unless options[:attachments].blank?
@@ -77,7 +83,10 @@ module Tolliver
77
83
  methods.each do |method|
78
84
 
79
85
  # Delivery object
80
- notification_delivery = notification.notification_deliveries.create(method: method)
86
+ notification_delivery = notification.notification_deliveries.build(method: method)
87
+
88
+ # Validate notification suitability for the selected method
89
+ next unless notification_delivery.method_service.is_notification_valid?(notification)
81
90
 
82
91
  # Is postponed
83
92
  if options[:is_postponed]
@@ -86,34 +95,46 @@ module Tolliver
86
95
 
87
96
  # Sender
88
97
  unless options[:sender].blank?
89
- raise Tolliver::Errors::BadRequest.new('Missing sender ref.') if options[:sender][:ref].blank?
90
- raise Tolliver::Errors::BadRequest.new('Missing sender contact.') if options[:sender][:contact].blank?
91
98
  notification_delivery.sender_ref = options[:sender][:ref]
92
- notification_delivery.sender_contact = options[:sender][:contact]
99
+ notification_delivery.sender_email = options[:sender][:email]
100
+ notification_delivery.sender_phone = options[:sender][:phone]
101
+ raise Tolliver::Errors::BadRequest.new('Missing sender ref.') if notification_delivery.sender_ref.blank?
102
+ unless notification_delivery.method_service.is_notification_delivery_valid?(notification_delivery) # throw exception if sender not valid
103
+ raise Tolliver::Errors::BadRequest.new('Sender contact not valid.')
104
+ end
93
105
  end
94
106
 
107
+ # Must be persisted in DB before receiver created
108
+ notification_delivery.save!
109
+
95
110
  # Receivers
96
111
  receivers = options[:receivers] || []
97
112
  raise Tolliver::Errors::BadRequest.new('Missing receivers.') if receivers.blank? || receivers.empty?
98
113
  receivers = [receivers] unless receivers.is_a?(Array)
99
- filtered_receivers = receivers.dup # TODO contact validation based on method and filter
100
114
 
101
- # Save to DB
102
- filtered_receivers.each do |receiver|
103
- raise Tolliver::Errors::BadRequest.new('Missing receiver ref.') if receiver[:ref].blank?
104
- raise Tolliver::Errors::BadRequest.new('Missing receiver contact.') if receiver[:contact].blank?
105
- notification_delivery.notification_receivers.create(receiver_ref: receiver[:ref], receiver_contact: receiver[:contact])
115
+ # Save to DB if valid for the selected method
116
+ receivers_count = 0
117
+ receivers.each do |receiver|
118
+ notification_receiver = notification_delivery.notification_receivers.build
119
+ notification_receiver.receiver_ref = receiver[:ref]
120
+ notification_receiver.receiver_email = receiver[:email]
121
+ notification_receiver.receiver_phone = receiver[:phone]
122
+ raise Tolliver::Errors::BadRequest.new('Missing receiver ref.') if notification_receiver.receiver_ref.blank?
123
+ if notification_delivery.method_service.is_notification_receiver_valid?(notification_receiver) # ignore receiver if not valid
124
+ notification_receiver.save!
125
+ receivers_count += 1
126
+ end
106
127
  end
107
128
  notification_delivery.sent_count = 0
108
- notification_delivery.receivers_count = filtered_receivers.size
109
- notification_delivery.save
129
+ notification_delivery.receivers_count = receivers_count
130
+ notification_delivery.save!
110
131
 
111
132
  end
112
133
 
113
134
  end
114
135
 
115
136
  else
116
- notification = nil # Do not create notification with empty message
137
+ notification = nil # Do not create disabled notification
117
138
  end
118
139
 
119
140
  end
data/lib/tolliver.rb CHANGED
@@ -29,6 +29,7 @@ require "tolliver/services/methods/email/smtp"
29
29
  require "tolliver/services/methods/email/mailgun"
30
30
  require "tolliver/services/methods/sms"
31
31
  require "tolliver/services/methods/sms/plivo"
32
+ require "tolliver/services/methods/slack"
32
33
 
33
34
  # Jobs
34
35
  require "tolliver/jobs/delivery_job"
@@ -134,6 +135,7 @@ module Tolliver
134
135
  # Available methods:
135
136
  # - email
136
137
  # - sms
138
+ # - slack
137
139
  # - whatever
138
140
  mattr_accessor :delivery_methods
139
141
  @@delivery_methods = [
@@ -170,10 +172,14 @@ module Tolliver
170
172
 
171
173
  # Used SMS provider
172
174
  mattr_accessor :sms_provider
173
- @@sms_provider = nil
175
+ @@sms_provider = :plivo
174
176
 
175
177
  # SMS provider params
176
178
  mattr_accessor :sms_provider_params
177
179
  @@sms_provider_params = {}
178
180
 
181
+ # Slack provider params
182
+ mattr_accessor :slack_params
183
+ @@slack_params = {}
184
+
179
185
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tolliver
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.2
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matěj Outlý
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-04-14 00:00:00.000000000 Z
11
+ date: 2022-08-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -51,6 +51,8 @@ files:
51
51
  - db/migrate/20170630190600_create_notification_deliveries.rb
52
52
  - db/migrate/20201027150000_create_notification_attachments.rb
53
53
  - db/migrate/20210415120000_add_notification_attachments_url.rb
54
+ - db/migrate/20210528120000_add_short_message_and_phone.rb
55
+ - db/migrate/20220805120000_add_slack_id.rb
54
56
  - lib/tolliver.rb
55
57
  - lib/tolliver/engine.rb
56
58
  - lib/tolliver/errors/bad_request.rb
@@ -68,6 +70,7 @@ files:
68
70
  - lib/tolliver/services/methods/email.rb
69
71
  - lib/tolliver/services/methods/email/mailgun.rb
70
72
  - lib/tolliver/services/methods/email/smtp.rb
73
+ - lib/tolliver/services/methods/slack.rb
71
74
  - lib/tolliver/services/methods/sms.rb
72
75
  - lib/tolliver/services/methods/sms/plivo.rb
73
76
  - lib/tolliver/services/notification_service.rb