dingtalk-client 0.1.0 → 0.2.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: d022dedfab5d7f9a0d748cd6b4980d06e31cd6d9da60f4ab7f2ff0f993649251
4
- data.tar.gz: 9cd2078604639e907cf88e3ace74da9d6d263faf4acba459595efaa60d0be3ef
3
+ metadata.gz: 9bfd72745e2e87e8bf338fa656d911879121f390179fd1627241f951c85c8e02
4
+ data.tar.gz: 502532b3b827eb0da21fd3560b679ac1f91f5d27f9beafa664f71810d0745f8b
5
5
  SHA512:
6
- metadata.gz: 3fc278827c664dacbccce92268eebd7bc824ec851bdad1d541b292c3244ed94aa6cd2993919797f58aad75925be78262b989658d4d2fd4b5a44886a0c6d9676a
7
- data.tar.gz: 4cf5370fbe4e8367b7468b822b6d07718696ae2dce42c7dbdc3b098886571fd50b86834a116d9fd1e3447bc42d7ccc890f45af7c48a90f6fd294d23ce5843ee5
6
+ metadata.gz: aa1d0e914f5d267f41e4fbd2d118dbee9ece415a4f886bc32870bf6b91b197a3ce5acfd300f1847204fef74298b4105ce652d52c9897694ed8f8ee0f9c137cb7
7
+ data.tar.gz: 629963615bee02162628f74f85fb85f1b3444e0a2a965d6c6e23506db9050dcb6b617694d9de1ee95191a4d4aae1c871a0ec5c9849b6c0157871d35b1a04dbfc
data/.gitignore CHANGED
@@ -6,3 +6,5 @@
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
9
+ /.ruby-version
10
+ /.byebug_history
@@ -1,8 +1,8 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.3.7
4
- - 2.4.4
5
- - 2.5.1
3
+ - 2.3.8
4
+ - 2.4.5
5
+ - 2.5.3
6
6
  cache: bundler
7
7
  script:
8
8
  - bundle exec rspec
data/Gemfile CHANGED
@@ -11,5 +11,5 @@ gem 'byebug'
11
11
  gem 'codecov', '>= 0.1.10', require: false
12
12
  gem 'rake', '~> 10.0'
13
13
  gem 'rspec', '~> 3.7', require: false
14
- gem 'rubocop', '~> 0.58.1', require: false
14
+ gem 'rubocop', '~> 0.60.0', require: false
15
15
  gem 'simplecov', require: false
@@ -1,23 +1,37 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- dingtalk-client (0.1.0)
4
+ dingtalk-client (0.2.0)
5
+ activesupport (~> 5.2.1)
6
+ httparty (~> 0.16.2)
5
7
 
6
8
  GEM
7
9
  remote: https://rubygems.org/
8
10
  specs:
11
+ activesupport (5.2.1)
12
+ concurrent-ruby (~> 1.0, >= 1.0.2)
13
+ i18n (>= 0.7, < 2)
14
+ minitest (~> 5.1)
15
+ tzinfo (~> 1.1)
9
16
  ast (2.4.0)
10
17
  byebug (10.0.2)
11
18
  codecov (0.1.10)
12
19
  json
13
20
  simplecov
14
21
  url
22
+ concurrent-ruby (1.0.5)
15
23
  diff-lcs (1.3)
16
24
  docile (1.3.1)
25
+ httparty (0.16.2)
26
+ multi_xml (>= 0.5.2)
27
+ i18n (1.1.1)
28
+ concurrent-ruby (~> 1.0)
17
29
  jaro_winkler (1.5.1)
18
30
  json (2.1.0)
31
+ minitest (5.11.3)
32
+ multi_xml (0.6.0)
19
33
  parallel (1.12.1)
20
- parser (2.5.1.2)
34
+ parser (2.5.3.0)
21
35
  ast (~> 2.4.0)
22
36
  powerpack (0.1.2)
23
37
  rainbow (3.0.0)
@@ -35,20 +49,23 @@ GEM
35
49
  diff-lcs (>= 1.2.0, < 2.0)
36
50
  rspec-support (~> 3.8.0)
37
51
  rspec-support (3.8.0)
38
- rubocop (0.58.2)
52
+ rubocop (0.60.0)
39
53
  jaro_winkler (~> 1.5.1)
40
54
  parallel (~> 1.10)
41
55
  parser (>= 2.5, != 2.5.1.1)
42
56
  powerpack (~> 0.1)
43
57
  rainbow (>= 2.2.2, < 4.0)
44
58
  ruby-progressbar (~> 1.7)
45
- unicode-display_width (~> 1.0, >= 1.0.1)
59
+ unicode-display_width (~> 1.4.0)
46
60
  ruby-progressbar (1.10.0)
47
61
  simplecov (0.16.1)
48
62
  docile (~> 1.1)
49
63
  json (>= 1.8, < 3)
50
64
  simplecov-html (~> 0.10.0)
51
65
  simplecov-html (0.10.2)
66
+ thread_safe (0.3.6)
67
+ tzinfo (1.2.5)
68
+ thread_safe (~> 0.1)
52
69
  unicode-display_width (1.4.0)
53
70
  url (0.3.2)
54
71
 
@@ -62,8 +79,8 @@ DEPENDENCIES
62
79
  dingtalk-client!
63
80
  rake (~> 10.0)
64
81
  rspec (~> 3.7)
65
- rubocop (~> 0.58.1)
82
+ rubocop (~> 0.60.0)
66
83
  simplecov
67
84
 
68
85
  BUNDLED WITH
69
- 1.16.6
86
+ 1.17.1
@@ -25,4 +25,6 @@ Gem::Specification.new do |spec|
25
25
 
26
26
  spec.required_ruby_version = '>= 2.5'
27
27
  spec.add_development_dependency 'bundler', '~> 1.16'
28
+ spec.add_dependency 'activesupport', '~> 5.2.1'
29
+ spec.add_dependency 'httparty', '~> 0.16.2'
28
30
  end
@@ -1,11 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dingtalk/client/version'
3
+ require 'httparty'
4
+ require 'active_support/all'
5
+ require 'dingtalk/client/errors'
6
+ require 'dingtalk/client/result'
7
+ require 'dingtalk/client/configurable'
4
8
 
5
9
  module Dingtalk
6
10
  # DingTalk Client
7
11
  # @see https://open-doc.dingtalk.com/
8
12
  module Client
9
- # Your code goes here...
13
+ extend ActiveSupport::Autoload
14
+ autoload :GroupRobotClient
15
+ include Configurable
16
+
17
+ def self.included(base)
18
+ base.include GroupRobotClient
19
+ end
10
20
  end
11
21
  end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dingtalk
4
+ module Client
5
+ # @example Config single item
6
+ # Dingtalk::Client.group_robot_tokens = { default: 'TOKENXXXXXXXXXXX' }
7
+ # @example Config multiple items
8
+ # Dingtalk::Client.configure do |config|
9
+ # config.group_robot_tokens = { default: 'TOKENXXXXXXXBBXX' }
10
+ # config.group_robot_webhook_prefix = 'http://dingtalk.com?access_token='
11
+ # end
12
+ module Configurable
13
+ def self.included(base)
14
+ base.extend ClassMethods
15
+ end
16
+
17
+ # @see Configurable
18
+ module ClassMethods
19
+ def configure
20
+ yield config
21
+ end
22
+
23
+ def config
24
+ @config ||= Configuration.new
25
+ end
26
+ end
27
+
28
+ # @see Configurable
29
+ class Configuration
30
+ attr_writer :group_robot_tokens, :group_robot_webhook_prefix, :template_dir
31
+
32
+ def initialize
33
+ @group_robot_webhook_prefix = 'https://oapi.dingtalk.com/robot/send?access_token='
34
+ @template_dir = '.'
35
+ end
36
+
37
+ def group_robot_tokens
38
+ return @group_robot_tokens.symbolize_keys if @group_robot_tokens.is_a?(Hash)
39
+
40
+ raise ConfigurationError.new(:group_robot_tokens, @group_robot_tokens, Hash)
41
+ end
42
+
43
+ def group_robot_webhook_prefix
44
+ String(@group_robot_webhook_prefix)
45
+ end
46
+
47
+ def template_dir
48
+ String(@template_dir)
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dingtalk
4
+ module Client
5
+ # Basic exception
6
+ class Error < StandardError; end
7
+
8
+ # :nodoc:
9
+ class ConfigurationError < Error
10
+ attr_reader :key, :value, :valid_values
11
+
12
+ def initialize(key, value, valid_values)
13
+ @key = key
14
+ @valud = value
15
+ @valid_values = valid_values
16
+ valid_values_str = Array(valid_values).join(', ')
17
+ message = if value.blank?
18
+ "#{key} not configured or configured with blank value, valid_values: #{valid_values_str}"
19
+ else
20
+ "Configure #{key} with value #{value} failed, valid_values: #{valid_values_str}"
21
+ end
22
+ super(message)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'dingtalk/client/group_robot_client/core'
4
+ require 'dingtalk/client/group_robot_client/notify_text'
5
+ require 'dingtalk/client/group_robot_client/notify_markdown'
6
+ require 'dingtalk/client/group_robot_client/notify_feedcard'
7
+
8
+ module Dingtalk
9
+ module Client
10
+ # @see https://open-doc.dingtalk.com/microapp/serverapi2/qf2nxq
11
+ module GroupRobotClient
12
+ include HTTParty
13
+ include Core
14
+ include NotifyText
15
+ include NotifyMarkdown
16
+ include NotifyFeedcard
17
+ base_uri Dingtalk::Client.config.group_robot_webhook_prefix
18
+ headers 'Content-Type' => 'application/json'
19
+ logger ::Logger.new($stdout), :debug, :curl
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dingtalk
4
+ module Client
5
+ module GroupRobotClient
6
+ # Group Bobot core functions
7
+ module Core
8
+ private
9
+
10
+ # @param token_code [Symbol]
11
+ def fetch_token(token_code)
12
+ Dingtalk::Client.config.group_robot_tokens[token_code].tap do |token|
13
+ raise ArgumentError, "Not found token code: #{token_code}" unless token
14
+ end
15
+ end
16
+
17
+ # @param token [String]
18
+ # @param body [Hash]
19
+ def notify(token, body)
20
+ response = GroupRobotClient.post(token, body: body.to_json)
21
+ if response.parsed_response.try(:[], 'errcode').try(:zero?)
22
+ Result.new(true)
23
+ else
24
+ message = <<-MESSAGE.gsub(/^\s+/, '')
25
+ HTTP Status: #{response.code} #{response.message}
26
+ Response Body: #{response.body}
27
+ MESSAGE
28
+ Result.new(false, message: message)
29
+ end
30
+ rescue StandardError => exception
31
+ Result.new(false, message: exception.inspect)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dingtalk
4
+ module Client
5
+ module GroupRobotClient
6
+ # @see https://open-doc.dingtalk.com/microapp/serverapi2/qf2nxq#a-nameytovydamarkdown%E7%B1%BB%E5%9E%8B
7
+ module NotifyFeedcard
8
+ # @param code [Symbol] set token_code and template_file
9
+ # @param links [Array<Hash>, Hash]
10
+ def notify_feedcard(code, links)
11
+ token_code = code.to_sym
12
+ token = fetch_token(token_code)
13
+ links = Array.wrap(links).map do |link|
14
+ Hash(link).symbolize_keys.tap do |hash|
15
+ required_keys = %i[title messageURL picURL]
16
+ keys_valid = required_keys.all? { |arg| hash[arg].present? }
17
+ raise ArgumentError, "links requires these keys present: #{required_keys.join(', ')}" unless keys_valid
18
+ end
19
+ end
20
+ body = get_feedcard_body(links)
21
+ notify(token, body)
22
+ end
23
+
24
+ private
25
+
26
+ # @param links [Array<Hash>]
27
+ # @return [Hash]
28
+ def get_feedcard_body(links)
29
+ {
30
+ msgtype: 'feedCard',
31
+ feedCard: {
32
+ links: links
33
+ }
34
+ }
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dingtalk
4
+ module Client
5
+ module GroupRobotClient
6
+ # @see https://open-doc.dingtalk.com/microapp/serverapi2/qf2nxq#a-nameytovydamarkdown%E7%B1%BB%E5%9E%8B
7
+ module NotifyMarkdown
8
+ # @param code [Symbol] set token_code and template_file
9
+ # @param title [String]
10
+ # @option options [String] template_file (code) without file suffix
11
+ # @option options [Boolean] is_at_all (false)
12
+ # @option options [Array] at_mobiles ([])
13
+ def notify_markdown(code, title, **options)
14
+ options.with_defaults!(
15
+ template_file: code,
16
+ is_at_all: false,
17
+ at_mobiles: []
18
+ )
19
+ token_code = code.to_sym
20
+ token = fetch_token(token_code)
21
+ title = String(title)
22
+ template_file = String(options[:template_file])
23
+ is_at_all = is_at_all != false
24
+ at_mobiles = Array(at_mobiles)
25
+ content = get_markdown_content(template_file)
26
+ body = get_markdown_body(title, content, is_at_all, at_mobiles)
27
+ notify(token, body)
28
+ end
29
+
30
+ private
31
+
32
+ # @param template_file [String]
33
+ def get_markdown_content(template_file)
34
+ path = "#{Dingtalk::Client.config.template_dir}/#{template_file}.markdown.erb"
35
+ ERB.new(File.read(path)).result(binding)
36
+ rescue Errno::ENOENT
37
+ raise ArgumentError, "Not found template: #{File.expand_path(path)}"
38
+ end
39
+
40
+ # @param title [String]
41
+ # @param content [String]
42
+ # @param is_at_all [Boolean]
43
+ # @param at_mobiles [Array]
44
+ # @return [Hash]
45
+ def get_markdown_body(title, content, is_at_all, at_mobiles)
46
+ {
47
+ msgtype: 'markdown',
48
+ markdown: {
49
+ title: title,
50
+ text: content
51
+ },
52
+ at: {
53
+ atMobiles: at_mobiles,
54
+ isAtAll: is_at_all
55
+ }
56
+ }
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dingtalk
4
+ module Client
5
+ module GroupRobotClient
6
+ # @see https://open-doc.dingtalk.com/microapp/serverapi2/qf2nxq#a-nameytovydamarkdown%E7%B1%BB%E5%9E%8B
7
+ module NotifyText
8
+ # @param code [Symbol] set token_code and template_file
9
+ # @param content [String]
10
+ # @option options [String] template_file (code) without file suffix
11
+ # @option options [Boolean] is_at_all (false)
12
+ # @option options [Array] at_mobiles ([])
13
+ def notify_text(code, content, **options)
14
+ options.with_defaults!(
15
+ is_at_all: false,
16
+ at_mobiles: []
17
+ )
18
+ token_code = code.to_sym
19
+ token = fetch_token(token_code)
20
+ content = String(content)
21
+ is_at_all = is_at_all != false
22
+ at_mobiles = Array(at_mobiles)
23
+ body = get_text_body(content, is_at_all, at_mobiles)
24
+ notify(token, body)
25
+ end
26
+
27
+ private
28
+
29
+ # @param content [String]
30
+ # @param is_at_all [Boolean]
31
+ # @param at_mobiles [Array]
32
+ # @return [Hash]
33
+ def get_text_body(content, is_at_all, at_mobiles)
34
+ {
35
+ msgtype: 'text',
36
+ text: {
37
+ content: content
38
+ },
39
+ at: {
40
+ atMobiles: at_mobiles,
41
+ isAtAll: is_at_all
42
+ }
43
+ }
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dingtalk
4
+ module Client
5
+ # HTTP Response result
6
+ class Result
7
+ attr_reader :status, :message
8
+
9
+ # @param status [Boolean]
10
+ # @param message [String] ('')
11
+ def initialize(status, message: '')
12
+ @status = status != false
13
+ @message = message.to_s
14
+ end
15
+
16
+ def failed?
17
+ !success?
18
+ end
19
+
20
+ def success?
21
+ status
22
+ end
23
+ end
24
+ end
25
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Dingtalk
4
4
  module Client
5
- VERSION = '0.1.0'
5
+ VERSION = '0.2.0'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dingtalk-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.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-10-29 00:00:00.000000000 Z
11
+ date: 2018-10-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -24,6 +24,34 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.16'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 5.2.1
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 5.2.1
41
+ - !ruby/object:Gem::Dependency
42
+ name: httparty
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.16.2
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.16.2
27
55
  description: A simple HTTP client wrapper for Dingtalk.
28
56
  email:
29
57
  - pinewong@163.com
@@ -33,7 +61,6 @@ extra_rdoc_files: []
33
61
  files:
34
62
  - ".gitignore"
35
63
  - ".rubocop.yml"
36
- - ".ruby-version"
37
64
  - ".travis.yml"
38
65
  - CODE_OF_CONDUCT.md
39
66
  - Gemfile
@@ -44,6 +71,14 @@ files:
44
71
  - bin/setup
45
72
  - dingtalk-client.gemspec
46
73
  - lib/dingtalk/client.rb
74
+ - lib/dingtalk/client/configurable.rb
75
+ - lib/dingtalk/client/errors.rb
76
+ - lib/dingtalk/client/group_robot_client.rb
77
+ - lib/dingtalk/client/group_robot_client/core.rb
78
+ - lib/dingtalk/client/group_robot_client/notify_feedcard.rb
79
+ - lib/dingtalk/client/group_robot_client/notify_markdown.rb
80
+ - lib/dingtalk/client/group_robot_client/notify_text.rb
81
+ - lib/dingtalk/client/result.rb
47
82
  - lib/dingtalk/client/version.rb
48
83
  homepage: https://github.com/pinewong/dingtalk-client
49
84
  licenses: []
@@ -64,7 +99,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
64
99
  version: '0'
65
100
  requirements: []
66
101
  rubyforge_project:
67
- rubygems_version: 2.7.6
102
+ rubygems_version: 2.7.7
68
103
  signing_key:
69
104
  specification_version: 4
70
105
  summary: A simple HTTP client wrapper for Dingtalk.
@@ -1 +0,0 @@
1
- 2.5.1