vox 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.
@@ -0,0 +1,177 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'vox/http/route'
4
+ require 'vox/http/util'
5
+
6
+ module Vox
7
+ module HTTP
8
+ module Routes
9
+ # Mixin for webhook routes.
10
+ module Webhook
11
+ include Util
12
+
13
+ # Create a new webhook.
14
+ # @param channel_id [String, Integer] The ID of the channel to create this webhook in.
15
+ # @param name [String] The name for the webhook.
16
+ # @param avatar [UploadIO] Image for the default webhook avatar.
17
+ # @return [Hash<Symbol, Object>] The created [webhook](https://discord.com/developers/docs/resources/webhook#webhook-object)
18
+ # object.
19
+ # @vox.permissions MANAGE_WEBHOOKS
20
+ # @vox.api_docs https://discord.com/developers/docs/resources/webhook#create-webhook
21
+ def create_webhook(channel_id, name: :undef, avatar: :undef)
22
+ avatar_data = if avatar != :undef && !avatar.nil?
23
+ "data:#{avatar.content_type};base64,#{Base64.encode64(avatar.io.read)}"
24
+ else
25
+ :undef
26
+ end
27
+ json = filter_undef({ name: name, avatar: avatar_data })
28
+ route = Route.new(:POST, '/channels/%{channel_id}/webhooks', channel_id: channel_id)
29
+ request(route, json: json)
30
+ end
31
+
32
+ # Get webhooks associated with a channel.
33
+ # @param channel_id [String, Integer] The channel to list webhooks for.
34
+ # @return [Array<Hash<Symbol, Object>>] An array of [webhook](https://discord.com/developers/docs/resources/webhook#webhook-object)
35
+ # objects.
36
+ # @vox.permissions MANAGE_WEBHOOKS
37
+ # @vox.api_docs https://discord.com/developers/docs/resources/webhook#get-channel-webhooks
38
+ def get_channel_webhooks(channel_id)
39
+ request(Route.new(:GET, '/channels/%{channel_id}/webhooks', channel_id: channel_id))
40
+ end
41
+
42
+ # Get webhooks associated with a guild.
43
+ # @param guild_id [String, Integer] The guild to list webhooks for.
44
+ # @return [Array<Hash<Symbol, Object>>] An array of [webhook](https://discord.com/developers/docs/resources/webhook#webhook-object)
45
+ # objects.
46
+ # @vox.permissions MANAGE_WEBHOOKS
47
+ # @vox.api_docs https://discord.com/developers/docs/resources/webhook#get-guild-webhooks
48
+ def get_guild_webhooks(guild_id)
49
+ request(Route.new(:GET, '/guilds/%{guild_id}/webhooks', guild_id: guild_id))
50
+ end
51
+
52
+ # Get a webhook by ID.
53
+ # @param webhook_id [String, Integer] The ID of the desired webhook.
54
+ # @return [Hash<Symbol, Object>] The [webhook](https://discord.com/developers/docs/resources/webhook#webhook-object)
55
+ # object.
56
+ # @vox.permissions MANAGE_WEBHOOKS
57
+ # @vox.api_docs
58
+ def get_webhook(webhook_id)
59
+ request(Route.new(:GET, '/webhooks/%{webhook_id}', webhook_id: webhook_id))
60
+ end
61
+
62
+ # Get a webhook by ID and token. This does not require authentication.
63
+ # @param webhook_id [String, Integer]
64
+ # @param webhook_token [String]
65
+ # @return [Hash<Symbol, Object>] The [webhook](https://discord.com/developers/docs/resources/webhook#webhook-object)
66
+ # object.
67
+ # @vox.api_docs https://discord.com/developers/docs/resources/webhook#get-webhook-with-token
68
+ def get_webhook_with_token(webhook_id, webhook_token)
69
+ route = Route.new(:GET, '/webhooks/%{webhook_id}/%{webhook_token}',
70
+ webhook_id: webhook_id, webhook_token: webhook_token)
71
+ request(route)
72
+ end
73
+
74
+ # Modify a webhook's properties.
75
+ # @param webhook_id [String, Integer] The ID of the target webhook.
76
+ # @param name [String] The new name for the webhook.
77
+ # @param avatar [UploadIO] The new avatar for the webhook.
78
+ # @param channel_id [String, Integer] The new channel for this webhook to use.
79
+ # @return [Hash<Symbol, Object>] The modified [webhook](https://discord.com/developers/docs/resources/webhook#webhook-object)
80
+ # object.
81
+ # @vox.permissions MANAGE_WEBHOOKS
82
+ # @vox.api_docs https://discord.com/developers/docs/resources/webhook#modify-webhook
83
+ def modify_webhook(webhook_id, name: :undef, avatar: :undef, channel_id: :undef)
84
+ avatar_data = if avatar != :undef && !avatar.nil?
85
+ "data:#{avatar.content_type};base64,#{Base64.encode64(avatar.io.read)}"
86
+ else
87
+ :undef
88
+ end
89
+ json = filter_undef({ name: name, avatar: avatar_data, channel_id: channel_id })
90
+ route = Route.new(:PATCH, '/webhooks/%{webhook_id}', webhook_id: webhook_id)
91
+ request(route, json: json)
92
+ end
93
+
94
+ # Modify a webhook's properties with a token. This endpoint does not require authorization.
95
+ # @param webhook_id [String, Integer] The ID of the target webhook.
96
+ # @param webhook_token [String] The token of the target webhook.
97
+ # @param name [String] The new name for the webhook.
98
+ # @param avatar [UploadIO] The new avatar for the webhook.
99
+ # @param channel_id [String, Integer] The new channel for this webhook to use.
100
+ # @return [Hash<Symbol, Object>] The modified [webhook](https://discord.com/developers/docs/resources/webhook#webhook-object)
101
+ # object.
102
+ # @vox.api_docs https://discord.com/developers/docs/resources/webhook#modify-webhook-with-token
103
+ def modify_webhook_with_token(webhook_id, webhook_token, name: :undef, avatar: :undef, channel_id: :undef)
104
+ avatar_data = if avatar != :undef && !avatar.nil?
105
+ "data:#{avatar.content_type};base64,#{Base64.encode64(avatar.io.read)}"
106
+ else
107
+ :undef
108
+ end
109
+ json = filter_undef({ name: name, avatar: avatar_data, channel_id: channel_id })
110
+ route = Route.new(:PATCH, '/webhooks/%{webhook_id}/%{webhook_token}',
111
+ webhook_id: webhook_id, webhook_token: webhook_token)
112
+ request(route, json: json)
113
+ end
114
+
115
+ # Delete a webhook.
116
+ # @param webhook_id [String, Integer] The ID of the webhook to be deleted.
117
+ # @return [nil] Returns `nil` on success.
118
+ # @vox.permissions MANAGE_WEBHOOKS
119
+ # @vox.api_docs https://discord.com/developers/docs/resources/webhook#delete-webhook
120
+ def delete_webhook(webhook_id)
121
+ request(Route.new(:DELETE, '/webhooks/%{webhook_id}', webhook_id: webhook_id))
122
+ end
123
+
124
+ # Delete a webhook with a token. This endpoint does not require authorization.
125
+ # @param webhook_id [String, Integer] The ID of the webhook to be deleted.
126
+ # @param webhook_token [String] The token for the target webhook/
127
+ # @return [nil] Returns `nil` on success.
128
+ # @vox.api_docs https://discord.com/developers/docs/resources/webhook#delete-webhook-with-token
129
+ def delete_webhook_with_token(webhook_id, webhook_token)
130
+ route = Route.new(:DELETE, '/webhooks/%{webhook_id}/%{webhook_token}',
131
+ webhook_id: webhook_id, webhook_token: webhook_token)
132
+ request(route)
133
+ end
134
+
135
+ # Post content to a webhook.
136
+ # @param webhook_id [String, Integer] The ID of the webhook to post to.
137
+ # @param webhook_token [String] The token for the target webhook.
138
+ # @param wait [true, false] Waits for server confirmation of message send before response,
139
+ # and returns the created message body.
140
+ # @param content [String] The message contents.
141
+ # @param username [String] Override the default avatar of the webhook.
142
+ # @param avatar_url [String] Override the default avatar of the webhook.
143
+ # @param tts [true, false] If this message is TTS.
144
+ # @param file [UploadIO] The file being sent.
145
+ # @param embeds [Array<Hash<Symbol, Object>>] An array of up to 10 [embed](https://discord.com/developers/docs/resources/channel#embed-object)
146
+ # objects.
147
+ # @param allowed_mentions [Hash<Symbol, Object>] [Allowed mentions](https://discord.com/developers/docs/resources/channel#allowed-mentions-object)
148
+ # object for this message.
149
+ # @param attachments [Hash<String, UploadIO>, Array<UploadIO>] A hash in the form of `filename => upload_io` to
150
+ # be referenced in embeds via the `attachment://` URI, or an array of {UploadIO} who's filenames are derived
151
+ # from the existing UploadIO object. See [attachment:// docs](https://discord.com/developers/docs/resources/channel#create-message-using-attachments-within-embeds).
152
+ # @vox.api_docs https://discord.com/developers/docs/resources/webhook#execute-webhook
153
+ def execute_webhook(webhook_id, webhook_token, wait: :undef, content: :undef, username: :undef,
154
+ avatar_url: :undef, tts: :undef, file: :undef, embeds: :undef,
155
+ allowed_mentions: :undef, attachments: :undef)
156
+ params = filter_undef({ wait: wait })
157
+ json = filter_undef({ content: content, username: username, avatar_url: avatar_url, tts: tts, embeds: embeds,
158
+ allowed_mentions: allowed_mentions })
159
+ route = Route.new(:POST, '/webhooks/%{webhook_id}/%{webhook_token}',
160
+ webhook_id: webhook_id, webhook_token: webhook_token)
161
+
162
+ if file != :undef
163
+ data = { file: file, payload_json: MultiJson.dump(json) }
164
+ request(route, data: data, query: params)
165
+ elsif attachments != :undef
166
+ attachments = attachments.collect { |k, v| UploadIO.new(v.io, v.content_type, k) } if attachments.is_a? Hash
167
+ attach_hash = Array(0...attachments.size).zip(attachments).to_h
168
+ data = attach_hash.merge(payload_json: MultiJson.dump(json))
169
+ request(route, data: data, query: params)
170
+ else
171
+ request(route, json: json, query: params)
172
+ end
173
+ end
174
+ end
175
+ end
176
+ end
177
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'vox/http/util'
4
+
5
+ module Vox
6
+ module HTTP
7
+ # Wrapper to faraday's UploadIO that allows for an optional MIME type
8
+ class UploadIO < Faraday::UploadIO
9
+ include Util
10
+
11
+ # @param file [File, IO, String] A File, IO, or file path for the upload.
12
+ # @param mime_type [String] The MIME type for the file, if `nil` it will be
13
+ # inferred from the file path, defaulting to 'application/octet-stream'
14
+ # if no matching MIME type matches.
15
+ # @param name [String] File name, this can be omitted if the provided file
16
+ # responds to `path`.
17
+ def initialize(file, mime_type = nil, name = nil)
18
+ mime_type ||= mime_for_file(file.respond_to?(:path) ? file.path : file)
19
+ super(file, mime_type, name)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'mime/types'
4
+
5
+ module Vox
6
+ module HTTP
7
+ # @!visibility private
8
+ module Util
9
+ # Remove members from a hash that have `:undef` as values
10
+ # @example
11
+ # ```ruby
12
+ # hash = { foo: 1, bar: :undef, baz: 2 }
13
+ # filter_hash(hash)
14
+ # # => { foo: 1, baz: 2 }
15
+ # ```
16
+ # @param hash [Hash] The hash to filter `:undef` members from.
17
+ # @return [Hash] The given hash with all members with an `:undef` value removed.
18
+ # @!visibility private
19
+ def filter_undef(hash)
20
+ hash.reject { |_, v| v == :undef }
21
+ end
22
+
23
+ # Get the MIME type from a File object or path for UploadIO purposes
24
+ # @!visibility private
25
+ # @param file [File, String] File object or String for a file path.
26
+ # @return [String] Returns the MIME type for a file if any. Defaults to application/octet-stream
27
+ def mime_for_file(file)
28
+ path = file.is_a?(File) ? file.path : file
29
+ MIME::Types.type_for(path)[0] || 'application/octet-stream'
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Vox
4
+ # Overall gem version, each component also contains its own version
5
+ VERSION = '0.2.0'
6
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/vox/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'vox'
7
+ spec.version = Vox::VERSION
8
+ spec.authors = ['Matthew Carey']
9
+ spec.email = ['matthew.b.carey@gmail.com']
10
+
11
+ spec.summary = 'Discord library'
12
+ spec.description = 'Discord library'
13
+ spec.homepage = 'http://swarley.github.io/vox/'
14
+ spec.license = 'MIT'
15
+ spec.required_ruby_version = Gem::Requirement.new('>= 2.5.0')
16
+
17
+ spec.metadata['homepage_uri'] = spec.homepage
18
+ spec.metadata['source_code_uri'] = 'https://github.com/swarley/vox'
19
+ spec.metadata['changelog_uri'] = 'https://github.com/swarley/vox/blob/master/CHANGELOG.md'
20
+
21
+ # Specify which files should be added to the gem when it is released.
22
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
23
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
24
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
25
+ end
26
+
27
+ spec.bindir = 'exe'
28
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
29
+ spec.require_paths = ['lib']
30
+
31
+ spec.add_runtime_dependency 'faraday', '~> 1.0.1'
32
+ spec.add_runtime_dependency 'logging', '~> 2.3.0'
33
+ spec.add_runtime_dependency 'mime-types', '~> 3.3.1'
34
+ spec.add_runtime_dependency 'multi_json', '~> 1.15.0'
35
+ spec.add_development_dependency 'rake', '~> 12.0'
36
+ spec.add_development_dependency 'rspec', '~> 3.0'
37
+ spec.add_development_dependency 'rubocop', '~> 0.89.1'
38
+ spec.add_development_dependency 'rubocop-performance', '~> 1.7.1'
39
+ spec.add_development_dependency 'rubocop-rspec', '~> 1.42.0'
40
+ spec.add_development_dependency 'simplecov', '~> 0.19.0'
41
+ spec.add_development_dependency 'yard', '~> 0.9.25'
42
+ end
metadata ADDED
@@ -0,0 +1,234 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vox
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Matthew Carey
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2020-08-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 1.0.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 1.0.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: logging
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 2.3.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 2.3.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: mime-types
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 3.3.1
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 3.3.1
55
+ - !ruby/object:Gem::Dependency
56
+ name: multi_json
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 1.15.0
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 1.15.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '12.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '12.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '3.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '3.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 0.89.1
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 0.89.1
111
+ - !ruby/object:Gem::Dependency
112
+ name: rubocop-performance
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 1.7.1
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 1.7.1
125
+ - !ruby/object:Gem::Dependency
126
+ name: rubocop-rspec
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: 1.42.0
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: 1.42.0
139
+ - !ruby/object:Gem::Dependency
140
+ name: simplecov
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: 0.19.0
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: 0.19.0
153
+ - !ruby/object:Gem::Dependency
154
+ name: yard
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: 0.9.25
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: 0.9.25
167
+ description: Discord library
168
+ email:
169
+ - matthew.b.carey@gmail.com
170
+ executables: []
171
+ extensions: []
172
+ extra_rdoc_files: []
173
+ files:
174
+ - ".github/workflows/deploy_docs.yml"
175
+ - ".github/workflows/rspec.yml"
176
+ - ".github/workflows/rubocop.yml"
177
+ - ".github/workflows/yard.yml"
178
+ - ".gitignore"
179
+ - ".rspec"
180
+ - ".rubocop.yml"
181
+ - ".yardopts"
182
+ - CHANGELOG.md
183
+ - CODE_OF_CONDUCT.md
184
+ - Gemfile
185
+ - LICENSE.md
186
+ - README.md
187
+ - Rakefile
188
+ - lib/vox.rb
189
+ - lib/vox/http/client.rb
190
+ - lib/vox/http/error.rb
191
+ - lib/vox/http/middleware.rb
192
+ - lib/vox/http/middleware/log_formatter.rb
193
+ - lib/vox/http/middleware/rate_limiter.rb
194
+ - lib/vox/http/route.rb
195
+ - lib/vox/http/routes.rb
196
+ - lib/vox/http/routes/audit_log.rb
197
+ - lib/vox/http/routes/channel.rb
198
+ - lib/vox/http/routes/emoji.rb
199
+ - lib/vox/http/routes/guild.rb
200
+ - lib/vox/http/routes/invite.rb
201
+ - lib/vox/http/routes/user.rb
202
+ - lib/vox/http/routes/voice.rb
203
+ - lib/vox/http/routes/webhook.rb
204
+ - lib/vox/http/upload_io.rb
205
+ - lib/vox/http/util.rb
206
+ - lib/vox/version.rb
207
+ - vox.gemspec
208
+ homepage: http://swarley.github.io/vox/
209
+ licenses:
210
+ - MIT
211
+ metadata:
212
+ homepage_uri: http://swarley.github.io/vox/
213
+ source_code_uri: https://github.com/swarley/vox
214
+ changelog_uri: https://github.com/swarley/vox/blob/master/CHANGELOG.md
215
+ post_install_message:
216
+ rdoc_options: []
217
+ require_paths:
218
+ - lib
219
+ required_ruby_version: !ruby/object:Gem::Requirement
220
+ requirements:
221
+ - - ">="
222
+ - !ruby/object:Gem::Version
223
+ version: 2.5.0
224
+ required_rubygems_version: !ruby/object:Gem::Requirement
225
+ requirements:
226
+ - - ">="
227
+ - !ruby/object:Gem::Version
228
+ version: '0'
229
+ requirements: []
230
+ rubygems_version: 3.0.3
231
+ signing_key:
232
+ specification_version: 4
233
+ summary: Discord library
234
+ test_files: []