active_notifier 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 24d5eac70996ae751cbfac298f4bd78074b53f913c19325347bf50bfcd557eb9
4
- data.tar.gz: 7716f56010b04db00fe06e7a3b5773350a9a58ffcb4b117a64bfd17ed3fe18a7
3
+ metadata.gz: 11d89dfa1aff8c314539b8ff79b5cbb72ed89f98e2fdce3c324a7e8ee097c789
4
+ data.tar.gz: b8edd79f2f6244a442a2d4bfb603ef0f4e6504971d6c9b4a33b66330f87a60e4
5
5
  SHA512:
6
- metadata.gz: c4793839706e3f4fad3151255736fc0b820611997cd044e793c125b93e1375aab281dd476165525748f6229cd6b45693d0536dad31cc66a47a3924f43119adf4
7
- data.tar.gz: 77e1fa443c84606455d712a7340d474b607ebcfa3fb59567f334a19a370384d5d7656fd94a9cd0f9fe4a7265c8b42139ca210e5dfe83cbf8567918e991fc00a5
6
+ metadata.gz: 53025b951b32263b901f958d9200fa0eae7c954960a39299a1d249686fdeac091bedeee457256c379a4bd44e09274a02e1c2d613e8b1003c918501cee18be66d
7
+ data.tar.gz: 2d83333750347d2ec943ac14a273111de68ccb02226898ffea26c4e22792efc460859b1c17306c8cd0c521c9d74ffe3a2399ff098a8338120aed489c4d3dda2d
data/.rubocop.yml CHANGED
@@ -2,6 +2,7 @@ AllCops:
2
2
  TargetRubyVersion: 2.3
3
3
  Exclude:
4
4
  - 'bin/*'
5
+ - 'vendor/**/*'
5
6
  Metrics/LineLength:
6
7
  Max: 120
7
8
  Style/AsciiComments:
data/.travis.yml ADDED
@@ -0,0 +1,13 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.5.1
4
+ cache: bundler
5
+ script:
6
+ - bundle exec rspec
7
+ - bundle exec rubocop
8
+ deploy:
9
+ provider: rubygems
10
+ api_key:
11
+ secure: Kuaq/l0/f+pasOQRFpiF43o5bOqlhP3wbStxSYVAZye8YuGCMZ7wnzhNlD8cU57nc1e2tsONv78OT8qUKr8uNTeDU1RpRzAq8FEAiIHYHe2Rw/JUibE2c7GJchvpoQNCSCZZJbr6NZ5EcK6yx/mOoiZgWlAcvLWb2SdkIwDsRkucl6UEE6DP87ddkjBsE9TYAKV+Q+U76JHr20E0ANjoyTq4K6htdLuOqY2GwwhosQzZw/ixHNS+9GMCDJNJAJg5VYbv8AgCNgzkOPmPydfca1GWHSVul1QLvxC5EC7Sv8gt+uAcfxErf860hwoymenobhCMNPPmRZk65I+a2PC2O0Ni8xWriT8zsOJC15kFEGvmWFT5Vhix1fOCglB2C0CCanbfId+NjGu9AzfuT2cn7ySKbl3f2A7U3Kaopqge38z4xg0uYudfh9TkcZteUM8bq/S3Ioh3Z7NrynMfWcaFxArMkFoiAyCcJhXmQg/WXFKJjDXIC5AEWaEfv1xnBh/UZPIaqB5KC7MU2VRoesebr3EQl3rLU1AS+ga5m50lqnTIMRyH6clxvwojgfg51hkFRc16svTXshDvCq+u+ZfQUghO93jkeVHXernbiZFyzPFosBUwTxk75o5OaSKs6l6O52OIGa+mp6YqlCPXw5AGfQLBdS7qcuFokAKNesJQnts=
12
+ on:
13
+ tags: true
data/README.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  Notify message through webhooks.
4
4
 
5
+ [![Gem Version](https://badge.fury.io/rb/active_notifier.svg)](https://badge.fury.io/rb/active_notifier)
6
+ [![Build Status](https://travis-ci.org/pinewong/active_notifier.svg)](https://travis-ci.org/pinewong/active_notifier)
7
+ [![Test Coverage](https://codecov.io/github/pinewong/active_notifier/coverage.svg?branch=master)](https://codecov.io/github/pinewong/active_notifier?branch=master)
8
+
5
9
  ## Installation
6
10
 
7
11
  Add this line to your application's Gemfile:
@@ -18,118 +22,88 @@ Or install it yourself as:
18
22
 
19
23
  $ gem install active_notifier
20
24
 
21
- ## Usage
25
+ ## Basic Usage
22
26
 
23
- ### Basic
27
+ Just notify the message through a webhook token, ActiveNotifier use Dingtalk by default, the webhook token
28
+ need be a accessible dingtalk webhook token.
24
29
 
25
30
  ```ruby
26
- ActiveNotifer.config.channel_tokens = { default: "xxx" }
27
- ActiveNotifier.exec(:default)
28
- # This will notifier message, use options:
29
- # token: config.channel_tokens[:default],
30
- # template: "#{config.template_home}/default.*.erb"
31
-
32
- ActiveNotifier.exec(:default, template: "orders/create")
33
- # Use specific template file but not get by channel
34
- # This will notifier message, use options:
35
- # token: config.channel_tokens[:default],
36
- # template: "#{config.template_home}/orders/create.*.erb"
37
-
38
- ActiveNotifier.exec(:default, token: "special_token", data: { title: "Title", message: "Message" })
39
- # Use specific token but not get by channel
40
- # This will notifier message, use options:
41
- # token: "special_token",
42
- # template: "#{config.template_home}/default.*.erb"
43
- # And the Hash data will inject to template, and get a dynamic message after parse template
31
+ ActiveNotifier.exec(token: "your-webhook-token", message: "your-message")
44
32
  ```
45
33
 
46
- ### Use custom template
34
+ Is it too much trouble to set the token and message always? You can save commonly used ones and access them via better ways.
35
+ For token, ActiveNotifier use channel_tokens to store it, and for message, we can use the ERB template and locals data, like the familiar ActiveView does.
47
36
 
48
- Set token and template home for Rails application
49
37
 
50
38
  ```ruby
51
39
  ActiveNotifier.configure do |config|
52
- config.channel_tokens = { default: "xxx" }
40
+ config.channel_tokens = { my_channel: "xxx" }
53
41
  config.template_home = Rails.root.join("app", "views", "active_notifier")
54
42
  end
55
43
  ```
56
44
 
57
- Set the default message template
58
-
59
- > app/views/active_notifier/default.markdown.erb
60
-
61
- ```erb
62
- ## #{data[:title]}
63
- > #{data[:message]}
45
+ ```shell
46
+ echo "## #{data[:title]\n> #{data[:body]}}" > app/views/active_notifier/my_channel.markdown.erb
64
47
  ```
65
48
 
66
- Notify message
67
-
68
49
  ```ruby
69
- ActiveNotifier.exec(:default, data: { title: "Title", message: "Message" }) # => Notifer OK
50
+ ActiveNotifier.exec(token_channel: :my_channel, template: :my_channel, data: { title: "Message Title", body: "Message Body" })
70
51
  ```
71
52
 
72
- ### Send message with dynamic type
73
-
74
- Message type will dynamic set according by valid template files, when we
75
- set a template named `order.text.erb`
53
+ Also when token_channel and template is the same, we can simplify it by using the first optional argument channel
76
54
 
77
55
  ```ruby
78
- ActiveNotifier.configure do |config|
79
- config.channel_tokens = { order: "xxx" }
80
- config.template_home = Rails.root.join("app", "views", "active_notifier")
56
+ ActiveNotifier.exec(:my_channel, data: { title: "Message Title", body: "Message Body" })
81
57
  ```
82
58
 
83
- > app/views/active_notifier/order.text.erb
59
+ ## Advanced knowledge
84
60
 
85
- ```erb
86
- title: #{data[:title]}
87
- message: #{data[:message]}
88
- ```
61
+ ### Send message with dynamic type
89
62
 
90
- When there is only text type template for order, it will be OK the
91
- notify message without set type option
63
+ Message type will dynamic set according to a valid template, imagine we have two template files named `order.text.erb` and `order.markdown.erb`,
64
+ now we want use the text type of template, we need add a type option
92
65
 
93
66
  ```ruby
94
- ActiveNotifier.exec(:default, data: { title: "Title", message: "Message" }) # => Notifer message OK
67
+ ActiveNotifier.exec(:order, data: { title: "Message Title", body: "Message Body" }, type: :text)
95
68
  ```
96
69
 
97
- Also, even though there are multiple types templates, like both `order.text.erb` and `order.markdown.erb`
98
- are exist, we still can make it OK which no need for type option, just
99
- set the priority type
70
+ But if there is only one type of template, the type option is optional
100
71
 
101
- > app/views/active_notifier/order.text.erb
72
+ ```ruby
73
+ # Now we have only template file `product.text.erb` for product channel
102
74
 
103
- ```erb
104
- title: #{data[:title]}
105
- message: #{data[:message]}
75
+ ActiveNotifier.exec(:product, data: { title: "Message Title", body: "Message Body" }) # Needn't type option
106
76
  ```
107
77
 
108
- > app/views/active_notifier/order.markdown.erb
78
+ And also we can configure priority type for ActiveNotifier
109
79
 
110
- ```erb
111
- ## #{data[:title]}
112
- > #{data[:message]}
80
+ ```ruby
81
+ ActiveNotifier.configure do |config|
82
+ # default is :markdown
83
+ config.priority_type = :text
84
+ end
113
85
  ```
114
86
 
115
87
  ```ruby
116
- # default priority_type is :markdown
117
- ActiveNotifer.config.priority_type = :text
88
+ # Now even we have template files `book.text.erb` and `book.markdown.erb` for book channel
118
89
 
119
- # Now this will choose text by default
120
- ActiveNotifier.exec(:default, data: { title: "Title", message: "Message" }) # => Notifer message OK by text type template
90
+ ActiveNotifier.exec(:book, data: { title: "Message Title", body: "Message Body" }) # Needn't type option, and will choose the text type
121
91
  ```
122
92
 
123
- ### Set a short constant to notify(Rails initializer will set this by default)
93
+ ### Set a short constant
94
+
95
+ ActiveSupport hook `after_initialize` will set this by default
124
96
 
125
97
  ```ruby
126
98
  ActiveNotifer.config.const_name = :Notifier
127
99
  Notifer.exec(...)
128
100
  ```
129
101
 
130
- ### Other
102
+ ## Help and Docs
131
103
 
132
- See complete abilities of ActiveNotifier, please follow [Spec files](https://github.com/pinewong/active_notifier/blob/master/spec/active_adapter_spec.rb)
104
+ * [More Examples](https://github.com/pinewong/active_notifier/blob/master/spec/active_notifier_spec.rb)
105
+ * [RDoc](https://www.rubydoc.info/github/pinewong/active_notifier)
106
+ * [Gem RDoc](http://www.rubydoc.info/gems/active_notifier/0.3.0)
133
107
 
134
108
  ## Development
135
109
 
@@ -34,6 +34,7 @@ Gem::Specification.new do |spec|
34
34
 
35
35
  spec.add_development_dependency "bundler", "~> 1.16"
36
36
  spec.add_development_dependency "byebug"
37
+ spec.add_development_dependency "codecov", ">= 0.1.10"
37
38
  spec.add_development_dependency "rake", "~> 10.0"
38
39
  spec.add_development_dependency "rspec", "~> 3.7"
39
40
  spec.add_development_dependency "rubocop", "~> 0.58.1"
@@ -7,15 +7,16 @@ module ActiveNotifier
7
7
  end
8
8
 
9
9
  # Notify message
10
+ #
10
11
  # @abstract Implement through setting a real adapter, like :dingtalk
11
12
  # @param token [String] Channel webhook token
12
13
  # @param type [Symbol] Message type
13
14
  # @param message [String] Message body
14
- # @param options [Hash] ({}) Adapter message options,
15
- # some adapters require some another options
15
+ # @param options [Hash] Adapter message options, some adapters require some another options
16
16
  # @raise [AdapterOptionsInvalidError]
17
17
  # @raise [AdapterTypeInvalidError]
18
18
  # @raise [MessageBlankError]
19
+ # @see ActiveNotitifier::exec for usage
19
20
  def notify(token, type, message, **options)
20
21
  adapter.notify(token, type, message, **options)
21
22
  end
@@ -2,14 +2,15 @@ module ActiveNotifier
2
2
  class DingtalkAdapter
3
3
  VALID_TYPES = %i[markdown].freeze
4
4
 
5
+ # (see AbstractAdapter#notify)
5
6
  def notify(token, type, message, **options)
6
7
  webhook = "#{ActiveNotifier.config.adapters_with_base_url.fetch(:dingtalk)}#{token}"
7
8
  unless VALID_TYPES.include?(type)
8
- error_message = "适配器 type 暂时只支持:#{VALID_TYPES.join(', ')}"
9
+ error_message = "The Dingtalk adapter only support types: #{VALID_TYPES.join(', ')}"
9
10
  raise ActiveNotifier::AdapterTypeInvalidError, error_message
10
11
  end
11
12
  raise ActiveNotifier::MessageBlankError, "message can't be blank, please check template file" if message.empty?
12
- title = options[:title].to_s
13
+ title = options[:title]&.to_s
13
14
  raise ActiveNotifier::AdapterOptionsInvalidError, "Dingtalk adapter require other options: title" if title.empty?
14
15
 
15
16
  body = {
@@ -3,15 +3,16 @@ module ActiveNotifier
3
3
  extend ActiveSupport::Concern
4
4
 
5
5
  module ClassMethods
6
- # Configure for ActiveNotifier
7
- # @yield [config] Give a Configuration instance for settings
8
- # @raise [ConfigureError]
6
+ # Configure for ActiveNotifier.
7
+ #
9
8
  # @example
10
9
  # ActiveNotifier.configure do |config|
11
10
  # config.const_name = :Message
12
11
  # config.adapter = :slack
13
12
  # # ...
14
13
  # end
14
+ # @yield [config] Give a Configuration instance for settings
15
+ # @raise [ConfigureError]
15
16
  def configure
16
17
  yield config
17
18
  end
@@ -3,59 +3,77 @@ module ActiveNotifier
3
3
  extend ActiveSupport::Concern
4
4
 
5
5
  module ClassMethods
6
- # Message execute
7
- # @param channel [#to_sym] Message channel, it will set template and token together
8
- # @param options [Hash] ({})
9
- # @option options [String] :template (nil) Message template, will use `options[:channel]` when this value is blank
10
- # @option options [String, Symbol] :token (nil) Message webhook token,
11
- # will use `options[:channel]` when this value is blank
12
- # @option options [Symbol] :type (nil) Message type, it will use a specific template file, for example,
13
- # when type is :text and template is order, then ActiveNotifier will choose `order.text.erb` for template file
14
- # @option options [Hash] :data ({}) Message variable data for template, it can used in erb template file:
15
- # ## #{data[:title]}
16
- # > #{data[:order].to_json}
17
- # @option options [Anything] Other options will used in adapter message execute,
18
- # like Dingtalk require title for message, we can pass it here:
19
- # `ActiveNotifer.exec(:default, title: "dingtalk title")`
6
+ # Message execute.
7
+ #
8
+ # @example Command Usage
9
+ # ActiveNotifier.exec(token: "your-webhook-token", message: "your-message")
10
+ # @example Common Usage
11
+ # # Configure it
12
+ # ActiveNotifier.configure do |config|
13
+ # config.channel_tokens = { my_channel: "xxx" }
14
+ # config.template_home = Rails.root.join("app", "views", "active_notifier")
15
+ # end
16
+ #
17
+ # # Add template
18
+ # echo "## #{data[:title]\n> #{data[:body]}}" > app/views/active_notifier/my_channel.markdown.erb
19
+ #
20
+ # # Execute it
21
+ # ActiveNotifier.exec(:my_channel, data: { title: "Message Title", body: "Message Body" })
22
+ # @param channel [#to_sym] (nil) Message channel, it will set template and token_channel together
23
+ # @param options [#to_h] ({})
24
+ # @option options [#to_s] :token (nil) Message webhook token,
25
+ # @option options [#to_s] :message (nil) Message
26
+ # @option options [#to_sym] :token_channel (nil) Message webhook token channel,
27
+ # will use `channel` when this value is blank
28
+ # @option options [#to_sym] :template (nil) Message template, will use `channel` when this value is blank
29
+ # @option options [#to_sym] :adapter (ActiveNotifier.config.adapter) Message adapter
30
+ # @option options [#to_sym] :type (nil) Message type, it will use a specific template file, for example,
31
+ # when type is :text and template is :order, then ActiveNotifier will choose `order.text.erb` for template file
32
+ # @option options [#to_h] :data ({}) Message variable data for template, it can used in erb template file
33
+ # @option options [Anything] Other options will used in adapter message execute, like Dingtalk require title
34
+ # for message, we can pass it here: `ActiveNotifer.exec(:default, title: "dingtalk title")`
20
35
  # @raise [TemplateNotFoundError]
21
36
  # @raise [UndefinedTokenError]
22
37
  # @raise [AdapterOptionsInvalidError]
23
38
  # @raise [AdapterTypeInvalidError]
24
39
  # @raise [MessageBlankError]
25
- # @example
26
- # ActiveNotifer.config.channel_tokens = {
27
- # default: "xxx"
28
- # }
29
- # ActiveNotifier.exec(:default)
30
- def exec(channel, **options)
31
- channel = channel&.to_sym
32
- raise ArgumentError, ":channel can't be blank" if channel.blank?
33
- template = options[:template].to_s.presence || channel.to_s
34
- token = get_token(channel, options[:token])
35
- raise UndefinedTokenError if token.blank?
36
- type = options[:type]&.to_sym.presence || guess_type_by_files(template)
37
- data = options[:data].to_h
38
-
39
- message = get_message(template, type, data)
40
- adapter = ActiveNotifier.adapt(ActiveNotifier.config.adapter)
41
- adapter_options = options.except(:token, :template, :type, :data)
42
- adapter.notify(token, type, message, adapter_options)
40
+ # @see Get more see README
41
+ def exec(channel = nil, **options)
42
+ channel = channel&.to_sym
43
+ token = options[:token]&.to_s
44
+ message = options[:message]&.to_s
45
+ token_channel = options[:token_channel]&.to_sym
46
+ template = options[:template]&.to_sym
47
+ adapter = options[:adapter]&.to_sym
48
+ type = options[:type]&.to_sym
49
+ data = options[:data].to_h
50
+ token = fetch_token(token, token_channel, channel)
51
+ template ||= channel
52
+ type ||= get_type_by_template(template)
53
+ message ||= get_message(template, type, data)
54
+ adapter_options = options.except(:token, :message, :token_channel, :template, :adapter, :type, :data)
55
+ adapter ||= ActiveNotifier.config.adapter.to_sym
56
+ ActiveNotifier.adapt(adapter).notify(token, type, message, adapter_options)
43
57
  end
44
58
 
45
59
  private
46
60
 
47
- def get_token(channel, options_token)
48
- case options_token
49
- when String
50
- options_token
51
- when Symbol
52
- ActiveNotifier.config.channel_tokens[options_token]
53
- else
54
- ActiveNotifier.config.channel_tokens[channel]
55
- end
61
+ # @param token [String, nil]
62
+ # @param token_channel [Symbol, nil]
63
+ # @param channel [Symbol, nil]
64
+ # @return [String]
65
+ def fetch_token(token, token_channel, channel)
66
+ token = token ||
67
+ token_channel && ActiveNotifier.config.channel_tokens[token_channel]&.to_s ||
68
+ channel && ActiveNotifier.config.channel_tokens[channel]&.to_s
69
+ raise ActiveNotifier::UndefinedTokenError unless token
70
+ token
56
71
  end
57
72
 
58
- def guess_type_by_files(template)
73
+ # @param template [Symbol, nil]
74
+ # @return [Symbol, nil]
75
+ def get_type_by_template(template)
76
+ return unless template
59
77
  template_paths = Dir["#{ActiveNotifier.config.template_home}/#{template}.*.erb"]
60
78
  raise ActiveNotifier::TemplateNotFoundError if template_paths.empty?
61
79
  types = template_paths.map do |template_path|
@@ -68,7 +86,12 @@ module ActiveNotifier
68
86
  end
69
87
  end
70
88
 
89
+ # @param template [Symbol, nil]
90
+ # @param type [Symbol]
91
+ # @param data [Hash]
92
+ # @return [String, nil]
71
93
  def get_message(template, type, data)
94
+ return unless template
72
95
  template_data = File.read("#{ActiveNotifier.config.template_home}/#{template}.#{type}.erb")
73
96
  ERB.new(template_data).result_with_hash(data: data)
74
97
  rescue Errno::ENOENT => e
@@ -1 +1 @@
1
- <%= data %>
1
+ > <%= data %>
@@ -0,0 +1 @@
1
+ <%= data %>
@@ -1,3 +1,3 @@
1
1
  module ActiveNotifier
2
- VERSION = "0.2.0".freeze
2
+ VERSION = "0.3.0".freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_notifier
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pine Wong
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-07-24 00:00:00.000000000 Z
11
+ date: 2018-07-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: codecov
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 0.1.10
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: 0.1.10
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: rake
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -151,6 +165,7 @@ extra_rdoc_files: []
151
165
  files:
152
166
  - ".gitignore"
153
167
  - ".rubocop.yml"
168
+ - ".travis.yml"
154
169
  - CODE_OF_CONDUCT.md
155
170
  - Gemfile
156
171
  - README.md
@@ -166,6 +181,7 @@ files:
166
181
  - lib/active_notifier/core.rb
167
182
  - lib/active_notifier/errors.rb
168
183
  - lib/active_notifier/templates/default.markdown.erb
184
+ - lib/active_notifier/templates/default.text.erb
169
185
  - lib/active_notifier/version.rb
170
186
  homepage: https://github.com/pinewong/active_notifier
171
187
  licenses: []
@@ -186,7 +202,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
186
202
  version: '0'
187
203
  requirements: []
188
204
  rubyforge_project:
189
- rubygems_version: 2.7.6
205
+ rubygems_version: 2.7.7
190
206
  signing_key:
191
207
  specification_version: 4
192
208
  summary: Notify message through webhooks.