msteams_hermes 1.1.0 → 1.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: 9b669c1e292e83f5cd4ade218b5746fd43d510992f5a5b2ef8db6c0fa50d8799
4
- data.tar.gz: a188b10e541fc0c5d471b872c20c2cc15a0852c95bea444da8d0bd2b179c2dc1
3
+ metadata.gz: 4b3cdc7a7dfce17ff21c71884f2e774845e1ba7fe89a2c9ead3445f88a40c544
4
+ data.tar.gz: c509e71637183ffa574dedb800be337f06f07c04869e8a0bfef61d5b7e20f2b6
5
5
  SHA512:
6
- metadata.gz: d320bd149716475e1be084bede6a3443a53263cfb77df1a8f163f8257465f9422d71ca7149447a769bf1860efe3ceb95f38e5b2a0a3ac3b993565d7abfa7e9b9
7
- data.tar.gz: 5d68eea1cdb86d0c2383881f4a334c8952650513c51aa883e06f2290fd366a9758fae12503d270350b40390102e3009b8c878b1d15150f1585663c178508dd01
6
+ metadata.gz: 6f2d422662a3846abd375126115db6ce6a008a67e811fb8563a4d6955d328e80df3591d3049e463fc65b29a0f41ccd4f66595a1cbaddab0811c40de40ecc9e82
7
+ data.tar.gz: e0c7a189f4a9be321c068efef20aaafe5244095f2b6617006940c92f10bc93ce1e4dcfe462aa7f6e1066ddee1398a611eaa66dbc971124928a8273c7a233b9bb
@@ -11,7 +11,7 @@ jobs:
11
11
  runs-on: ubuntu-latest
12
12
  strategy:
13
13
  matrix:
14
- ruby-version: [ "2.7", "3.0", "3.1.2" ]
14
+ ruby-version: [ "3.1", "3.2", "3.3" ]
15
15
  steps:
16
16
  - uses: actions/checkout@v2
17
17
 
data/.rubocop.yml CHANGED
@@ -1,9 +1,10 @@
1
1
  AllCops:
2
- TargetRubyVersion: 2.7
2
+ TargetRubyVersion: 3.1
3
3
 
4
4
  Metrics/BlockLength:
5
5
  Exclude:
6
- - 'spec/**/*'
6
+ - msteams_hermes.gemspec
7
+ - spec/**/*
7
8
 
8
9
  Style/StringLiterals:
9
10
  Enabled: true
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  ## Changelog
2
2
 
3
+ ## [1.2.0] - 2024-12-20
4
+ - Add support for MSTeams workflow based webhooks
5
+
6
+ ## [1.1.1] - 2023-01-24
7
+ - Prevent causing 413 response from microsoft teams webhook
8
+
3
9
  ## [1.1.0] - 2023-01-24
4
10
  - Add support for @mentions
5
11
 
data/Gemfile CHANGED
@@ -4,7 +4,3 @@ source "https://rubygems.org"
4
4
 
5
5
  # Specify your gem's dependencies in msteams_hermes.gemspec
6
6
  gemspec
7
-
8
- gem "rake"
9
- gem "rspec"
10
- gem "rubocop"
data/Gemfile.lock CHANGED
@@ -1,59 +1,86 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- msteams_hermes (1.1.0)
4
+ msteams_hermes (1.2.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
+ addressable (2.8.6)
10
+ public_suffix (>= 2.0.2, < 6.0)
9
11
  ast (2.4.2)
10
- diff-lcs (1.5.0)
11
- json (2.6.2)
12
- parallel (1.22.1)
13
- parser (3.1.2.1)
12
+ bigdecimal (3.1.8)
13
+ byebug (11.1.3)
14
+ coderay (1.1.3)
15
+ crack (1.0.0)
16
+ bigdecimal
17
+ rexml
18
+ diff-lcs (1.5.1)
19
+ hashdiff (1.1.0)
20
+ json (2.7.2)
21
+ language_server-protocol (3.17.0.3)
22
+ method_source (1.1.0)
23
+ parallel (1.24.0)
24
+ parser (3.3.1.0)
14
25
  ast (~> 2.4.1)
26
+ racc
27
+ pry (0.14.2)
28
+ coderay (~> 1.1)
29
+ method_source (~> 1.0)
30
+ pry-byebug (3.10.1)
31
+ byebug (~> 11.0)
32
+ pry (>= 0.13, < 0.15)
33
+ public_suffix (5.0.5)
34
+ racc (1.8.0)
15
35
  rainbow (3.1.1)
16
- rake (13.0.6)
17
- regexp_parser (2.5.0)
18
- rexml (3.2.5)
19
- rspec (3.11.0)
20
- rspec-core (~> 3.11.0)
21
- rspec-expectations (~> 3.11.0)
22
- rspec-mocks (~> 3.11.0)
23
- rspec-core (3.11.0)
24
- rspec-support (~> 3.11.0)
25
- rspec-expectations (3.11.0)
36
+ rake (13.2.1)
37
+ regexp_parser (2.9.2)
38
+ rexml (3.3.4)
39
+ strscan
40
+ rspec (3.13.0)
41
+ rspec-core (~> 3.13.0)
42
+ rspec-expectations (~> 3.13.0)
43
+ rspec-mocks (~> 3.13.0)
44
+ rspec-core (3.13.0)
45
+ rspec-support (~> 3.13.0)
46
+ rspec-expectations (3.13.0)
26
47
  diff-lcs (>= 1.2.0, < 2.0)
27
- rspec-support (~> 3.11.0)
28
- rspec-mocks (3.11.1)
48
+ rspec-support (~> 3.13.0)
49
+ rspec-mocks (3.13.1)
29
50
  diff-lcs (>= 1.2.0, < 2.0)
30
- rspec-support (~> 3.11.0)
31
- rspec-support (3.11.0)
32
- rubocop (1.36.0)
51
+ rspec-support (~> 3.13.0)
52
+ rspec-support (3.13.1)
53
+ rubocop (1.63.5)
33
54
  json (~> 2.3)
55
+ language_server-protocol (>= 3.17.0)
34
56
  parallel (~> 1.10)
35
- parser (>= 3.1.2.1)
57
+ parser (>= 3.3.0.2)
36
58
  rainbow (>= 2.2.2, < 4.0)
37
59
  regexp_parser (>= 1.8, < 3.0)
38
60
  rexml (>= 3.2.5, < 4.0)
39
- rubocop-ast (>= 1.20.1, < 2.0)
61
+ rubocop-ast (>= 1.31.1, < 2.0)
40
62
  ruby-progressbar (~> 1.7)
41
- unicode-display_width (>= 1.4.0, < 3.0)
42
- rubocop-ast (1.21.0)
43
- parser (>= 3.1.1.0)
44
- ruby-progressbar (1.11.0)
45
- unicode-display_width (2.2.0)
63
+ unicode-display_width (>= 2.4.0, < 3.0)
64
+ rubocop-ast (1.31.3)
65
+ parser (>= 3.3.1.0)
66
+ ruby-progressbar (1.13.0)
67
+ strscan (3.1.0)
68
+ unicode-display_width (2.5.0)
69
+ webmock (3.23.0)
70
+ addressable (>= 2.8.0)
71
+ crack (>= 0.3.2)
72
+ hashdiff (>= 0.4.0, < 2.0.0)
46
73
 
47
74
  PLATFORMS
48
75
  ruby
49
- x86_64-darwin-20
50
- x86_64-darwin-21
51
76
 
52
77
  DEPENDENCIES
53
78
  msteams_hermes!
79
+ pry-byebug
54
80
  rake
55
81
  rspec
56
82
  rubocop
83
+ webmock (~> 3.23)
57
84
 
58
85
  BUNDLED WITH
59
- 2.2.15
86
+ 2.5.10
data/complex_example.rb CHANGED
@@ -19,7 +19,7 @@ header = MsTeamsHermes::Components::Container.new(
19
19
  weight: MsTeamsHermes::Style::FontWeight::BOLDER
20
20
  ),
21
21
  MsTeamsHermes::Components::TextBlock.new(
22
- text: "Saturday, 1 January 2022"
22
+ text: Time.now.strftime("%A, %d %B %Y %H:%M:%S").to_s
23
23
  )
24
24
  ]
25
25
  )
@@ -72,4 +72,4 @@ content = MsTeamsHermes::Components::AdaptiveCard.new(
72
72
  ]
73
73
  )
74
74
 
75
- MsTeamsHermes::Message.new(webhook_url: YOUR_WEBHOOK_URL, content: content).deliver
75
+ MsTeamsHermes::Message.new(webhook_url: YOUR_WEBHOOK_URL, content:).deliver
@@ -20,9 +20,9 @@ module MsTeamsHermes
20
20
  def to_hash
21
21
  {
22
22
  type: "Action.OpenUrl",
23
- url: url,
24
- title: title,
25
- tooltip: tooltip
23
+ url:,
24
+ title:,
25
+ tooltip:
26
26
  }
27
27
  end
28
28
  end
@@ -1,20 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "msteams_hermes/components/base"
4
+ require "msteams_hermes/style"
4
5
 
5
6
  module MsTeamsHermes
6
7
  ##
7
8
  # Module containing Microsoft's components representations
8
9
  ##
9
10
  module Components
11
+ include MsTeamsHermes::Style
10
12
  ##
11
13
  # A class representing Microsoft's AdaptiveCard object
12
14
  # https://adaptivecards.io/explorer/AdaptiveCard.html
13
15
  ##
14
16
  class AdaptiveCard < Base
15
- attr_reader :body, :actions, :entities
17
+ attr_reader :body, :actions, :entities, :width
16
18
 
17
- def initialize(body:, actions: nil, entities: [])
19
+ def initialize(body:, actions: nil, entities: [], width: Style::Width::DEFAULT)
18
20
  @body = body
19
21
  raise "AdaptiveCard `body` must be an Array" unless @body.is_a? Array
20
22
 
@@ -23,6 +25,9 @@ module MsTeamsHermes
23
25
 
24
26
  @entities = entities
25
27
  raise "AdaptiveCard `entities` must be an Array" unless @entities.nil? || @entities.is_a?(Array)
28
+
29
+ @width = width
30
+ raise "AdaptiveCard `width` must be one of the available Width options" unless Style::Width.all.include?(width)
26
31
  end
27
32
 
28
33
  def to_hash
@@ -31,7 +36,10 @@ module MsTeamsHermes
31
36
  version: "1.5",
32
37
  body: body.map(&:to_hash),
33
38
  actions: actions&.map(&:to_hash),
34
- msteams: { entities: entities.map(&:to_hash) }
39
+ msteams: {
40
+ entities: entities.map(&:to_hash),
41
+ width:
42
+ }
35
43
  }
36
44
  end
37
45
  end
@@ -25,7 +25,7 @@ module MsTeamsHermes
25
25
  def to_hash
26
26
  {
27
27
  type: "Column",
28
- width: width,
28
+ width:,
29
29
  items: items.map(&:to_hash)
30
30
  }
31
31
  end
@@ -27,7 +27,7 @@ module MsTeamsHermes
27
27
  def to_hash
28
28
  {
29
29
  type: "Container",
30
- style: style,
30
+ style:,
31
31
  selectAction: select_action&.to_hash,
32
32
  items: items.map(&:to_hash)
33
33
  }
@@ -23,7 +23,7 @@ module MsTeamsHermes
23
23
  def to_hash
24
24
  {
25
25
  type: "FactSet",
26
- facts: facts
26
+ facts:
27
27
  }
28
28
  end
29
29
 
@@ -37,13 +37,13 @@ module MsTeamsHermes
37
37
  def to_hash
38
38
  {
39
39
  type: "TextBlock",
40
- text: text,
41
- color: color,
42
- size: size,
43
- font_type: font_type,
44
- weight: weight,
45
- wrap: wrap,
46
- is_subtle: is_subtle
40
+ text:,
41
+ color:,
42
+ size:,
43
+ font_type:,
44
+ weight:,
45
+ wrap:,
46
+ is_subtle:
47
47
  }
48
48
  end
49
49
  end
@@ -3,12 +3,47 @@
3
3
  require "net/http"
4
4
  require "json"
5
5
 
6
+ ##
7
+ # Module to encapsulate the logic that decides whether a given response
8
+ # is of type workflow or connector type webhook.
9
+ # Both types must be considered differently to support both types of
10
+ # MSTeams webhooks.
11
+ ##
12
+ module MsTeamsWebhookType
13
+ end
14
+
6
15
  module MsTeamsHermes
7
16
  ##
8
17
  # A class representing Microsoft's webhook message object
9
18
  # https://docs.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/connectors-using?tabs=cURL#send-adaptive-cards-using-an-incoming-webhook
10
19
  ##
11
20
  class Message
21
+ ##
22
+ # Raises when the message is larger than the latest known maximum size of a microsoft teams message
23
+ ##
24
+ class MessageBodyTooLargeError < StandardError
25
+ def initialize(current_size)
26
+ super "Microsoft Teams Webhook answered with a 413 due to content size limitations" \
27
+ " (last check it was about #{MSTEAMS_MESSAGE_SIZE_LIMIT} bytes)." \
28
+ "\nYour message results in a size of about #{current_size} bytes which is too much."
29
+ end
30
+ end
31
+
32
+ ##
33
+ # Raises when the response message changes from the successful response
34
+ ##
35
+ class UnknownError < StandardError
36
+ def initialize(error)
37
+ super "Microsoft Teams Webhook had an unexpected response body:\n#{error}"
38
+ end
39
+ end
40
+
41
+ # Docu says: 'The message size limit is 28 KB',
42
+ # but testing aligned with 21KB.
43
+ # See: https://learn.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/add-incoming-webhook
44
+ MSTEAMS_MESSAGE_SIZE_LIMIT = 21_000
45
+ MSTEAMS_MESSAGE_413_ERROR_TOKEN = "returned HTTP error 413"
46
+
12
47
  attr_reader :webhook_url, :content
13
48
 
14
49
  def initialize(content:, webhook_url: ENV["WEBHOOK_URL"])
@@ -19,6 +54,8 @@ module MsTeamsHermes
19
54
  raise "Message `content` must be an AdaptiveCard" unless @content.is_a? Components::AdaptiveCard
20
55
  end
21
56
 
57
+ # rubocop:disable Metrics/AbcSize
58
+ # rubocop:disable Metrics/MethodLength
22
59
  ##
23
60
  # Sends a HTTP request to the webhook URL specified via
24
61
  # either environment variable or when initializing the class
@@ -31,9 +68,19 @@ module MsTeamsHermes
31
68
  req = Net::HTTP::Post.new(uri)
32
69
  req.body = body_json
33
70
  req["Content-Type"] = "application/json"
34
- http.request(req)
71
+
72
+ response = http.request(req)
73
+
74
+ return response if response_from_mst_workflow_webhook?(response) ||
75
+ response_from_mst_connector_webhook?(response)
76
+
77
+ raise MessageBodyTooLargeError, body_json.bytesize if message_too_large?(response)
78
+
79
+ raise UnknownError, response.body
35
80
  end
36
81
  end
82
+ # rubocop:enable Metrics/AbcSize
83
+ # rubocop:enable Metrics/MethodLength
37
84
 
38
85
  ##
39
86
  # Formats the JSON object to be set on the HTTP request
@@ -52,5 +99,21 @@ module MsTeamsHermes
52
99
  ]
53
100
  }.to_json
54
101
  end
102
+
103
+ private
104
+
105
+ def response_from_mst_workflow_webhook?(response)
106
+ response.code == "202" && response.body.empty?
107
+ end
108
+
109
+ def response_from_mst_connector_webhook?(response)
110
+ # For details see:
111
+ # https://learn.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/connectors-using?tabs=cURL%2Ctext1#send-messages-using-curl-and-powershell
112
+ response.code == "200" && response.body == "1"
113
+ end
114
+
115
+ def message_too_large?(response)
116
+ response.body.include? MSTEAMS_MESSAGE_413_ERROR_TOKEN
117
+ end
55
118
  end
56
119
  end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MsTeamsHermes
4
+ ##
5
+ # Module containing Microsoft's style representations
6
+ ##
7
+ module Style
8
+ ##
9
+ # Module containing available width options for the AdaptiveCard component
10
+ ##
11
+ module Width
12
+ DEFAULT = "default"
13
+ FULL = "full"
14
+
15
+ def self.all
16
+ [DEFAULT, FULL]
17
+ end
18
+ end
19
+ end
20
+ end
@@ -5,6 +5,7 @@ require "msteams_hermes/style/container_style"
5
5
  require "msteams_hermes/style/font_size"
6
6
  require "msteams_hermes/style/font_type"
7
7
  require "msteams_hermes/style/font_weight"
8
+ require "msteams_hermes/style/width"
8
9
 
9
10
  module MsTeamsHermes
10
11
  ##
@@ -16,5 +17,6 @@ module MsTeamsHermes
16
17
  include MsTeamsHermes::Style::FontSize
17
18
  include MsTeamsHermes::Style::FontType
18
19
  include MsTeamsHermes::Style::FontWeight
20
+ include MsTeamsHermes::Style::Width
19
21
  end
20
22
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MsTeamsHermes
4
- VERSION = "1.1.0"
4
+ VERSION = "1.2.0"
5
5
  end
@@ -16,12 +16,13 @@ Gem::Specification.new do |spec|
16
16
  "Microsoft's adaptive cards."
17
17
  spec.homepage = "https://github.com/xing/msteams_hermes"
18
18
  spec.license = "MIT"
19
- spec.required_ruby_version = Gem::Requirement.new(">= 2.7.0")
20
19
 
21
20
  spec.metadata["homepage_uri"] = spec.homepage
22
21
  spec.metadata["source_code_uri"] = "https://github.com/xing/msteams_hermes"
23
22
  spec.metadata["changelog_uri"] = "https://github.com/xing/msteams_hermes/CHANGELOG.md"
24
23
 
24
+ spec.required_ruby_version = Gem::Requirement.new(">= 3.1")
25
+
25
26
  # Specify which files should be added to the gem when it is released.
26
27
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
27
28
  spec.files = Dir.chdir(File.expand_path(__dir__)) do
@@ -34,6 +35,9 @@ Gem::Specification.new do |spec|
34
35
  # Uncomment to register a new dependency of your gem
35
36
  # spec.add_dependency "example-gem", "~> 1.0"
36
37
 
37
- # For more information and examples about making a new gem, checkout our
38
- # guide at: https://bundler.io/guides/creating_gem.html
38
+ spec.add_development_dependency "pry-byebug"
39
+ spec.add_development_dependency "rake"
40
+ spec.add_development_dependency "rspec"
41
+ spec.add_development_dependency "rubocop"
42
+ spec.add_development_dependency "webmock", "~> 3.23"
39
43
  end
metadata CHANGED
@@ -1,15 +1,85 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: msteams_hermes
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rafael Rocha
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-01-24 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2024-12-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: pry-byebug
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
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: rubocop
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: webmock
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.23'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.23'
13
83
  description: This gem helps you sending messages to your Microsoft Teams channels.
14
84
  With autonomy to create your own layouts, like UI kits such as React, Flutter, SwiftUI
15
85
  (and some others), you will be able to customize it with the objects representations
@@ -53,6 +123,7 @@ files:
53
123
  - lib/msteams_hermes/style/font_size.rb
54
124
  - lib/msteams_hermes/style/font_type.rb
55
125
  - lib/msteams_hermes/style/font_weight.rb
126
+ - lib/msteams_hermes/style/width.rb
56
127
  - lib/msteams_hermes/version.rb
57
128
  - msteams_hermes.gemspec
58
129
  homepage: https://github.com/xing/msteams_hermes
@@ -70,14 +141,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
70
141
  requirements:
71
142
  - - ">="
72
143
  - !ruby/object:Gem::Version
73
- version: 2.7.0
144
+ version: '3.1'
74
145
  required_rubygems_version: !ruby/object:Gem::Requirement
75
146
  requirements:
76
147
  - - ">="
77
148
  - !ruby/object:Gem::Version
78
149
  version: '0'
79
150
  requirements: []
80
- rubygems_version: 3.3.7
151
+ rubygems_version: 3.5.23
81
152
  signing_key:
82
153
  specification_version: 4
83
154
  summary: Send messages to any Microsoft Teams' channel as easy as possible.