vox 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []