active_notifier 0.1.0.pre
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 +7 -0
- data/.gitignore +11 -0
- data/.rubocop.yml +28 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/README.md +39 -0
- data/Rakefile +2 -0
- data/active_notifier.gemspec +43 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/active_notifier/adaptable.rb +31 -0
- data/lib/active_notifier/adapters/abstract_adapter.rb +13 -0
- data/lib/active_notifier/adapters/dingtalk_adapter.rb +45 -0
- data/lib/active_notifier/configurable.rb +100 -0
- data/lib/active_notifier/core.rb +61 -0
- data/lib/active_notifier/errors.rb +25 -0
- data/lib/active_notifier/templates/default.markdown.erb +1 -0
- data/lib/active_notifier/version.rb +3 -0
- data/lib/active_notifier.rb +37 -0
- metadata +193 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 99ed29b22b337b7a33b7d90f08a2a59cbb1b281ee1c3f2245d241ac3e1148d7a
|
4
|
+
data.tar.gz: c65c631aba93cf5f449db75c1b23e207847af6d8fcb5777750ec445be986f2af
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 899b5bf5ee71a079e64e570d3c9a7ba0c7b4293a165253a5ad4c582bedec3725ba6e571c5b6e8dd46852573f4682b07355737bad76084dd7117441cd8e78623d
|
7
|
+
data.tar.gz: b8ce6d62b6f320363c010a52217d7506cf449f577b462003c0275ca82283e02a2919f2ccef3905375743e20d29e3cc1695e50c8707b82a27408be589a519f042
|
data/.gitignore
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: 2.3
|
3
|
+
Exclude:
|
4
|
+
- 'bin/*'
|
5
|
+
Metrics/LineLength:
|
6
|
+
Max: 120
|
7
|
+
Style/AsciiComments:
|
8
|
+
Enabled: false
|
9
|
+
Style/FrozenStringLiteralComment:
|
10
|
+
Enabled: false
|
11
|
+
Style/Documentation:
|
12
|
+
Enabled: false
|
13
|
+
Style/BlockComments:
|
14
|
+
Enabled: false
|
15
|
+
Metrics/MethodLength:
|
16
|
+
Max: 30
|
17
|
+
Metrics/AbcSize:
|
18
|
+
Max: 30
|
19
|
+
Style/StringLiterals:
|
20
|
+
Enabled: false
|
21
|
+
Style/BlockDelimiters:
|
22
|
+
Enabled: false
|
23
|
+
Metrics/ModuleLength:
|
24
|
+
Exclude:
|
25
|
+
- "**/*_spec.rb"
|
26
|
+
Metrics/BlockLength:
|
27
|
+
Exclude:
|
28
|
+
- "**/*_spec.rb"
|
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
2
|
+
|
3
|
+
## Our Pledge
|
4
|
+
|
5
|
+
In the interest of fostering an open and welcoming environment, we as
|
6
|
+
contributors and maintainers pledge to making participation in our project and
|
7
|
+
our community a harassment-free experience for everyone, regardless of age, body
|
8
|
+
size, disability, ethnicity, gender identity and expression, level of experience,
|
9
|
+
nationality, personal appearance, race, religion, or sexual identity and
|
10
|
+
orientation.
|
11
|
+
|
12
|
+
## Our Standards
|
13
|
+
|
14
|
+
Examples of behavior that contributes to creating a positive environment
|
15
|
+
include:
|
16
|
+
|
17
|
+
* Using welcoming and inclusive language
|
18
|
+
* Being respectful of differing viewpoints and experiences
|
19
|
+
* Gracefully accepting constructive criticism
|
20
|
+
* Focusing on what is best for the community
|
21
|
+
* Showing empathy towards other community members
|
22
|
+
|
23
|
+
Examples of unacceptable behavior by participants include:
|
24
|
+
|
25
|
+
* The use of sexualized language or imagery and unwelcome sexual attention or
|
26
|
+
advances
|
27
|
+
* Trolling, insulting/derogatory comments, and personal or political attacks
|
28
|
+
* Public or private harassment
|
29
|
+
* Publishing others' private information, such as a physical or electronic
|
30
|
+
address, without explicit permission
|
31
|
+
* Other conduct which could reasonably be considered inappropriate in a
|
32
|
+
professional setting
|
33
|
+
|
34
|
+
## Our Responsibilities
|
35
|
+
|
36
|
+
Project maintainers are responsible for clarifying the standards of acceptable
|
37
|
+
behavior and are expected to take appropriate and fair corrective action in
|
38
|
+
response to any instances of unacceptable behavior.
|
39
|
+
|
40
|
+
Project maintainers have the right and responsibility to remove, edit, or
|
41
|
+
reject comments, commits, code, wiki edits, issues, and other contributions
|
42
|
+
that are not aligned to this Code of Conduct, or to ban temporarily or
|
43
|
+
permanently any contributor for other behaviors that they deem inappropriate,
|
44
|
+
threatening, offensive, or harmful.
|
45
|
+
|
46
|
+
## Scope
|
47
|
+
|
48
|
+
This Code of Conduct applies both within project spaces and in public spaces
|
49
|
+
when an individual is representing the project or its community. Examples of
|
50
|
+
representing a project or community include using an official project e-mail
|
51
|
+
address, posting via an official social media account, or acting as an appointed
|
52
|
+
representative at an online or offline event. Representation of a project may be
|
53
|
+
further defined and clarified by project maintainers.
|
54
|
+
|
55
|
+
## Enforcement
|
56
|
+
|
57
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
58
|
+
reported by contacting the project team at pinewong@163.com. All
|
59
|
+
complaints will be reviewed and investigated and will result in a response that
|
60
|
+
is deemed necessary and appropriate to the circumstances. The project team is
|
61
|
+
obligated to maintain confidentiality with regard to the reporter of an incident.
|
62
|
+
Further details of specific enforcement policies may be posted separately.
|
63
|
+
|
64
|
+
Project maintainers who do not follow or enforce the Code of Conduct in good
|
65
|
+
faith may face temporary or permanent repercussions as determined by other
|
66
|
+
members of the project's leadership.
|
67
|
+
|
68
|
+
## Attribution
|
69
|
+
|
70
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
71
|
+
available at [http://contributor-covenant.org/version/1/4][version]
|
72
|
+
|
73
|
+
[homepage]: http://contributor-covenant.org
|
74
|
+
[version]: http://contributor-covenant.org/version/1/4/
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# ActiveNotifier
|
2
|
+
|
3
|
+
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/active_notifier`. To experiment with that code, run `bin/console` for an interactive prompt.
|
4
|
+
|
5
|
+
TODO: Delete this and the text above, and describe your gem
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'active_notifier'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install active_notifier
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
TODO: Write usage instructions here
|
26
|
+
|
27
|
+
## Development
|
28
|
+
|
29
|
+
After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
30
|
+
|
31
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
32
|
+
|
33
|
+
## Contributing
|
34
|
+
|
35
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/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
|
+
|
37
|
+
## Code of Conduct
|
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/[USERNAME]/active_notifier/blob/master/CODE_OF_CONDUCT.md).
|
data/Rakefile
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
lib = File.expand_path("lib", __dir__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require "active_notifier/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "active_notifier"
|
7
|
+
spec.version = ActiveNotifier::VERSION
|
8
|
+
spec.authors = ["Pine Wong"]
|
9
|
+
spec.email = ["pinewong@163.com"]
|
10
|
+
|
11
|
+
spec.summary = "Notify message through webhooks."
|
12
|
+
spec.description = "Notify message through webhooks."
|
13
|
+
spec.homepage = "https://github.com/pinewong/active_notifier"
|
14
|
+
|
15
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
16
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
17
|
+
# if spec.respond_to?(:metadata)
|
18
|
+
# spec.metadata["allowed_push_host"] = "Set to 'http://mygemserver.com'"
|
19
|
+
# else
|
20
|
+
# raise "RubyGems 2.0 or newer is required to protect against " \
|
21
|
+
# "public gem pushes."
|
22
|
+
# end
|
23
|
+
|
24
|
+
# Specify which files should be added to the gem when it is released.
|
25
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
26
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
27
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
28
|
+
end
|
29
|
+
spec.bindir = "exe"
|
30
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
31
|
+
spec.require_paths = ["lib"]
|
32
|
+
|
33
|
+
spec.add_dependency "activesupport", "~> 5.0"
|
34
|
+
|
35
|
+
spec.add_development_dependency "bundler", "~> 1.16"
|
36
|
+
spec.add_development_dependency "byebug"
|
37
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
38
|
+
spec.add_development_dependency "rspec", "~> 3.7"
|
39
|
+
spec.add_development_dependency "rubocop", "~> 0.58.1"
|
40
|
+
spec.add_development_dependency "simplecov"
|
41
|
+
spec.add_development_dependency "vcr", "~> 4.0"
|
42
|
+
spec.add_development_dependency "webmock", "~> 3.4", ">= 3.4.2"
|
43
|
+
end
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "active_notifier"
|
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__)
|
data/bin/setup
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
module ActiveNotifier
|
2
|
+
module Adaptable
|
3
|
+
def self.included(base)
|
4
|
+
base.extend ClassMethods
|
5
|
+
end
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
def adapters
|
9
|
+
@adapters ||= {}
|
10
|
+
end
|
11
|
+
|
12
|
+
def adapt(adapter)
|
13
|
+
adapters[adapter.to_sym] ||= begin
|
14
|
+
adapter_class = get_adapter_class(adapter)
|
15
|
+
adapter_class.abstract_adapter = abstract_adapter_class
|
16
|
+
abstract_adapter_class.new(adapter_class)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def get_adapter_class(adapter)
|
23
|
+
"ActiveNotifier::#{adapter.to_s.camelize}Adapter".constantize
|
24
|
+
end
|
25
|
+
|
26
|
+
def abstract_adapter_class
|
27
|
+
"ActiveNotifier::AbstractAdapter".constantize
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module ActiveNotifier
|
2
|
+
class AbstractAdapter
|
3
|
+
attr_reader :adapter
|
4
|
+
|
5
|
+
def initialize(adapter_class)
|
6
|
+
@adapter = adapter_class.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def notify(webhook, type, message, **options)
|
10
|
+
adapter.notify(webhook, type, message, **options)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module ActiveNotifier
|
2
|
+
class DingtalkAdapter
|
3
|
+
VALID_WEBHOOK_HOSTS = %w[oapi.dingtalk.com].freeze
|
4
|
+
VALID_TYPES = %i[markdown].freeze
|
5
|
+
delegate :abstract_adapter, to: :class
|
6
|
+
|
7
|
+
def notify(webhook, type, message, **options)
|
8
|
+
webhook, type, message, options = process_args(webhook, type, message, options)
|
9
|
+
body = {
|
10
|
+
'msgtype' => type,
|
11
|
+
type => {
|
12
|
+
'title': options[:title],
|
13
|
+
'text': message
|
14
|
+
}
|
15
|
+
}
|
16
|
+
headers = {
|
17
|
+
'Content-Type' => 'application/json',
|
18
|
+
'Accept' => 'application/json'
|
19
|
+
}
|
20
|
+
Net::HTTP.post(URI(webhook), body.to_json, headers)
|
21
|
+
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
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
module ActiveNotifier
|
2
|
+
module Configurable
|
3
|
+
def self.included(base)
|
4
|
+
base.extend ClassMethods
|
5
|
+
end
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
def config
|
9
|
+
@config ||= Configuration.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def configure
|
13
|
+
yield config
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Configuration
|
18
|
+
# 常量名, 简化调用, 符号,默认 :Notifier (如果被占用请更换)
|
19
|
+
def const_name
|
20
|
+
@const_name || :Notifier
|
21
|
+
end
|
22
|
+
|
23
|
+
def const_name=(const_name)
|
24
|
+
const_name = const_name.to_sym
|
25
|
+
const_name = "Notifier" if const_name.empty?
|
26
|
+
if Kernel.const_defined?(const_name)
|
27
|
+
raise ActiveNotifier::ConfigureError, "const_name 已经存在,请在 initializers 中定义其他值"
|
28
|
+
end
|
29
|
+
Kernel.const_set(const_name, ActiveNotifier)
|
30
|
+
@const_name = const_name
|
31
|
+
end
|
32
|
+
|
33
|
+
# 消息适配器, 字符串, 默认 :dingtalk
|
34
|
+
def adapter
|
35
|
+
@adapter || :dingtalk
|
36
|
+
end
|
37
|
+
|
38
|
+
def adapter=(adapter)
|
39
|
+
adapter = adapter.to_sym
|
40
|
+
unless valid_adapters.include?(adapter)
|
41
|
+
raise ActiveNotifier::ConfigureError, "adapter 当前只支持:#{valid_adapters.join(', ')}"
|
42
|
+
end
|
43
|
+
@adapter = adapter
|
44
|
+
end
|
45
|
+
|
46
|
+
# 消息渠道的 webhook 设置
|
47
|
+
def channel_webhooks
|
48
|
+
@channel_webhooks || {}
|
49
|
+
end
|
50
|
+
|
51
|
+
def channel_webhooks=(channel_webhooks)
|
52
|
+
channel_webhooks = channel_webhooks.to_h.symbolize_keys
|
53
|
+
unless channel_webhooks.key?(:default) && channel_webhooks[:default].present?
|
54
|
+
raise ActiveNotifier::ConfigureError, "channel_webhooks 请至少设置 default 键"
|
55
|
+
end
|
56
|
+
@channel_webhooks = channel_webhooks
|
57
|
+
end
|
58
|
+
|
59
|
+
# 消息模版主目录, 字符串, 默认 views/notifier/application), 不需要加模版后缀
|
60
|
+
def template_home
|
61
|
+
@template_home || "#{__dir__}/templates"
|
62
|
+
end
|
63
|
+
|
64
|
+
def template_home=(template_home)
|
65
|
+
template_home = template_home.to_s
|
66
|
+
raise ActiveNotifier::ConfigureError, "模板主目录不能为空" if template_home.empty?
|
67
|
+
@template_home = template_home
|
68
|
+
end
|
69
|
+
|
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
|
+
# 消息优先类型, 字符串, 默认 :markdown, 对应模板后缀名,如果未指定该参数且存在多个模板,则优先选择此类型
|
82
|
+
def priority_type
|
83
|
+
@priority_type || :markdown
|
84
|
+
end
|
85
|
+
|
86
|
+
def priority_type=(priority_type)
|
87
|
+
@priority_type = priority_type.to_sym
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
def valid_adapters
|
93
|
+
@valid_adapters ||= begin
|
94
|
+
found_adapters = Dir["*_adapter.rb", base: "#{__dir__}/adapters"]
|
95
|
+
found_adapters.map { |adapter| adapter.sub("_adapter.rb", "").to_sym } - [:abstract]
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module ActiveNotifier
|
2
|
+
module Core
|
3
|
+
def self.included(base)
|
4
|
+
base.extend ClassMethods
|
5
|
+
end
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
# Params:
|
9
|
+
# options:
|
10
|
+
# channel: 消息渠道, 符号, 默认 :default, 请参照 initializers 中的配置选择
|
11
|
+
# template: 消息模版, 符号, 默认 :application(views/notifier/application), 不需要加模版后缀
|
12
|
+
# type: 消息类型, 符号, 默认 :type, 对应模板后缀名
|
13
|
+
# data: 传递数据, Hash, 默认 {}
|
14
|
+
# 其他键的值会被当成适配器选项值,直接传到适配器中处理
|
15
|
+
def exec(**options)
|
16
|
+
webhook = get_webhook(options[:channel])
|
17
|
+
template = options[:template]&.to_sym || ActiveNotifier.config.template
|
18
|
+
type = options[:type]&.to_sym || guess_type_by_files(template)
|
19
|
+
data = options[:data].to_h
|
20
|
+
|
21
|
+
message = get_message(template, type, data)
|
22
|
+
adapter = ActiveNotifier.adapt(ActiveNotifier.config.adapter)
|
23
|
+
adapter_options = options.except(:channel, :template, :type, :data)
|
24
|
+
adapter.notify(webhook, type, message, adapter_options)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def get_webhook(channel)
|
30
|
+
if ActiveNotifier.config.channel_webhooks.empty?
|
31
|
+
raise ActiveNotifier::ConfigureError, "请在 initializers 中为 channel_webhooks 至少设置 default 键"
|
32
|
+
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
|
+
end
|
39
|
+
|
40
|
+
def guess_type_by_files(template)
|
41
|
+
template_paths = Dir["#{ActiveNotifier.config.template_home}/#{template}.*.erb"]
|
42
|
+
raise ActiveNotifier::TemplateNotFoundError if template_paths.empty?
|
43
|
+
types = template_paths.map do |template_path|
|
44
|
+
template_path[%r{#{ActiveNotifier.config.template_home}/#{template}.([a-zA-Z]+).erb}, 1].to_sym
|
45
|
+
end
|
46
|
+
if types.include?(ActiveNotifier.config.priority_type)
|
47
|
+
ActiveNotifier.config.priority_type
|
48
|
+
else
|
49
|
+
types.first
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def get_message(template, type, data)
|
54
|
+
template_data = File.read("#{ActiveNotifier.config.template_home}/#{template}.#{type}.erb")
|
55
|
+
ERB.new(template_data).result_with_hash(data: data)
|
56
|
+
rescue Errno::ENOENT => e
|
57
|
+
raise ActiveNotifier::TemplateNotFoundError, e
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module ActiveNotifier
|
2
|
+
# 顶级错误
|
3
|
+
class Error < StandardError; end
|
4
|
+
|
5
|
+
# 配置错误
|
6
|
+
class ConfigureError < Error; end
|
7
|
+
|
8
|
+
# 模板未找到
|
9
|
+
class TemplateNotFoundError < Error; end
|
10
|
+
|
11
|
+
# 使用未定义 channel
|
12
|
+
class ChannelUndefinedError < Error; end
|
13
|
+
|
14
|
+
# 消息为空
|
15
|
+
class MessageBlankError < Error; end
|
16
|
+
|
17
|
+
# 适配器 webhook 无效
|
18
|
+
class AdapterWebhookInvalidError < Error; end
|
19
|
+
|
20
|
+
# 适配器 type 无效
|
21
|
+
class AdapterTypeInvalidError < Error; end
|
22
|
+
|
23
|
+
# 适配器 options 无效
|
24
|
+
class AdapterOptionsInvalidError < Error; end
|
25
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= data[:message].presence || "......" %>
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require "active_notifier/version"
|
2
|
+
require "active_support"
|
3
|
+
require "active_support/all"
|
4
|
+
|
5
|
+
module ActiveNotifier
|
6
|
+
extend ActiveSupport::Autoload
|
7
|
+
|
8
|
+
autoload :Configurable
|
9
|
+
autoload :Core
|
10
|
+
autoload :Adaptable
|
11
|
+
|
12
|
+
eager_autoload do
|
13
|
+
autoload_at "active_notifier/errors" do
|
14
|
+
autoload :Error
|
15
|
+
autoload :ConfigureError
|
16
|
+
autoload :TemplateNotFoundError
|
17
|
+
autoload :ChannelUndefinedError
|
18
|
+
autoload :MessageBlankError
|
19
|
+
autoload :AdapterWebhookInvalidError
|
20
|
+
autoload :AdapterTypeInvalidError
|
21
|
+
autoload :AdapterOptionsInvalidError
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
autoload_under "adapters" do
|
26
|
+
autoload :AbstractAdapter
|
27
|
+
autoload :DingtalkAdapter
|
28
|
+
end
|
29
|
+
|
30
|
+
include Configurable
|
31
|
+
include Core
|
32
|
+
include Adaptable
|
33
|
+
|
34
|
+
ActiveSupport.on_load(:after_initialize) do
|
35
|
+
Kernel.const_set(ActiveNotifier.config.const_name, ActiveNotifier)
|
36
|
+
end
|
37
|
+
end
|
metadata
ADDED
@@ -0,0 +1,193 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: active_notifier
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0.pre
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Pine Wong
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-07-23 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '5.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '5.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.16'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.16'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: byebug
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '10.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '10.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.7'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.7'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.58.1
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.58.1
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: simplecov
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: vcr
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '4.0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '4.0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: webmock
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '3.4'
|
132
|
+
- - ">="
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: 3.4.2
|
135
|
+
type: :development
|
136
|
+
prerelease: false
|
137
|
+
version_requirements: !ruby/object:Gem::Requirement
|
138
|
+
requirements:
|
139
|
+
- - "~>"
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '3.4'
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: 3.4.2
|
145
|
+
description: Notify message through webhooks.
|
146
|
+
email:
|
147
|
+
- pinewong@163.com
|
148
|
+
executables: []
|
149
|
+
extensions: []
|
150
|
+
extra_rdoc_files: []
|
151
|
+
files:
|
152
|
+
- ".gitignore"
|
153
|
+
- ".rubocop.yml"
|
154
|
+
- CODE_OF_CONDUCT.md
|
155
|
+
- Gemfile
|
156
|
+
- README.md
|
157
|
+
- Rakefile
|
158
|
+
- active_notifier.gemspec
|
159
|
+
- bin/console
|
160
|
+
- bin/setup
|
161
|
+
- lib/active_notifier.rb
|
162
|
+
- lib/active_notifier/adaptable.rb
|
163
|
+
- lib/active_notifier/adapters/abstract_adapter.rb
|
164
|
+
- lib/active_notifier/adapters/dingtalk_adapter.rb
|
165
|
+
- lib/active_notifier/configurable.rb
|
166
|
+
- lib/active_notifier/core.rb
|
167
|
+
- lib/active_notifier/errors.rb
|
168
|
+
- lib/active_notifier/templates/default.markdown.erb
|
169
|
+
- lib/active_notifier/version.rb
|
170
|
+
homepage: https://github.com/pinewong/active_notifier
|
171
|
+
licenses: []
|
172
|
+
metadata: {}
|
173
|
+
post_install_message:
|
174
|
+
rdoc_options: []
|
175
|
+
require_paths:
|
176
|
+
- lib
|
177
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
178
|
+
requirements:
|
179
|
+
- - ">="
|
180
|
+
- !ruby/object:Gem::Version
|
181
|
+
version: '0'
|
182
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
183
|
+
requirements:
|
184
|
+
- - ">"
|
185
|
+
- !ruby/object:Gem::Version
|
186
|
+
version: 1.3.1
|
187
|
+
requirements: []
|
188
|
+
rubyforge_project:
|
189
|
+
rubygems_version: 2.7.6
|
190
|
+
signing_key:
|
191
|
+
specification_version: 4
|
192
|
+
summary: Notify message through webhooks.
|
193
|
+
test_files: []
|