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 +4 -4
- data/.github/workflows/ci.yml +1 -1
- data/.rubocop.yml +3 -2
- data/CHANGELOG.md +6 -0
- data/Gemfile +0 -4
- data/Gemfile.lock +57 -30
- data/complex_example.rb +2 -2
- data/lib/msteams_hermes/actions/open_url.rb +3 -3
- data/lib/msteams_hermes/components/adaptive_card.rb +11 -3
- data/lib/msteams_hermes/components/column.rb +1 -1
- data/lib/msteams_hermes/components/container.rb +1 -1
- data/lib/msteams_hermes/components/fact_set.rb +1 -1
- data/lib/msteams_hermes/components/text_block.rb +7 -7
- data/lib/msteams_hermes/message.rb +64 -1
- data/lib/msteams_hermes/style/width.rb +20 -0
- data/lib/msteams_hermes/style.rb +2 -0
- data/lib/msteams_hermes/version.rb +1 -1
- data/msteams_hermes.gemspec +7 -3
- metadata +76 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4b3cdc7a7dfce17ff21c71884f2e774845e1ba7fe89a2c9ead3445f88a40c544
|
4
|
+
data.tar.gz: c509e71637183ffa574dedb800be337f06f07c04869e8a0bfef61d5b7e20f2b6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6f2d422662a3846abd375126115db6ce6a008a67e811fb8563a4d6955d328e80df3591d3049e463fc65b29a0f41ccd4f66595a1cbaddab0811c40de40ecc9e82
|
7
|
+
data.tar.gz: e0c7a189f4a9be321c068efef20aaafe5244095f2b6617006940c92f10bc93ce1e4dcfe462aa7f6e1066ddee1398a611eaa66dbc971124928a8273c7a233b9bb
|
data/.github/workflows/ci.yml
CHANGED
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,59 +1,86 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
msteams_hermes (1.
|
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
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
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.
|
17
|
-
regexp_parser (2.
|
18
|
-
rexml (3.
|
19
|
-
|
20
|
-
|
21
|
-
rspec-
|
22
|
-
rspec-
|
23
|
-
|
24
|
-
|
25
|
-
|
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.
|
28
|
-
rspec-mocks (3.
|
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.
|
31
|
-
rspec-support (3.
|
32
|
-
rubocop (1.
|
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.
|
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.
|
61
|
+
rubocop-ast (>= 1.31.1, < 2.0)
|
40
62
|
ruby-progressbar (~> 1.7)
|
41
|
-
unicode-display_width (>=
|
42
|
-
rubocop-ast (1.
|
43
|
-
parser (>= 3.
|
44
|
-
ruby-progressbar (1.
|
45
|
-
|
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.
|
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: "
|
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:
|
75
|
+
MsTeamsHermes::Message.new(webhook_url: YOUR_WEBHOOK_URL, content:).deliver
|
@@ -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: {
|
39
|
+
msteams: {
|
40
|
+
entities: entities.map(&:to_hash),
|
41
|
+
width:
|
42
|
+
}
|
35
43
|
}
|
36
44
|
end
|
37
45
|
end
|
@@ -37,13 +37,13 @@ module MsTeamsHermes
|
|
37
37
|
def to_hash
|
38
38
|
{
|
39
39
|
type: "TextBlock",
|
40
|
-
text
|
41
|
-
color
|
42
|
-
size
|
43
|
-
font_type
|
44
|
-
weight
|
45
|
-
wrap
|
46
|
-
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
|
-
|
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
|
data/lib/msteams_hermes/style.rb
CHANGED
@@ -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
|
data/msteams_hermes.gemspec
CHANGED
@@ -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
|
-
|
38
|
-
|
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.
|
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:
|
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:
|
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.
|
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.
|