active_notifier 0.1.0.pre → 0.1.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 +4 -4
- data/README.md +2 -2
- data/bin/console +1 -0
- data/lib/active_notifier.rb +2 -3
- data/lib/active_notifier/adaptable.rb +0 -1
- data/lib/active_notifier/adapters/abstract_adapter.rb +2 -2
- data/lib/active_notifier/adapters/dingtalk_adapter.rb +11 -27
- data/lib/active_notifier/configurable.rb +16 -36
- data/lib/active_notifier/core.rb +22 -17
- data/lib/active_notifier/errors.rb +3 -6
- data/lib/active_notifier/templates/default.markdown.erb +1 -1
- data/lib/active_notifier/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bbb1a3370063f78b39543cb4d5fc05d8acea444503c2f230f9bfd2d19abdd979
|
4
|
+
data.tar.gz: 81999de8ce52f5cee7ec78f6fadbab107b9ca74fdceef9d34eaee7dc70074867
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 885d46d316433753c76d29c8be098b1f1b8d9c67da748fc0122ce1d54253ad76aaa4b0be76a4f13efe56286ea1284637ca47ed773f58cfcb3cfc9dde1ca87f7f
|
7
|
+
data.tar.gz: d98d5c3cf396d0e8d71fdf29c5121d2fda78e029a3fdfa80a5d9a59935e8274e9a04de877da0ad9d2302999f0dbb2abc012e9f7144fa88e038e6ed93eb3a0992
|
data/README.md
CHANGED
@@ -32,8 +32,8 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
32
32
|
|
33
33
|
## Contributing
|
34
34
|
|
35
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
35
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/pinewong/active_notifier. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
36
36
|
|
37
37
|
## Code of Conduct
|
38
38
|
|
39
|
-
Everyone interacting in the ActiveNotifier project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/
|
39
|
+
Everyone interacting in the ActiveNotifier project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/pinewong/active_notifier/blob/master/CODE_OF_CONDUCT.md).
|
data/bin/console
CHANGED
data/lib/active_notifier.rb
CHANGED
@@ -14,11 +14,10 @@ module ActiveNotifier
|
|
14
14
|
autoload :Error
|
15
15
|
autoload :ConfigureError
|
16
16
|
autoload :TemplateNotFoundError
|
17
|
-
autoload :ChannelUndefinedError
|
18
17
|
autoload :MessageBlankError
|
19
|
-
autoload :AdapterWebhookInvalidError
|
20
18
|
autoload :AdapterTypeInvalidError
|
21
19
|
autoload :AdapterOptionsInvalidError
|
20
|
+
autoload :UndefinedTokenError
|
22
21
|
end
|
23
22
|
end
|
24
23
|
|
@@ -32,6 +31,6 @@ module ActiveNotifier
|
|
32
31
|
include Adaptable
|
33
32
|
|
34
33
|
ActiveSupport.on_load(:after_initialize) do
|
35
|
-
Kernel.const_set(ActiveNotifier.config.const_name, ActiveNotifier)
|
34
|
+
Kernel.const_set(ActiveNotifier.config.const_name || :Notifier, ActiveNotifier)
|
36
35
|
end
|
37
36
|
end
|
@@ -6,8 +6,8 @@ module ActiveNotifier
|
|
6
6
|
@adapter = adapter_class.new
|
7
7
|
end
|
8
8
|
|
9
|
-
def notify(
|
10
|
-
adapter.notify(
|
9
|
+
def notify(token, type, message, **options)
|
10
|
+
adapter.notify(token, type, message, **options)
|
11
11
|
end
|
12
12
|
end
|
13
13
|
end
|
@@ -1,15 +1,21 @@
|
|
1
1
|
module ActiveNotifier
|
2
2
|
class DingtalkAdapter
|
3
|
-
VALID_WEBHOOK_HOSTS = %w[oapi.dingtalk.com].freeze
|
4
3
|
VALID_TYPES = %i[markdown].freeze
|
5
|
-
delegate :abstract_adapter, to: :class
|
6
4
|
|
7
|
-
def notify(
|
8
|
-
webhook
|
5
|
+
def notify(token, type, message, **options)
|
6
|
+
webhook = "#{ActiveNotifier.config.adapters_with_base_url.fetch(:dingtalk)}#{token}"
|
7
|
+
unless VALID_TYPES.include?(type)
|
8
|
+
error_message = "适配器 type 暂时只支持:#{VALID_TYPES.join(', ')}"
|
9
|
+
raise ActiveNotifier::AdapterTypeInvalidError, error_message
|
10
|
+
end
|
11
|
+
raise ActiveNotifier::MessageBlankError, "消息不能为空, 请检查 template 模板" if message.empty?
|
12
|
+
title = options[:title].to_s
|
13
|
+
raise ActiveNotifier::AdapterOptionsInvalidError, "钉钉适配器还需提供必须值:title" if title.empty?
|
14
|
+
|
9
15
|
body = {
|
10
16
|
'msgtype' => type,
|
11
17
|
type => {
|
12
|
-
'title':
|
18
|
+
'title': title,
|
13
19
|
'text': message
|
14
20
|
}
|
15
21
|
}
|
@@ -19,27 +25,5 @@ module ActiveNotifier
|
|
19
25
|
}
|
20
26
|
Net::HTTP.post(URI(webhook), body.to_json, headers)
|
21
27
|
end
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
def process_args(webhook, type, message, options)
|
26
|
-
if VALID_WEBHOOK_HOSTS.none? { |valid_host| webhook.include?(valid_host) }
|
27
|
-
error_message = "适配器 host 暂时只支持:#{VALID_WEBHOOK_HOSTS.join(', ')}, 如果第三方 API 新增或改变,请联系维护者"
|
28
|
-
raise ActiveNotifier::AdapterWebhookInvalidError, error_message
|
29
|
-
end
|
30
|
-
unless VALID_TYPES.include?(type)
|
31
|
-
error_message = "适配器 type 暂时只支持:#{VALID_TYPES.join(', ')}"
|
32
|
-
raise ActiveNotifier::AdapterTypeInvalidError, error_message
|
33
|
-
end
|
34
|
-
raise ActiveNotifier::MessageBlankError, "消息不能为空, 请检查 template 模板" if message.empty?
|
35
|
-
options[:title] = options[:title].to_s
|
36
|
-
raise ActiveNotifier::AdapterOptionsInvalidError, "适配器选项必须值:title" if options[:title].empty?
|
37
|
-
|
38
|
-
[webhook, type, message, options]
|
39
|
-
end
|
40
|
-
|
41
|
-
class << self
|
42
|
-
attr_accessor :abstract_adapter
|
43
|
-
end
|
44
28
|
end
|
45
29
|
end
|
@@ -16,16 +16,12 @@ module ActiveNotifier
|
|
16
16
|
|
17
17
|
class Configuration
|
18
18
|
# 常量名, 简化调用, 符号,默认 :Notifier (如果被占用请更换)
|
19
|
-
|
20
|
-
@const_name || :Notifier
|
21
|
-
end
|
19
|
+
attr_reader :const_name
|
22
20
|
|
23
21
|
def const_name=(const_name)
|
24
22
|
const_name = const_name.to_sym
|
25
23
|
const_name = "Notifier" if const_name.empty?
|
26
|
-
if Kernel.const_defined?(const_name)
|
27
|
-
raise ActiveNotifier::ConfigureError, "const_name 已经存在,请在 initializers 中定义其他值"
|
28
|
-
end
|
24
|
+
raise ActiveNotifier::ConfigureError, "const_name 已经存在,请配置其他值" if Kernel.const_defined?(const_name)
|
29
25
|
Kernel.const_set(const_name, ActiveNotifier)
|
30
26
|
@const_name = const_name
|
31
27
|
end
|
@@ -37,28 +33,25 @@ module ActiveNotifier
|
|
37
33
|
|
38
34
|
def adapter=(adapter)
|
39
35
|
adapter = adapter.to_sym
|
40
|
-
unless
|
41
|
-
raise ActiveNotifier::ConfigureError, "adapter 当前只支持:#{
|
36
|
+
unless adapters_with_base_url.key?(adapter)
|
37
|
+
raise ActiveNotifier::ConfigureError, "adapter 当前只支持:#{adapters_with_base_url.keys.join(', ')}"
|
42
38
|
end
|
43
39
|
@adapter = adapter
|
44
40
|
end
|
45
41
|
|
46
|
-
# 消息渠道的
|
47
|
-
def
|
48
|
-
@
|
42
|
+
# 消息渠道的 channel_tokens 设置
|
43
|
+
def channel_tokens
|
44
|
+
@channel_tokens || {}
|
49
45
|
end
|
50
46
|
|
51
|
-
def
|
52
|
-
|
53
|
-
|
54
|
-
raise ActiveNotifier::ConfigureError, "channel_webhooks 请至少设置 default 键"
|
55
|
-
end
|
56
|
-
@channel_webhooks = channel_webhooks
|
47
|
+
def channel_tokens=(channel_tokens)
|
48
|
+
channel_tokens = channel_tokens.to_h.symbolize_keys
|
49
|
+
@channel_tokens = channel_tokens
|
57
50
|
end
|
58
51
|
|
59
52
|
# 消息模版主目录, 字符串, 默认 views/notifier/application), 不需要加模版后缀
|
60
53
|
def template_home
|
61
|
-
@template_home || "#{__dir__}/templates"
|
54
|
+
@template_home || "#{File.expand_path(__dir__)}/templates"
|
62
55
|
end
|
63
56
|
|
64
57
|
def template_home=(template_home)
|
@@ -67,17 +60,6 @@ module ActiveNotifier
|
|
67
60
|
@template_home = template_home
|
68
61
|
end
|
69
62
|
|
70
|
-
# 消息模版, 字符串, 默认 default($template_home/default), 不需要加模版后缀
|
71
|
-
def template
|
72
|
-
@template || "default"
|
73
|
-
end
|
74
|
-
|
75
|
-
def template=(template)
|
76
|
-
template = template.to_s
|
77
|
-
raise ActiveNotifier::ConfigureError, "模板名不能为空" if template.empty?
|
78
|
-
@template = template
|
79
|
-
end
|
80
|
-
|
81
63
|
# 消息优先类型, 字符串, 默认 :markdown, 对应模板后缀名,如果未指定该参数且存在多个模板,则优先选择此类型
|
82
64
|
def priority_type
|
83
65
|
@priority_type || :markdown
|
@@ -87,13 +69,11 @@ module ActiveNotifier
|
|
87
69
|
@priority_type = priority_type.to_sym
|
88
70
|
end
|
89
71
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
found_adapters.map { |adapter| adapter.sub("_adapter.rb", "").to_sym } - [:abstract]
|
96
|
-
end
|
72
|
+
# 适配器以及基本连接
|
73
|
+
def adapters_with_base_url
|
74
|
+
@adapters_with_base_url ||= {
|
75
|
+
dingtalk: "https://oapi.dingtalk.com/robot/send?access_token="
|
76
|
+
}
|
97
77
|
end
|
98
78
|
end
|
99
79
|
end
|
data/lib/active_notifier/core.rb
CHANGED
@@ -6,35 +6,40 @@ module ActiveNotifier
|
|
6
6
|
|
7
7
|
module ClassMethods
|
8
8
|
# Params:
|
9
|
+
# channel: 消息渠道, 符号,
|
10
|
+
# 例如设置为 :order, 则使用 channel_tokens[:order] 和 order.markdown.erb 模板发送消息
|
9
11
|
# options:
|
10
|
-
#
|
11
|
-
#
|
12
|
-
# type: 消息类型, 符号, 默认 :
|
12
|
+
# template: 消息模版, 字符串, 默认 "default", 不需要加模版后缀
|
13
|
+
# token: webhook token, 类型符号则取 chanenl_tokens[:symbol] 值,类型字符串则使用原值
|
14
|
+
# type: 消息类型, 符号, 默认 :markdown, 对应模板后缀名
|
13
15
|
# data: 传递数据, Hash, 默认 {}
|
14
16
|
# 其他键的值会被当成适配器选项值,直接传到适配器中处理
|
15
|
-
def exec(**options)
|
16
|
-
|
17
|
-
|
18
|
-
|
17
|
+
def exec(channel, **options)
|
18
|
+
channel = channel&.to_sym
|
19
|
+
raise ArgumentError, "Channel 不能为空" if channel.blank?
|
20
|
+
template = options[:template].to_s.presence || channel.to_s
|
21
|
+
token = get_token(channel, options[:token])
|
22
|
+
raise UndefinedTokenError, "Token 值未定义" if token.blank?
|
23
|
+
type = options[:type]&.to_sym.presence || guess_type_by_files(template)
|
19
24
|
data = options[:data].to_h
|
20
25
|
|
21
26
|
message = get_message(template, type, data)
|
22
27
|
adapter = ActiveNotifier.adapt(ActiveNotifier.config.adapter)
|
23
|
-
adapter_options = options.except(:
|
24
|
-
adapter.notify(
|
28
|
+
adapter_options = options.except(:token, :template, :type, :data)
|
29
|
+
adapter.notify(token, type, message, adapter_options)
|
25
30
|
end
|
26
31
|
|
27
32
|
private
|
28
33
|
|
29
|
-
def
|
30
|
-
|
31
|
-
|
34
|
+
def get_token(channel, options_token)
|
35
|
+
case options_token
|
36
|
+
when String
|
37
|
+
options_token
|
38
|
+
when Symbol
|
39
|
+
ActiveNotifier.config.channel_tokens[options_token]
|
40
|
+
else
|
41
|
+
ActiveNotifier.config.channel_tokens[channel]
|
32
42
|
end
|
33
|
-
channel = channel&.to_sym
|
34
|
-
return ActiveNotifier.config.channel_webhooks[:default] unless channel
|
35
|
-
error_message = "使用 #{channel} 前,请先在 initializers 中定义"
|
36
|
-
raise ChannelUndefinedError, error_message unless ActiveNotifier.config.channel_webhooks.key?(channel)
|
37
|
-
ActiveNotifier.config.channel_webhooks[channel]
|
38
43
|
end
|
39
44
|
|
40
45
|
def guess_type_by_files(template)
|
@@ -8,18 +8,15 @@ module ActiveNotifier
|
|
8
8
|
# 模板未找到
|
9
9
|
class TemplateNotFoundError < Error; end
|
10
10
|
|
11
|
-
# 使用未定义 channel
|
12
|
-
class ChannelUndefinedError < Error; end
|
13
|
-
|
14
11
|
# 消息为空
|
15
12
|
class MessageBlankError < Error; end
|
16
13
|
|
17
|
-
# 适配器 webhook 无效
|
18
|
-
class AdapterWebhookInvalidError < Error; end
|
19
|
-
|
20
14
|
# 适配器 type 无效
|
21
15
|
class AdapterTypeInvalidError < Error; end
|
22
16
|
|
23
17
|
# 适配器 options 无效
|
24
18
|
class AdapterOptionsInvalidError < Error; end
|
19
|
+
|
20
|
+
# Token 未定义
|
21
|
+
class UndefinedTokenError < Error; end
|
25
22
|
end
|
@@ -1 +1 @@
|
|
1
|
-
<%= data
|
1
|
+
<%= data %>
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_notifier
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pine Wong
|
@@ -181,9 +181,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
181
181
|
version: '0'
|
182
182
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
183
183
|
requirements:
|
184
|
-
- - "
|
184
|
+
- - ">="
|
185
185
|
- !ruby/object:Gem::Version
|
186
|
-
version:
|
186
|
+
version: '0'
|
187
187
|
requirements: []
|
188
188
|
rubyforge_project:
|
189
189
|
rubygems_version: 2.7.6
|