discord-notifier-confidist 1.0.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8c530416c5985430f3cf2069337be722b0a1aa4f
4
+ data.tar.gz: 437e114a9d44cec817e47db37f76308e967186ae
5
+ SHA512:
6
+ metadata.gz: 393ecc72be0ac6b9de9638c41db01eb41efafba6e1465be44a19f7651b69fa2dc9eaa41881b32689aa5db5dd906360024e32a67dae2a5b9638434fdce02ff478
7
+ data.tar.gz: f3d6e122d5daaa2b42874739920bfe8bcf4d6457c7cced1ed843c11fe4801e9f3baaa923a8449dbbb3f7d922fbb659cad8efbf20a07bb8b90e1f3abc5a36dee2
@@ -0,0 +1,2 @@
1
+ # This file exists for Rails autoloading
2
+ require_relative '../discord_notifier'
@@ -0,0 +1,11 @@
1
+ module Discord
2
+ module Backports
3
+ unless Hash.instance_methods(false).include?(:compact)
4
+ refine Hash do
5
+ def compact
6
+ select { |_, value| !value.nil? }
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,16 @@
1
+ require 'net/http'
2
+
3
+ module Discord
4
+ module Backports
5
+ unless Net::HTTP.methods.include?(:post)
6
+ refine Net::HTTP.singleton_class do
7
+ def post(url, data, header = nil)
8
+ start(url.hostname, url.port,
9
+ :use_ssl => url.scheme == 'https' ) {|http|
10
+ http.post(url.path, data, header)
11
+ }
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,87 @@
1
+ module Discord
2
+ class Embed
3
+ attr_reader :data
4
+
5
+ def initialize(&block)
6
+ @data = {}
7
+ self.instance_exec(&block) if block_given?
8
+ end
9
+
10
+ def title(str)
11
+ raise ArgumentError, 'Title Embed data must be a String' unless str.is_a?(String)
12
+ @data[:title] = str
13
+ end
14
+
15
+ def description(str)
16
+ raise ArgumentError, 'Description Embed data must be a String' unless str.is_a?(String)
17
+ @data[:description] = str
18
+ end
19
+
20
+ def url(str)
21
+ raise ArgumentError, 'URL Embed data must be a String' unless str.is_a?(String)
22
+ @data[:url] = str
23
+ end
24
+
25
+ def timestamp(date)
26
+ raise ArgumentError, 'Timestamp Embed data must be a Date' unless date.is_a?(DateTime)
27
+ @data[:timestamp] = date
28
+ end
29
+
30
+ def color(val)
31
+ case val
32
+ when String
33
+ @data[:color] = val.delete('#').to_i(16)
34
+ when Integer
35
+ raise ArgumentError, 'Color must be 24 bit' if val >= 16_777_216
36
+ @data[:color] = val
37
+ else
38
+ raise ArgumentError, 'Color must be hex or 24 bit int'
39
+ end
40
+ end
41
+
42
+ def thumbnail(params)
43
+ raise ArgumentError, "Thumbnail Embed data must be a Hash" unless params.is_a?(Hash)
44
+
45
+ @data[:thumbnail] = params
46
+ end
47
+
48
+ def video(params)
49
+ raise ArgumentError, "Video Embed data must be a Hash" unless params.is_a?(Hash)
50
+
51
+ @data[:video] = params
52
+ end
53
+
54
+ def image(params)
55
+ raise ArgumentError, "Image Embed data must be a Hash" unless params.is_a?(Hash)
56
+
57
+ @data[:image] = params
58
+ end
59
+
60
+ def provider(params)
61
+ raise ArgumentError, "Provider Embed data must be a Hash" unless params.is_a?(Hash)
62
+
63
+ @data[:provider] = params
64
+ end
65
+
66
+ def author(params)
67
+ raise ArgumentError, "Author Embed data must be a Hash" unless params.is_a?(Hash)
68
+
69
+ @data[:author] = params
70
+ end
71
+
72
+ def footer(params)
73
+ raise ArgumentError, "Footer Embed data must be a Hash" unless params.is_a?(Hash)
74
+
75
+ @data[:footer] = params
76
+ end
77
+
78
+ def add_field(params)
79
+ raise ArgumentError, "Field Embed data must be a Hash" unless params.is_a?(Hash)
80
+
81
+ @data[:fields] ||= []
82
+ @data[:fields] << params
83
+ end
84
+
85
+ alias :field :add_field
86
+ end
87
+ end
@@ -0,0 +1,33 @@
1
+ require 'net/http'
2
+
3
+ module Discord
4
+ BOUNDARY = "DiscordNotifier"
5
+
6
+ def self.form_data_request(uri, params)
7
+ req = Net::HTTP::Post.new(uri)
8
+ req.add_field "Content-Type", "multipart/form-data; boundary=#{BOUNDARY}"
9
+ req.body = Discord.multipart_form_data(params)
10
+ return req
11
+ end
12
+
13
+ def self.multipart_form_data(config)
14
+ file = config[:file]
15
+ filename = File.basename(file.path)
16
+ file_contents = File.read(file)
17
+ payload = config.select {|k, v| k != :file}
18
+
19
+ form = <<~eos
20
+ --#{BOUNDARY}
21
+ Content-Disposition: form-data; name="file"; filename="#{filename}"
22
+
23
+ #{file_contents}
24
+
25
+ --#{BOUNDARY}
26
+ Content-Disposition: form-data; name="payload_json"
27
+
28
+ #{payload.to_json}
29
+
30
+ --#{BOUNDARY}--
31
+ eos
32
+ end
33
+ end
@@ -0,0 +1,5 @@
1
+ module Discord
2
+ module Notifier
3
+ VERSION = '1.0.0'.freeze
4
+ end
5
+ end
@@ -0,0 +1,78 @@
1
+ require 'json'
2
+ require 'net/http'
3
+ require 'net/https'
4
+ require_relative 'discord_notifier/embed'
5
+ require_relative 'discord_notifier/form_data'
6
+ require_relative 'discord_notifier/backports/hash'
7
+ require_relative 'discord_notifier/backports/http'
8
+
9
+ module Discord
10
+ using Backports
11
+
12
+ Config = Struct.new(:url, :username, :avatar_url, :wait)
13
+
14
+ module Notifier
15
+ @@config = Config.new
16
+
17
+ def self.setup
18
+ yield @@config
19
+ end
20
+
21
+ def self.message(content, config = {})
22
+ params = payload(content, config)
23
+
24
+ if params[:file]
25
+ send_form(params)
26
+ else
27
+ send_request(params)
28
+ end
29
+ end
30
+
31
+ def self.payload(content, config)
32
+ payload = @@config.to_h.merge(config)
33
+
34
+ case content
35
+ when String
36
+ payload[:content] = content
37
+ when Embed
38
+ payload[:embeds] = [content.data]
39
+ when Array
40
+ payload[:embeds] = content.map { |embed| embed.data }
41
+ when File
42
+ payload[:file] = content
43
+ else
44
+ raise ArgumentError, 'Unsupported content type'
45
+ end
46
+
47
+ payload.compact
48
+ end
49
+
50
+ def self.send_request(params)
51
+ uri = endpoint(params)
52
+ http = Net::HTTP.new(uri.host, uri.port)
53
+ http.use_ssl = true
54
+
55
+ req = Net::HTTP::Post.new(endpoint(params))
56
+ req.body = params.to_json
57
+ req.content_type = 'application/json'
58
+
59
+ http.request(req)
60
+ end
61
+
62
+ def self.send_form(params)
63
+ uri = endpoint(params)
64
+
65
+ req = Discord.form_data_request(uri, params)
66
+
67
+ http = Net::HTTP.new(uri.host, uri.port)
68
+ http.use_ssl = true
69
+ http.request(req)
70
+ end
71
+
72
+ def self.endpoint(config)
73
+ uri = URI(config[:url])
74
+ uri.query = URI.encode_www_form(wait: true) if config[:wait]
75
+ return uri
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,76 @@
1
+ require 'test_helper'
2
+ require 'date'
3
+
4
+ class Discord::EmbedTest < Minitest::Test
5
+ def test_that_it_has_a_data_hash
6
+ embed = Discord::Embed.new
7
+ assert embed.data.is_a? Hash
8
+ end
9
+
10
+ def test_embed_fields_exist
11
+ embed = Discord::Embed.new
12
+ fields = %w(title description url timestamp color footer image thumbnail
13
+ video provider author)
14
+
15
+ fields.each do |field|
16
+ assert embed.public_methods.include?(field.to_sym), "#{field} not found"
17
+ end
18
+
19
+ assert embed.public_methods.include? :add_field
20
+ assert embed.public_methods.include? :field
21
+ end
22
+
23
+ def test_multiple_fields
24
+ embed = Discord::Embed.new do
25
+ add_field name: "Field 1"
26
+ add_field name: "Field 2"
27
+ add_field name: "Field 3"
28
+ end
29
+
30
+ assert_equal embed.data[:fields].size, 3
31
+ end
32
+
33
+ def test_embed_field_argument_types
34
+ embed = Discord::Embed.new
35
+
36
+ assert_raises(ArgumentError) { embed.title({ value: 'Hash' }) }
37
+ embed.title 'String Value'
38
+
39
+ assert_raises(ArgumentError) { embed.description({ value: 'Hash' }) }
40
+ embed.description 'String Value'
41
+
42
+ assert_raises(ArgumentError) { embed.url({ value: 'Hash' }) }
43
+ embed.url 'String Value'
44
+
45
+ assert_raises(ArgumentError) { embed.thumbnail('String Value') }
46
+ embed.thumbnail value: 'Hash Value'
47
+
48
+ assert_raises(ArgumentError) { embed.video('String Value') }
49
+ embed.video value: 'Hash Value'
50
+
51
+ assert_raises(ArgumentError) { embed.image('String Value') }
52
+ embed.image value: 'Hash Value'
53
+
54
+ assert_raises(ArgumentError) { embed.provider('String Value') }
55
+ embed.provider value: 'Hash Value'
56
+
57
+ assert_raises(ArgumentError) { embed.author('String Value') }
58
+ embed.author value: 'Hash Value'
59
+
60
+ assert_raises(ArgumentError) { embed.footer('String Value') }
61
+ embed.footer value: 'Hash Value'
62
+
63
+ assert_raises(ArgumentError) { embed.field('String Value') }
64
+ embed.field value: 'Hash Value'
65
+
66
+ assert_raises(ArgumentError) { embed.color({ hex: 'value' }) }
67
+ assert_raises(ArgumentError) { embed.color(16_777_500) }
68
+ embed.color 0x008000
69
+ val = embed.data[:color]
70
+ embed.color '#008000'
71
+ assert_equal val, embed.data[:color]
72
+
73
+ assert_raises(ArgumentError) { embed.timestamp({ value: 'Hash' }) }
74
+ embed.timestamp DateTime.new(2001,2,3,4,5,6)
75
+ end
76
+ end
@@ -0,0 +1,37 @@
1
+ require 'test_helper'
2
+
3
+ class Discord::FormDataTest < Minitest::Test
4
+ def expected_form_body
5
+ Dir.chdir(File.dirname(__FILE__))
6
+ File.read('../../form_body.txt')
7
+ end
8
+
9
+ def test_that_boundary_is_defined
10
+ refute_nil Discord::BOUNDARY
11
+ end
12
+
13
+ def test_form_data_request_has_correct_header
14
+ params = {
15
+ url: 'http://test.com',
16
+ username: 'Gem Test',
17
+ avatar_url: 'http://avatar.com/discord.png',
18
+ file: test_attachment
19
+ }
20
+
21
+ request = Discord.form_data_request(URI('http://test.com'), params)
22
+ assert_equal 'multipart/form-data', request.content_type
23
+ end
24
+
25
+ def test_multipart_form_data_has_correct_format
26
+ expected_body = expected_form_body
27
+ params = {
28
+ url: 'http://test.com',
29
+ username: 'Gem Test',
30
+ avatar_url: 'http://avatar.com/discord.png',
31
+ file: test_attachment
32
+ }
33
+
34
+ body = Discord.multipart_form_data(params)
35
+ assert_equal expected_body, body
36
+ end
37
+ end
@@ -0,0 +1,7 @@
1
+ require 'test_helper'
2
+
3
+ class Discord::NotifierTest < Minitest::Test
4
+ def test_that_it_has_a_version_number
5
+ refute_nil Discord::Notifier::VERSION
6
+ end
7
+ end
@@ -0,0 +1,199 @@
1
+ require 'test_helper'
2
+ require 'net/http'
3
+ require 'json'
4
+
5
+ class Discord::NotifierTest < Minitest::Test
6
+ def setup
7
+ Discord::Notifier.setup do |config|
8
+ config.url = 'http://test.com'
9
+ config.username = 'Gem Test'
10
+ config.avatar_url = 'http://avatar.com/discord.png'
11
+ end
12
+ end
13
+
14
+ def teardown
15
+ Discord::Notifier.setup do |config|
16
+ config.url = nil
17
+ config.username = nil
18
+ config.avatar_url = nil
19
+ config.wait = nil
20
+ end
21
+ end
22
+
23
+ def test_configuration
24
+ expected_config = Discord::Config.new 'http://test.com',
25
+ 'Gem Test',
26
+ 'http://avatar.com/discord.png',
27
+ nil
28
+
29
+ Discord::Notifier.setup do |config|
30
+ assert_equal expected_config, config
31
+ end
32
+ end
33
+
34
+ def test_has_message
35
+ assert Discord::Notifier.methods.include? :message
36
+ end
37
+
38
+ def test_message_responds_to_correct_format
39
+ form_params = nil
40
+ request_params = nil
41
+ file = test_attachment
42
+
43
+ Discord::Notifier.stub :send_form, ->(args) { form_params = args } do
44
+ Discord::Notifier.message file
45
+ end
46
+
47
+ assert form_params
48
+
49
+ Discord::Notifier.stub :send_request, ->(args) { request_params = args } do
50
+ Discord::Notifier.message "String Message"
51
+ end
52
+
53
+ assert request_params
54
+ end
55
+
56
+ def test_string_message
57
+ actual_params = nil
58
+ expected_params = {
59
+ url: 'http://test.com',
60
+ username: 'Gem Test',
61
+ avatar_url: 'http://avatar.com/discord.png',
62
+ content: 'String Message'
63
+ }
64
+
65
+ actual_params = Discord::Notifier.payload "String Message", {}
66
+ assert_equal expected_params, actual_params
67
+ end
68
+
69
+ def test_embed_message
70
+ actual_params = nil
71
+ expected_params = {
72
+ url: 'http://test.com',
73
+ username: 'Gem Test',
74
+ avatar_url: 'http://avatar.com/discord.png',
75
+ embeds: [{
76
+ title: 'Embed Message Test',
77
+ description: 'Sending an embed through Discord Notifier',
78
+ url: 'http://github.com/ianmitchell/discord_notifier',
79
+ color: 0x008000,
80
+ thumbnail: {
81
+ url: 'http://avatar.com/discord.png'
82
+ },
83
+ author: {
84
+ name: 'Ian Mitchell',
85
+ url: 'http://ianmitchell.io'
86
+ },
87
+ footer: {
88
+ text: 'Mini MiniTest Test'
89
+ },
90
+ fields: [
91
+ {
92
+ name: 'Content',
93
+ value: 'This is a content section'
94
+ },
95
+ {
96
+ name: 'Subsection',
97
+ value: 'This is a content subsection'
98
+ }
99
+ ]
100
+ }]
101
+ }
102
+
103
+ embed = Discord::Embed.new do
104
+ title 'Embed Message Test'
105
+ description 'Sending an embed through Discord Notifier'
106
+ url 'http://github.com/ianmitchell/discord_notifier'
107
+ color 0x008000
108
+ thumbnail url: 'http://avatar.com/discord.png'
109
+ author name: 'Ian Mitchell',
110
+ url: 'http://ianmitchell.io'
111
+ footer text: 'Mini MiniTest Test'
112
+ add_field name: 'Content', value: 'This is a content section'
113
+ add_field name: 'Subsection', value: 'This is a content subsection'
114
+ end
115
+
116
+ actual_params = Discord::Notifier.payload embed, {}
117
+ assert_equal expected_params, actual_params
118
+ end
119
+
120
+ def test_custom_config_message
121
+ custom_config = {
122
+ url: 'http://custom.com',
123
+ username: 'Gem Config Test',
124
+ avatar_url: 'http://avatar.com/slack.png',
125
+ wait: true
126
+ }
127
+ actual_params = nil
128
+ expected_params = {
129
+ content: 'String Message'
130
+ }.merge(custom_config)
131
+
132
+ actual_params = Discord::Notifier.payload "String Message", custom_config
133
+ assert_equal expected_params, actual_params
134
+ end
135
+
136
+ def test_multiple_embeds
137
+ actual_params = nil
138
+ expected_params = {
139
+ url: 'http://test.com',
140
+ username: 'Gem Test',
141
+ avatar_url: 'http://avatar.com/discord.png',
142
+ embeds: [
143
+ {
144
+ title: 'Embed Message Test',
145
+ description: 'Sending an embed through Discord Notifier',
146
+ url: 'http://github.com/ianmitchell/discord_notifier',
147
+ },
148
+ {
149
+ title: 'Second Embed Message Test',
150
+ description: 'Sending an embed through Discord Notifier',
151
+ url: 'http://github.com/ianmitchell/discord_notifier',
152
+ }
153
+ ]
154
+ }
155
+
156
+ embed_one = Discord::Embed.new do
157
+ title 'Embed Message Test'
158
+ description 'Sending an embed through Discord Notifier'
159
+ url 'http://github.com/ianmitchell/discord_notifier'
160
+ end
161
+
162
+ embed_two = Discord::Embed.new do
163
+ title 'Second Embed Message Test'
164
+ description 'Sending an embed through Discord Notifier'
165
+ url 'http://github.com/ianmitchell/discord_notifier'
166
+ end
167
+
168
+ actual_params = Discord::Notifier.payload [embed_one, embed_two], {}
169
+ assert_equal expected_params, actual_params
170
+ end
171
+
172
+ def test_file_attachment
173
+ file = test_attachment
174
+ actual_params = nil
175
+ expected_params = {
176
+ url: 'http://test.com',
177
+ username: 'Gem Test',
178
+ avatar_url: 'http://avatar.com/discord.png',
179
+ file: file
180
+ }
181
+
182
+ actual_params = Discord::Notifier.payload file, {}
183
+ assert_equal expected_params, actual_params
184
+ end
185
+
186
+ def test_incorrect_message_type
187
+ assert_raises ArgumentError do
188
+ Discord::Notifier.message 42
189
+ end
190
+ end
191
+
192
+ def test_endpoint
193
+ endpoint = Discord::Notifier.endpoint url: 'http://test.com'
194
+ assert endpoint.eql? URI('http://test.com')
195
+
196
+ endpoint = Discord::Notifier.endpoint url: 'http://test.com', wait: true
197
+ assert endpoint.eql? URI('http://test.com?wait=true')
198
+ end
199
+ end
@@ -0,0 +1,26 @@
1
+ require 'net/http'
2
+
3
+ # Since refinements don't work with `respond_to` which
4
+ # Minitest uses when it stubs methods, we need to monkey
5
+ # patch Net::HTTP here for our tests.
6
+ unless Net::HTTP.methods.include?(:post)
7
+ class Net::HTTP
8
+ def self.post(url, data, header = nil)
9
+ start(url.hostname, url.port,
10
+ :use_ssl => url.scheme == 'https' ) {|http|
11
+ http.post(url.path, data, header)
12
+ }
13
+ end
14
+ end
15
+ end
16
+
17
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
18
+ require 'discord_notifier'
19
+ require 'discord_notifier/version'
20
+
21
+ require 'minitest/autorun'
22
+
23
+ def test_attachment
24
+ Dir.chdir(File.dirname(__FILE__))
25
+ File.open('test_attachment.txt')
26
+ end
metadata ADDED
@@ -0,0 +1,105 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: discord-notifier-confidist
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Nicholas Schiavi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-02-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.15'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.15'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.0'
55
+ description:
56
+ email:
57
+ - nicholas@confidist.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - lib/discord/notifier.rb
63
+ - lib/discord_notifier/backports/hash.rb
64
+ - lib/discord_notifier/backports/http.rb
65
+ - lib/discord_notifier/embed.rb
66
+ - lib/discord_notifier/form_data.rb
67
+ - lib/discord_notifier/version.rb
68
+ - lib/discord_notifier_confidist.rb
69
+ - test/discord/discord_notifier/embed_test.rb
70
+ - test/discord/discord_notifier/form_data_test.rb
71
+ - test/discord/discord_notifier/version_test.rb
72
+ - test/discord/discord_notifier_test.rb
73
+ - test/test_helper.rb
74
+ homepage: https://github.com/ianmitchell/discord-notifier
75
+ licenses:
76
+ - MIT
77
+ metadata: {}
78
+ post_install_message:
79
+ rdoc_options: []
80
+ require_paths:
81
+ - lib
82
+ required_ruby_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: 2.3.0
87
+ required_rubygems_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ requirements: []
93
+ rubyforge_project:
94
+ rubygems_version: 2.6.13
95
+ signing_key:
96
+ specification_version: 4
97
+ summary: 'Forked from Ian Mitchell : A minimal wrapper for posting Discord Webhooks
98
+ and Embeds'
99
+ test_files:
100
+ - test/discord/discord_notifier_test.rb
101
+ - test/discord/discord_notifier/embed_test.rb
102
+ - test/discord/discord_notifier/version_test.rb
103
+ - test/discord/discord_notifier/form_data_test.rb
104
+ - test/test_helper.rb
105
+ has_rdoc: