active_notifier 0.1.0.pre → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|