dingtalk-client 0.1.0 → 0.2.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: 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