discordrb 2.0.4 → 2.1.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.
Potentially problematic release.
This version of discordrb might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -0
- data/LICENSE.txt +1 -1
- data/lib/discordrb.rb +0 -7
- data/lib/discordrb/api.rb +60 -48
- data/lib/discordrb/bot.rb +23 -6
- data/lib/discordrb/commands/command_bot.rb +41 -7
- data/lib/discordrb/commands/container.rb +5 -0
- data/lib/discordrb/commands/parser.rb +3 -0
- data/lib/discordrb/container.rb +15 -0
- data/lib/discordrb/data.rb +60 -4
- data/lib/discordrb/events/lifetime.rb +6 -0
- data/lib/discordrb/permissions.rb +3 -1
- data/lib/discordrb/version.rb +1 -1
- metadata +2 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: e61613220092ee639a9cd4db8f5fad0d7485b5a8
         | 
| 4 | 
            +
              data.tar.gz: 008902a804d2938eff3d369bb500d6a755ccb605
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: fedc89d8c0ccb3229425382413e2ce4bb946e676924542092290985f4ba11b2d5e402ce210df590fbeb29393536593ef8e09d5189cd795f225b40156fa052e55
         | 
| 7 | 
            +
              data.tar.gz: 9793bdc3c7ed44daa090145e0bf693c0ab12070ebe1e73f89204a0c8423c6d7e734461caef25b461fee1a0893a1c9717c7fda6dc2fbc7badbe458eeed44e2038
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,5 +1,19 @@ | |
| 1 1 | 
             
            # Changelog
         | 
| 2 2 |  | 
| 3 | 
            +
            ## 2.1.0
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            - API support for the April 29 Discord update, which was the first feature update in a while with more than a few additions to the API, was added. This includes: ([#111](https://github.com/meew0/discordrb/pull/111))
         | 
| 6 | 
            +
              - Members' nicknames can now be set and read (`Member#nick`) and updates to them are being tracked.
         | 
| 7 | 
            +
              - Roles now have a `mentionable?` property and a `mention` utility method.
         | 
| 8 | 
            +
              - `Message` now tracks a message's role mentions.
         | 
| 9 | 
            +
            - The internal REST rate limit handler was updated:
         | 
| 10 | 
            +
              - It now tracks message rate limits server wide to properly handle new bot account rate limits. ([#100](https://github.com/meew0/discordrb/issues/100))
         | 
| 11 | 
            +
              - It now keeps track of all requests, even those that are known not to be rate limited (it just won't do anything to them). This allows for more flexibility should future rate limits be added.
         | 
| 12 | 
            +
            - Guild sharding is now supported using the optional `shard_id` and `num_shards` to bot initializers. Read about it here: https://github.com/hammerandchisel/discord-api-docs/issues/17 ([#98](https://github.com/meew0/discordrb/issues/98))
         | 
| 13 | 
            +
            - Commands can now require users to have specific action permissions to be able to execute them using the `:required_permissions` attribute. ([#104](https://github.com/meew0/discordrb/issues/104) / [#112](https://github.com/meew0/discordrb/pull/112))
         | 
| 14 | 
            +
            - A `heartbeat` event was added that gets triggered every now and then to allow for roughly periodic actions. ([#110](https://github.com/meew0/discordrb/pull/110))
         | 
| 15 | 
            +
            - Prefixes are now more flexible in the format they can have - arrays and callables are now allowed as well. Read the documentation for more info.([#107](https://github.com/meew0/discordrb/issues/107) / [#109](https://github.com/meew0/discordrb/pull/109))
         | 
| 16 | 
            +
             | 
| 3 17 | 
             
            ## 2.0.4
         | 
| 4 18 |  | 
| 5 19 | 
             
            - Added a utility method `Invite#url` ([#86](https://github.com/meew0/discordrb/issues/86)/[#101](https://github.com/meew0/discordrb/pull/101), thanks @PoVa)
         | 
    
        data/LICENSE.txt
    CHANGED
    
    
    
        data/lib/discordrb.rb
    CHANGED
    
    | @@ -1,12 +1,5 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            -
            unless ENV['DISCORDRB_V2_MESSAGE']
         | 
| 4 | 
            -
              puts "You're using version 2 of discordrb which has some breaking changes!"
         | 
| 5 | 
            -
              puts "Don't worry if your bot crashes, you can find a list and migration advice here:"
         | 
| 6 | 
            -
              puts ' https://github.com/meew0/discordrb/blob/master/CHANGELOG.md#200'
         | 
| 7 | 
            -
              puts 'This message will go away in version 2.1 or can be disabled by setting the DISCORDRB_V2_MESSAGE environment variable.'
         | 
| 8 | 
            -
            end
         | 
| 9 | 
            -
             | 
| 10 3 | 
             
            require 'discordrb/version'
         | 
| 11 4 | 
             
            require 'discordrb/bot'
         | 
| 12 5 | 
             
            require 'discordrb/commands/command_bot'
         | 
    
        data/lib/discordrb/api.rb
    CHANGED
    
    | @@ -43,9 +43,7 @@ module Discordrb::API | |
| 43 43 |  | 
| 44 44 | 
             
              # Resets all rate limit mutexes
         | 
| 45 45 | 
             
              def reset_mutexes
         | 
| 46 | 
            -
                @mutexes = {
         | 
| 47 | 
            -
                  message: Mutex.new
         | 
| 48 | 
            -
                }
         | 
| 46 | 
            +
                @mutexes = {}
         | 
| 49 47 | 
             
              end
         | 
| 50 48 |  | 
| 51 49 | 
             
              # Performs a RestClient request.
         | 
| @@ -68,6 +66,8 @@ module Discordrb::API | |
| 68 66 |  | 
| 69 67 | 
             
                begin
         | 
| 70 68 | 
             
                  if key
         | 
| 69 | 
            +
                    @mutexes[key] = Mutex.new unless @mutexes[key]
         | 
| 70 | 
            +
             | 
| 71 71 | 
             
                    # Lock and unlock, i. e. wait for the mutex to unlock and don't do anything with it afterwards
         | 
| 72 72 | 
             
                    @mutexes[key].lock
         | 
| 73 73 | 
             
                    @mutexes[key].unlock
         | 
| @@ -106,7 +106,7 @@ module Discordrb::API | |
| 106 106 | 
             
              # Ban a user from a server and delete their messages from the last message_days days
         | 
| 107 107 | 
             
              def ban_user(token, server_id, user_id, message_days)
         | 
| 108 108 | 
             
                request(
         | 
| 109 | 
            -
                   | 
| 109 | 
            +
                  __method__,
         | 
| 110 110 | 
             
                  :put,
         | 
| 111 111 | 
             
                  "#{api_base}/guilds/#{server_id}/bans/#{user_id}?delete-message-days=#{message_days}",
         | 
| 112 112 | 
             
                  nil,
         | 
| @@ -117,7 +117,7 @@ module Discordrb::API | |
| 117 117 | 
             
              # Unban a user from a server
         | 
| 118 118 | 
             
              def unban_user(token, server_id, user_id)
         | 
| 119 119 | 
             
                request(
         | 
| 120 | 
            -
                   | 
| 120 | 
            +
                  __method__,
         | 
| 121 121 | 
             
                  :delete,
         | 
| 122 122 | 
             
                  "#{api_base}/guilds/#{server_id}/bans/#{user_id}",
         | 
| 123 123 | 
             
                  Authorization: token
         | 
| @@ -127,7 +127,7 @@ module Discordrb::API | |
| 127 127 | 
             
              # Kick a user from a server
         | 
| 128 128 | 
             
              def kick_user(token, server_id, user_id)
         | 
| 129 129 | 
             
                request(
         | 
| 130 | 
            -
                   | 
| 130 | 
            +
                  __method__,
         | 
| 131 131 | 
             
                  :delete,
         | 
| 132 132 | 
             
                  "#{api_base}/guilds/#{server_id}/members/#{user_id}",
         | 
| 133 133 | 
             
                  Authorization: token
         | 
| @@ -137,7 +137,7 @@ module Discordrb::API | |
| 137 137 | 
             
              # Move a user to a different voice channel
         | 
| 138 138 | 
             
              def move_user(token, server_id, user_id, channel_id)
         | 
| 139 139 | 
             
                request(
         | 
| 140 | 
            -
                   | 
| 140 | 
            +
                  __method__,
         | 
| 141 141 | 
             
                  :patch,
         | 
| 142 142 | 
             
                  "#{api_base}/guilds/#{server_id}/members/#{user_id}",
         | 
| 143 143 | 
             
                  { channel_id: channel_id }.to_json,
         | 
| @@ -146,10 +146,22 @@ module Discordrb::API | |
| 146 146 | 
             
                )
         | 
| 147 147 | 
             
              end
         | 
| 148 148 |  | 
| 149 | 
            +
              # Change a user's nickname on a server
         | 
| 150 | 
            +
              def change_nickname(token, server_id, user_id, nick)
         | 
| 151 | 
            +
                request(
         | 
| 152 | 
            +
                  __method__,
         | 
| 153 | 
            +
                  :patch,
         | 
| 154 | 
            +
                  "#{api_base}/guilds/#{server_id}/members/#{user_id}",
         | 
| 155 | 
            +
                  { nick: nick }.to_json,
         | 
| 156 | 
            +
                  Authorization: token,
         | 
| 157 | 
            +
                  content_type: :json
         | 
| 158 | 
            +
                )
         | 
| 159 | 
            +
              end
         | 
| 160 | 
            +
             | 
| 149 161 | 
             
              # Get a server's banned users
         | 
| 150 162 | 
             
              def bans(token, server_id)
         | 
| 151 163 | 
             
                request(
         | 
| 152 | 
            -
                   | 
| 164 | 
            +
                  __method__,
         | 
| 153 165 | 
             
                  :get,
         | 
| 154 166 | 
             
                  "#{api_base}/guilds/#{server_id}/bans",
         | 
| 155 167 | 
             
                  Authorization: token
         | 
| @@ -159,7 +171,7 @@ module Discordrb::API | |
| 159 171 | 
             
              # Login to the server
         | 
| 160 172 | 
             
              def login(email, password)
         | 
| 161 173 | 
             
                request(
         | 
| 162 | 
            -
                   | 
| 174 | 
            +
                  __method__,
         | 
| 163 175 | 
             
                  :post,
         | 
| 164 176 | 
             
                  "#{api_base}/auth/login",
         | 
| 165 177 | 
             
                  email: email,
         | 
| @@ -170,7 +182,7 @@ module Discordrb::API | |
| 170 182 | 
             
              # Logout from the server
         | 
| 171 183 | 
             
              def logout(token)
         | 
| 172 184 | 
             
                request(
         | 
| 173 | 
            -
                   | 
| 185 | 
            +
                  __method__,
         | 
| 174 186 | 
             
                  :post,
         | 
| 175 187 | 
             
                  "#{api_base}/auth/logout",
         | 
| 176 188 | 
             
                  nil,
         | 
| @@ -181,7 +193,7 @@ module Discordrb::API | |
| 181 193 | 
             
              # Create an OAuth application
         | 
| 182 194 | 
             
              def create_oauth_application(token, name, redirect_uris)
         | 
| 183 195 | 
             
                request(
         | 
| 184 | 
            -
                   | 
| 196 | 
            +
                  __method__,
         | 
| 185 197 | 
             
                  :post,
         | 
| 186 198 | 
             
                  "#{api_base}/oauth2/applications",
         | 
| 187 199 | 
             
                  { name: name, redirect_uris: redirect_uris }.to_json,
         | 
| @@ -193,7 +205,7 @@ module Discordrb::API | |
| 193 205 | 
             
              # Change an OAuth application's properties
         | 
| 194 206 | 
             
              def update_oauth_application(token, name, redirect_uris, description = '', icon = nil)
         | 
| 195 207 | 
             
                request(
         | 
| 196 | 
            -
                   | 
| 208 | 
            +
                  __method__,
         | 
| 197 209 | 
             
                  :put,
         | 
| 198 210 | 
             
                  "#{api_base}/oauth2/applications",
         | 
| 199 211 | 
             
                  { name: name, redirect_uris: redirect_uris, description: description, icon: icon }.to_json,
         | 
| @@ -205,7 +217,7 @@ module Discordrb::API | |
| 205 217 | 
             
              # Create a server
         | 
| 206 218 | 
             
              def create_server(token, name, region = :london)
         | 
| 207 219 | 
             
                request(
         | 
| 208 | 
            -
                   | 
| 220 | 
            +
                  __method__,
         | 
| 209 221 | 
             
                  :post,
         | 
| 210 222 | 
             
                  "#{api_base}/guilds",
         | 
| 211 223 | 
             
                  { name: name, region: region.to_s }.to_json,
         | 
| @@ -217,7 +229,7 @@ module Discordrb::API | |
| 217 229 | 
             
              # Update a server
         | 
| 218 230 | 
             
              def update_server(token, server_id, name, region, icon, afk_channel_id, afk_timeout)
         | 
| 219 231 | 
             
                request(
         | 
| 220 | 
            -
                   | 
| 232 | 
            +
                  __method__,
         | 
| 221 233 | 
             
                  :patch,
         | 
| 222 234 | 
             
                  "#{api_base}/guilds/#{server_id}",
         | 
| 223 235 | 
             
                  { name: name, region: region, icon: icon, afk_channel_id: afk_channel_id, afk_timeout: afk_timeout }.to_json,
         | 
| @@ -229,7 +241,7 @@ module Discordrb::API | |
| 229 241 | 
             
              # Transfer server ownership
         | 
| 230 242 | 
             
              def transfer_ownership(token, server_id, user_id)
         | 
| 231 243 | 
             
                request(
         | 
| 232 | 
            -
                   | 
| 244 | 
            +
                  __method__,
         | 
| 233 245 | 
             
                  :patch,
         | 
| 234 246 | 
             
                  "#{api_base}/guilds/#{server_id}",
         | 
| 235 247 | 
             
                  { owner_id: user_id }.to_json,
         | 
| @@ -241,7 +253,7 @@ module Discordrb::API | |
| 241 253 | 
             
              # Delete a server
         | 
| 242 254 | 
             
              def delete_server(token, server_id)
         | 
| 243 255 | 
             
                request(
         | 
| 244 | 
            -
                   | 
| 256 | 
            +
                  __method__,
         | 
| 245 257 | 
             
                  :delete,
         | 
| 246 258 | 
             
                  "#{api_base}/guilds/#{server_id}",
         | 
| 247 259 | 
             
                  Authorization: token
         | 
| @@ -251,7 +263,7 @@ module Discordrb::API | |
| 251 263 | 
             
              # Leave a server
         | 
| 252 264 | 
             
              def leave_server(token, server_id)
         | 
| 253 265 | 
             
                request(
         | 
| 254 | 
            -
                   | 
| 266 | 
            +
                  __method__,
         | 
| 255 267 | 
             
                  :delete,
         | 
| 256 268 | 
             
                  "#{api_base}/users/@me/guilds/#{server_id}",
         | 
| 257 269 | 
             
                  Authorization: token
         | 
| @@ -261,7 +273,7 @@ module Discordrb::API | |
| 261 273 | 
             
              # Get a channel's data
         | 
| 262 274 | 
             
              def channel(token, channel_id)
         | 
| 263 275 | 
             
                request(
         | 
| 264 | 
            -
                   | 
| 276 | 
            +
                  __method__,
         | 
| 265 277 | 
             
                  :get,
         | 
| 266 278 | 
             
                  "#{api_base}/channels/#{channel_id}",
         | 
| 267 279 | 
             
                  Authorization: token
         | 
| @@ -271,7 +283,7 @@ module Discordrb::API | |
| 271 283 | 
             
              # Get a server's data
         | 
| 272 284 | 
             
              def server(token, server_id)
         | 
| 273 285 | 
             
                request(
         | 
| 274 | 
            -
                   | 
| 286 | 
            +
                  __method__,
         | 
| 275 287 | 
             
                  :get,
         | 
| 276 288 | 
             
                  "#{api_base}/guilds/#{server_id}",
         | 
| 277 289 | 
             
                  Authorization: token
         | 
| @@ -281,7 +293,7 @@ module Discordrb::API | |
| 281 293 | 
             
              # Get a member's data
         | 
| 282 294 | 
             
              def member(token, server_id, user_id)
         | 
| 283 295 | 
             
                request(
         | 
| 284 | 
            -
                   | 
| 296 | 
            +
                  __method__,
         | 
| 285 297 | 
             
                  :get,
         | 
| 286 298 | 
             
                  "#{api_base}/guilds/#{server_id}/members/#{user_id}",
         | 
| 287 299 | 
             
                  Authorization: token
         | 
| @@ -291,7 +303,7 @@ module Discordrb::API | |
| 291 303 | 
             
              # Create a channel
         | 
| 292 304 | 
             
              def create_channel(token, server_id, name, type)
         | 
| 293 305 | 
             
                request(
         | 
| 294 | 
            -
                   | 
| 306 | 
            +
                  __method__,
         | 
| 295 307 | 
             
                  :post,
         | 
| 296 308 | 
             
                  "#{api_base}/guilds/#{server_id}/channels",
         | 
| 297 309 | 
             
                  { name: name, type: type }.to_json,
         | 
| @@ -303,7 +315,7 @@ module Discordrb::API | |
| 303 315 | 
             
              # Update a channel's data
         | 
| 304 316 | 
             
              def update_channel(token, channel_id, name, topic, position = 0)
         | 
| 305 317 | 
             
                request(
         | 
| 306 | 
            -
                   | 
| 318 | 
            +
                  __method__,
         | 
| 307 319 | 
             
                  :patch,
         | 
| 308 320 | 
             
                  "#{api_base}/channels/#{channel_id}",
         | 
| 309 321 | 
             
                  { name: name, position: position, topic: topic }.to_json,
         | 
| @@ -315,7 +327,7 @@ module Discordrb::API | |
| 315 327 | 
             
              # Delete a channel
         | 
| 316 328 | 
             
              def delete_channel(token, channel_id)
         | 
| 317 329 | 
             
                request(
         | 
| 318 | 
            -
                   | 
| 330 | 
            +
                  __method__,
         | 
| 319 331 | 
             
                  :delete,
         | 
| 320 332 | 
             
                  "#{api_base}/channels/#{channel_id}",
         | 
| 321 333 | 
             
                  Authorization: token
         | 
| @@ -325,7 +337,7 @@ module Discordrb::API | |
| 325 337 | 
             
              # Join a server using an invite
         | 
| 326 338 | 
             
              def join_server(token, invite_code)
         | 
| 327 339 | 
             
                request(
         | 
| 328 | 
            -
                   | 
| 340 | 
            +
                  __method__,
         | 
| 329 341 | 
             
                  :post,
         | 
| 330 342 | 
             
                  "#{api_base}/invite/#{invite_code}",
         | 
| 331 343 | 
             
                  nil,
         | 
| @@ -336,7 +348,7 @@ module Discordrb::API | |
| 336 348 | 
             
              # Resolve an invite
         | 
| 337 349 | 
             
              def resolve_invite(token, invite_code)
         | 
| 338 350 | 
             
                request(
         | 
| 339 | 
            -
                   | 
| 351 | 
            +
                  __method__,
         | 
| 340 352 | 
             
                  :get,
         | 
| 341 353 | 
             
                  "#{api_base}/invite/#{invite_code}",
         | 
| 342 354 | 
             
                  Authorization: token
         | 
| @@ -346,7 +358,7 @@ module Discordrb::API | |
| 346 358 | 
             
              # Create a private channel
         | 
| 347 359 | 
             
              def create_private(token, bot_user_id, user_id)
         | 
| 348 360 | 
             
                request(
         | 
| 349 | 
            -
                   | 
| 361 | 
            +
                  __method__,
         | 
| 350 362 | 
             
                  :post,
         | 
| 351 363 | 
             
                  "#{api_base}/users/#{bot_user_id}/channels",
         | 
| 352 364 | 
             
                  { recipient_id: user_id }.to_json,
         | 
| @@ -360,7 +372,7 @@ module Discordrb::API | |
| 360 372 | 
             
              # Create an instant invite from a server or a channel id
         | 
| 361 373 | 
             
              def create_invite(token, channel_id, max_age = 0, max_uses = 0, temporary = false, xkcd = false)
         | 
| 362 374 | 
             
                request(
         | 
| 363 | 
            -
                   | 
| 375 | 
            +
                  __method__,
         | 
| 364 376 | 
             
                  :post,
         | 
| 365 377 | 
             
                  "#{api_base}/channels/#{channel_id}/invites",
         | 
| 366 378 | 
             
                  { max_age: max_age, max_uses: max_uses, temporary: temporary, xkcdpass: xkcd }.to_json,
         | 
| @@ -372,7 +384,7 @@ module Discordrb::API | |
| 372 384 | 
             
              # Delete an invite by code
         | 
| 373 385 | 
             
              def delete_invite(token, code)
         | 
| 374 386 | 
             
                request(
         | 
| 375 | 
            -
                   | 
| 387 | 
            +
                  __method__,
         | 
| 376 388 | 
             
                  :delete,
         | 
| 377 389 | 
             
                  "#{api_base}/invites/#{code}",
         | 
| 378 390 | 
             
                  Authorization: token
         | 
| @@ -380,9 +392,9 @@ module Discordrb::API | |
| 380 392 | 
             
              end
         | 
| 381 393 |  | 
| 382 394 | 
             
              # Send a message to a channel
         | 
| 383 | 
            -
              def send_message(token, channel_id, message, mentions = [], tts = false)
         | 
| 395 | 
            +
              def send_message(token, channel_id, message, mentions = [], tts = false, guild_id = nil)
         | 
| 384 396 | 
             
                request(
         | 
| 385 | 
            -
                   | 
| 397 | 
            +
                  "message-#{guild_id}".to_sym,
         | 
| 386 398 | 
             
                  :post,
         | 
| 387 399 | 
             
                  "#{api_base}/channels/#{channel_id}/messages",
         | 
| 388 400 | 
             
                  { content: message, mentions: mentions, tts: tts }.to_json,
         | 
| @@ -396,7 +408,7 @@ module Discordrb::API | |
| 396 408 | 
             
              # Delete a message
         | 
| 397 409 | 
             
              def delete_message(token, channel_id, message_id)
         | 
| 398 410 | 
             
                request(
         | 
| 399 | 
            -
                   | 
| 411 | 
            +
                  __method__,
         | 
| 400 412 | 
             
                  :delete,
         | 
| 401 413 | 
             
                  "#{api_base}/channels/#{channel_id}/messages/#{message_id}",
         | 
| 402 414 | 
             
                  Authorization: token
         | 
| @@ -420,7 +432,7 @@ module Discordrb::API | |
| 420 432 | 
             
              # so this is an easy way to catch up on messages
         | 
| 421 433 | 
             
              def acknowledge_message(token, channel_id, message_id)
         | 
| 422 434 | 
             
                request(
         | 
| 423 | 
            -
                   | 
| 435 | 
            +
                  __method__,
         | 
| 424 436 | 
             
                  :post,
         | 
| 425 437 | 
             
                  "#{api_base}/channels/#{channel_id}/messages/#{message_id}/ack",
         | 
| 426 438 | 
             
                  nil,
         | 
| @@ -431,7 +443,7 @@ module Discordrb::API | |
| 431 443 | 
             
              # Send a file as a message to a channel
         | 
| 432 444 | 
             
              def send_file(token, channel_id, file)
         | 
| 433 445 | 
             
                request(
         | 
| 434 | 
            -
                   | 
| 446 | 
            +
                  __method__,
         | 
| 435 447 | 
             
                  :post,
         | 
| 436 448 | 
             
                  "#{api_base}/channels/#{channel_id}/messages",
         | 
| 437 449 | 
             
                  { file: file },
         | 
| @@ -442,7 +454,7 @@ module Discordrb::API | |
| 442 454 | 
             
              # Create a role (parameters such as name and colour will have to be set by update_role afterwards)
         | 
| 443 455 | 
             
              def create_role(token, server_id)
         | 
| 444 456 | 
             
                request(
         | 
| 445 | 
            -
                   | 
| 457 | 
            +
                  __method__,
         | 
| 446 458 | 
             
                  :post,
         | 
| 447 459 | 
             
                  "#{api_base}/guilds/#{server_id}/roles",
         | 
| 448 460 | 
             
                  nil,
         | 
| @@ -456,7 +468,7 @@ module Discordrb::API | |
| 456 468 | 
             
              # connecting to voice, speaking and voice activity (push-to-talk isn't mandatory)
         | 
| 457 469 | 
             
              def update_role(token, server_id, role_id, name, colour, hoist = false, packed_permissions = 36_953_089)
         | 
| 458 470 | 
             
                request(
         | 
| 459 | 
            -
                   | 
| 471 | 
            +
                  __method__,
         | 
| 460 472 | 
             
                  :patch,
         | 
| 461 473 | 
             
                  "#{api_base}/guilds/#{server_id}/roles/#{role_id}",
         | 
| 462 474 | 
             
                  { color: colour, name: name, hoist: hoist, permissions: packed_permissions }.to_json,
         | 
| @@ -468,7 +480,7 @@ module Discordrb::API | |
| 468 480 | 
             
              # Delete a role
         | 
| 469 481 | 
             
              def delete_role(token, server_id, role_id)
         | 
| 470 482 | 
             
                request(
         | 
| 471 | 
            -
                   | 
| 483 | 
            +
                  __method__,
         | 
| 472 484 | 
             
                  :delete,
         | 
| 473 485 | 
             
                  "#{api_base}/guilds/#{server_id}/roles/#{role_id}",
         | 
| 474 486 | 
             
                  Authorization: token
         | 
| @@ -478,7 +490,7 @@ module Discordrb::API | |
| 478 490 | 
             
              # Update a user's roles
         | 
| 479 491 | 
             
              def update_user_roles(token, server_id, user_id, roles)
         | 
| 480 492 | 
             
                request(
         | 
| 481 | 
            -
                   | 
| 493 | 
            +
                  __method__,
         | 
| 482 494 | 
             
                  :patch,
         | 
| 483 495 | 
             
                  "#{api_base}/guilds/#{server_id}/members/#{user_id}",
         | 
| 484 496 | 
             
                  { roles: roles }.to_json,
         | 
| @@ -490,7 +502,7 @@ module Discordrb::API | |
| 490 502 | 
             
              # Update a user's permission overrides in a channel
         | 
| 491 503 | 
             
              def update_user_overrides(token, channel_id, user_id, allow, deny)
         | 
| 492 504 | 
             
                request(
         | 
| 493 | 
            -
                   | 
| 505 | 
            +
                  __method__,
         | 
| 494 506 | 
             
                  :put,
         | 
| 495 507 | 
             
                  "#{api_base}/channels/#{channel_id}/permissions/#{user_id}",
         | 
| 496 508 | 
             
                  { type: 'member', id: user_id, allow: allow, deny: deny }.to_json,
         | 
| @@ -502,7 +514,7 @@ module Discordrb::API | |
| 502 514 | 
             
              # Update a role's permission overrides in a channel
         | 
| 503 515 | 
             
              def update_role_overrides(token, channel_id, role_id, allow, deny)
         | 
| 504 516 | 
             
                request(
         | 
| 505 | 
            -
                   | 
| 517 | 
            +
                  __method__,
         | 
| 506 518 | 
             
                  :put,
         | 
| 507 519 | 
             
                  "#{api_base}/channels/#{channel_id}/permissions/#{role_id}",
         | 
| 508 520 | 
             
                  { type: 'role', id: role_id, allow: allow, deny: deny }.to_json,
         | 
| @@ -514,7 +526,7 @@ module Discordrb::API | |
| 514 526 | 
             
              # Get the gateway to be used
         | 
| 515 527 | 
             
              def gateway(token)
         | 
| 516 528 | 
             
                request(
         | 
| 517 | 
            -
                   | 
| 529 | 
            +
                  __method__,
         | 
| 518 530 | 
             
                  :get,
         | 
| 519 531 | 
             
                  "#{api_base}/gateway",
         | 
| 520 532 | 
             
                  Authorization: token
         | 
| @@ -524,7 +536,7 @@ module Discordrb::API | |
| 524 536 | 
             
              # Validate a token (this request will fail if the token is invalid)
         | 
| 525 537 | 
             
              def validate_token(token)
         | 
| 526 538 | 
             
                request(
         | 
| 527 | 
            -
                   | 
| 539 | 
            +
                  __method__,
         | 
| 528 540 | 
             
                  :post,
         | 
| 529 541 | 
             
                  "#{api_base}/auth/login",
         | 
| 530 542 | 
             
                  {}.to_json,
         | 
| @@ -536,7 +548,7 @@ module Discordrb::API | |
| 536 548 | 
             
              # Start typing (needs to be resent every 5 seconds to keep up the typing)
         | 
| 537 549 | 
             
              def start_typing(token, channel_id)
         | 
| 538 550 | 
             
                request(
         | 
| 539 | 
            -
                   | 
| 551 | 
            +
                  __method__,
         | 
| 540 552 | 
             
                  :post,
         | 
| 541 553 | 
             
                  "#{api_base}/channels/#{channel_id}/typing",
         | 
| 542 554 | 
             
                  nil,
         | 
| @@ -547,7 +559,7 @@ module Discordrb::API | |
| 547 559 | 
             
              # Get user data
         | 
| 548 560 | 
             
              def user(token, user_id)
         | 
| 549 561 | 
             
                request(
         | 
| 550 | 
            -
                   | 
| 562 | 
            +
                  __method__,
         | 
| 551 563 | 
             
                  :get,
         | 
| 552 564 | 
             
                  "#{api_base}/users/#{user_id}",
         | 
| 553 565 | 
             
                  Authorization: token
         | 
| @@ -557,7 +569,7 @@ module Discordrb::API | |
| 557 569 | 
             
              # Get profile data
         | 
| 558 570 | 
             
              def profile(token)
         | 
| 559 571 | 
             
                request(
         | 
| 560 | 
            -
                   | 
| 572 | 
            +
                  __method__,
         | 
| 561 573 | 
             
                  :get,
         | 
| 562 574 | 
             
                  "#{api_base}/users/@me",
         | 
| 563 575 | 
             
                  Authorization: token
         | 
| @@ -567,7 +579,7 @@ module Discordrb::API | |
| 567 579 | 
             
              # Get information about a user's connections
         | 
| 568 580 | 
             
              def connections(token)
         | 
| 569 581 | 
             
                request(
         | 
| 570 | 
            -
                   | 
| 582 | 
            +
                  __method__,
         | 
| 571 583 | 
             
                  :get,
         | 
| 572 584 | 
             
                  "#{api_base}/users/@me/connections",
         | 
| 573 585 | 
             
                  Authorization: token
         | 
| @@ -577,7 +589,7 @@ module Discordrb::API | |
| 577 589 | 
             
              # Update user data
         | 
| 578 590 | 
             
              def update_user(token, email, password, new_username, avatar, new_password = nil)
         | 
| 579 591 | 
             
                request(
         | 
| 580 | 
            -
                   | 
| 592 | 
            +
                  __method__,
         | 
| 581 593 | 
             
                  :patch,
         | 
| 582 594 | 
             
                  "#{api_base}/users/@me",
         | 
| 583 595 | 
             
                  { avatar: avatar, email: email, new_password: new_password, password: password, username: new_username }.to_json,
         | 
| @@ -589,7 +601,7 @@ module Discordrb::API | |
| 589 601 | 
             
              # Get the servers a user is connected to
         | 
| 590 602 | 
             
              def servers(token)
         | 
| 591 603 | 
             
                request(
         | 
| 592 | 
            -
                   | 
| 604 | 
            +
                  __method__,
         | 
| 593 605 | 
             
                  :get,
         | 
| 594 606 | 
             
                  "#{api_base}/users/@me/guilds",
         | 
| 595 607 | 
             
                  Authorization: token
         | 
| @@ -599,7 +611,7 @@ module Discordrb::API | |
| 599 611 | 
             
              # Get a list of messages from a channel's history
         | 
| 600 612 | 
             
              def channel_log(token, channel_id, amount, before = nil, after = nil)
         | 
| 601 613 | 
             
                request(
         | 
| 602 | 
            -
                   | 
| 614 | 
            +
                  __method__,
         | 
| 603 615 | 
             
                  :get,
         | 
| 604 616 | 
             
                  "#{api_base}/channels/#{channel_id}/messages?limit=#{amount}#{"&before=#{before}" if before}#{"&after=#{after}" if after}",
         | 
| 605 617 | 
             
                  Authorization: token
         | 
    
        data/lib/discordrb/bot.rb
    CHANGED
    
    | @@ -109,6 +109,9 @@ module Discordrb | |
| 109 109 | 
             
                # same codebase. Not required but I recommend setting it anyway.
         | 
| 110 110 | 
             
                attr_accessor :name
         | 
| 111 111 |  | 
| 112 | 
            +
                # @return [Array(Integer, Integer)] the current shard key
         | 
| 113 | 
            +
                attr_reader :shard_key
         | 
| 114 | 
            +
             | 
| 112 115 | 
             
                include EventContainer
         | 
| 113 116 | 
             
                include Cache
         | 
| 114 117 |  | 
| @@ -145,10 +148,15 @@ module Discordrb | |
| 145 148 | 
             
                #   Useful for very large bots running in debug or verbose log_mode.
         | 
| 146 149 | 
             
                # @param parse_self [true, false] Whether the bot should react on its own messages. It's best to turn this off
         | 
| 147 150 | 
             
                #   unless you really need this so you don't inadvertently create infinite loops.
         | 
| 151 | 
            +
                # @param shard_id [Integer] The number of the shard this bot should handle. See
         | 
| 152 | 
            +
                #   https://github.com/hammerandchisel/discord-api-docs/issues/17 for how to do sharding.
         | 
| 153 | 
            +
                # @param num_shards [Integer] The total number of shards that should be running. See
         | 
| 154 | 
            +
                #   https://github.com/hammerandchisel/discord-api-docs/issues/17 for how to do sharding.
         | 
| 148 155 | 
             
                def initialize(
         | 
| 149 156 | 
             
                    email: nil, password: nil, log_mode: :normal,
         | 
| 150 157 | 
             
                    token: nil, application_id: nil,
         | 
| 151 | 
            -
                    type: nil, name: '', fancy_log: false, suppress_ready: false, parse_self: false | 
| 158 | 
            +
                    type: nil, name: '', fancy_log: false, suppress_ready: false, parse_self: false,
         | 
| 159 | 
            +
                    shard_id: nil, num_shards: nil)
         | 
| 152 160 | 
             
                  # Make sure people replace the login details in the example files...
         | 
| 153 161 | 
             
                  if email.is_a?(String) && email.end_with?('example.com')
         | 
| 154 162 | 
             
                    puts 'You have to replace the login details in the example files with your own!'
         | 
| @@ -172,6 +180,8 @@ module Discordrb | |
| 172 180 |  | 
| 173 181 | 
             
                  @name = name
         | 
| 174 182 |  | 
| 183 | 
            +
                  @shard_key = num_shards ? [shard_id, num_shards] : nil
         | 
| 184 | 
            +
             | 
| 175 185 | 
             
                  LOGGER.fancy = fancy_log
         | 
| 176 186 | 
             
                  @prevent_ready = suppress_ready
         | 
| 177 187 |  | 
| @@ -390,11 +400,11 @@ module Discordrb | |
| 390 400 | 
             
                # @param content [String] The text that should be sent as a message. It is limited to 2000 characters (Discord imposed).
         | 
| 391 401 | 
             
                # @param tts [true, false] Whether or not this message should be sent using Discord text-to-speech.
         | 
| 392 402 | 
             
                # @return [Message] The message that was sent.
         | 
| 393 | 
            -
                def send_message(channel_id, content, tts = false)
         | 
| 403 | 
            +
                def send_message(channel_id, content, tts = false, server_id = nil)
         | 
| 394 404 | 
             
                  channel_id = channel_id.resolve_id
         | 
| 395 405 | 
             
                  debug("Sending message to #{channel_id} with content '#{content}'")
         | 
| 396 406 |  | 
| 397 | 
            -
                  response = API.send_message(token, channel_id, content, [], tts)
         | 
| 407 | 
            +
                  response = API.send_message(token, channel_id, content, [], tts, server_id)
         | 
| 398 408 | 
             
                  Message.new(JSON.parse(response), self)
         | 
| 399 409 | 
             
                end
         | 
| 400 410 |  | 
| @@ -433,7 +443,7 @@ module Discordrb | |
| 433 443 | 
             
                end
         | 
| 434 444 |  | 
| 435 445 | 
             
                # Creates a new application to do OAuth authorization with. This allows you to use OAuth to authorize users using
         | 
| 436 | 
            -
                # Discord. For information how to use this, see  | 
| 446 | 
            +
                # Discord. For information how to use this, see the docs: https://discordapp.com/developers/docs/topics/oauth2
         | 
| 437 447 | 
             
                # @param name [String] What your application should be called.
         | 
| 438 448 | 
             
                # @param redirect_uris [Array<String>] URIs that Discord should redirect your users to after authorizing.
         | 
| 439 449 | 
             
                # @return [Array(String, String)] your applications' client ID and client secret to be used in OAuth authorization.
         | 
| @@ -457,7 +467,7 @@ module Discordrb | |
| 457 467 | 
             
                # @return [User] The user identified by the mention, or `nil` if none exists.
         | 
| 458 468 | 
             
                def parse_mention(mention)
         | 
| 459 469 | 
             
                  # Mention format: <@id>
         | 
| 460 | 
            -
                  return nil unless  | 
| 470 | 
            +
                  return nil unless /<@!?(?<id>\d+)>?/ =~ mention
         | 
| 461 471 | 
             
                  user(id.to_i)
         | 
| 462 472 | 
             
                end
         | 
| 463 473 |  | 
| @@ -724,6 +734,7 @@ module Discordrb | |
| 724 734 |  | 
| 725 735 | 
             
                  member = server.member(data['user']['id'].to_i)
         | 
| 726 736 | 
             
                  member.update_roles(data['roles'])
         | 
| 737 | 
            +
                  member.update_nick(data['nick'])
         | 
| 727 738 | 
             
                end
         | 
| 728 739 |  | 
| 729 740 | 
             
                # Internal handler for GUILD_MEMBER_DELETE
         | 
| @@ -1095,7 +1106,7 @@ module Discordrb | |
| 1095 1106 | 
             
                    return if message.from_bot? && !should_parse_self
         | 
| 1096 1107 |  | 
| 1097 1108 | 
             
                    unless message.author
         | 
| 1098 | 
            -
                      LOGGER. | 
| 1109 | 
            +
                      LOGGER.debug("Edited a message with nil author! Content: #{message.content.inspect}, channel: #{message.channel.inspect}")
         | 
| 1099 1110 | 
             
                      return
         | 
| 1100 1111 | 
             
                    end
         | 
| 1101 1112 |  | 
| @@ -1296,6 +1307,9 @@ module Discordrb | |
| 1296 1307 | 
             
                    }
         | 
| 1297 1308 | 
             
                  }
         | 
| 1298 1309 |  | 
| 1310 | 
            +
                  # Discord is very strict about the existence of the shard parameter, so only add it if it actually exists
         | 
| 1311 | 
            +
                  packet[:d][:shard] = @shard_key if @shard_key
         | 
| 1312 | 
            +
             | 
| 1299 1313 | 
             
                  @ws.send(packet.to_json)
         | 
| 1300 1314 | 
             
                end
         | 
| 1301 1315 |  | 
| @@ -1343,6 +1357,9 @@ module Discordrb | |
| 1343 1357 |  | 
| 1344 1358 | 
             
                def send_heartbeat(sequence = nil)
         | 
| 1345 1359 | 
             
                  sequence ||= @sequence
         | 
| 1360 | 
            +
             | 
| 1361 | 
            +
                  raise_event(HeartbeatEvent.new(self))
         | 
| 1362 | 
            +
             | 
| 1346 1363 | 
             
                  LOGGER.out("Sending heartbeat with sequence #{sequence}")
         | 
| 1347 1364 | 
             
                  data = {
         | 
| 1348 1365 | 
             
                    op: Opcodes::HEARTBEAT,
         | 
| @@ -23,9 +23,18 @@ module Discordrb::Commands | |
| 23 23 | 
             
                # Creates a new CommandBot and logs in to Discord.
         | 
| 24 24 | 
             
                # @param attributes [Hash] The attributes to initialize the CommandBot with.
         | 
| 25 25 | 
             
                # @see {Discordrb::Bot#initialize} for other attributes that should be used to create the underlying regular bot.
         | 
| 26 | 
            -
                # @option attributes [String] :prefix The prefix that should trigger this bot's commands.  | 
| 27 | 
            -
                #    | 
| 28 | 
            -
                # | 
| 26 | 
            +
                # @option attributes [String, Array<String>, #call] :prefix The prefix that should trigger this bot's commands. It
         | 
| 27 | 
            +
                #   can be:
         | 
| 28 | 
            +
                #
         | 
| 29 | 
            +
                #   * Any string (including the empty string). This has the effect that if a message starts with the prefix, the
         | 
| 30 | 
            +
                #     prefix will be stripped and the rest of the chain will be parsed as a command chain. Note that it will be
         | 
| 31 | 
            +
                #     literal - if the prefix is "hi" then the corresponding trigger string for a command called "test" would be
         | 
| 32 | 
            +
                #     "hitest". Don't forget to put spaces in if you need them!
         | 
| 33 | 
            +
                #   * An array of prefixes. Those will behave similarly to setting one string as a prefix, but instead of only one
         | 
| 34 | 
            +
                #     string, any of the strings in the array can be used.
         | 
| 35 | 
            +
                #   * Something Proc-like (responds to :call) that takes a string as an argument (the message) and returns either
         | 
| 36 | 
            +
                #     the command chain in raw form or `nil` if the given string shouldn't be parsed. This can be used to make more
         | 
| 37 | 
            +
                #     complicated dynamic prefixes, or even something else entirely (suffixes, or most adventurous, infixes).
         | 
| 29 38 | 
             
                # @option attributes [true, false] :advanced_functionality Whether to enable advanced functionality (very powerful
         | 
| 30 39 | 
             
                #   way to nest commands into chains, see https://github.com/meew0/discordrb/wiki/Commands#command-chain-syntax
         | 
| 31 40 | 
             
                #   for info. Default is true.
         | 
| @@ -62,7 +71,9 @@ module Discordrb::Commands | |
| 62 71 | 
             
                    name: attributes[:name],
         | 
| 63 72 | 
             
                    fancy_log: attributes[:fancy_log],
         | 
| 64 73 | 
             
                    suppress_ready: attributes[:suppress_ready],
         | 
| 65 | 
            -
                    parse_self: attributes[:parse_self] | 
| 74 | 
            +
                    parse_self: attributes[:parse_self],
         | 
| 75 | 
            +
                    shard_id: attributes[:shard_id],
         | 
| 76 | 
            +
                    num_shards: attributes[:num_shards])
         | 
| 66 77 |  | 
| 67 78 | 
             
                  @prefix = attributes[:prefix]
         | 
| 68 79 | 
             
                  @attributes = {
         | 
| @@ -150,7 +161,8 @@ module Discordrb::Commands | |
| 150 161 | 
             
                    event.respond @attributes[:command_doesnt_exist_message].gsub('%command%', name.to_s) if @attributes[:command_doesnt_exist_message]
         | 
| 151 162 | 
             
                    return
         | 
| 152 163 | 
             
                  end
         | 
| 153 | 
            -
                  if permission?(event.user, command.attributes[:permission_level], event.server)
         | 
| 164 | 
            +
                  if permission?(event.user, command.attributes[:permission_level], event.server) &&
         | 
| 165 | 
            +
                     required_permissions?(event.author, command.attributes[:required_permissions], event.channel)
         | 
| 154 166 | 
             
                    event.command = command
         | 
| 155 167 | 
             
                    result = command.call(event, arguments, chained)
         | 
| 156 168 | 
             
                    stringify(result)
         | 
| @@ -205,8 +217,8 @@ module Discordrb::Commands | |
| 205 217 |  | 
| 206 218 | 
             
                  event = CommandEvent.new(message, self)
         | 
| 207 219 |  | 
| 208 | 
            -
                   | 
| 209 | 
            -
                   | 
| 220 | 
            +
                  chain = trigger?(message.content)
         | 
| 221 | 
            +
                  return unless chain
         | 
| 210 222 |  | 
| 211 223 | 
             
                  # Don't allow spaces between the prefix and the command
         | 
| 212 224 | 
             
                  if chain.start_with?(' ') && !@attributes[:spaces_allowed]
         | 
| @@ -222,6 +234,28 @@ module Discordrb::Commands | |
| 222 234 | 
             
                  execute_chain(chain, event)
         | 
| 223 235 | 
             
                end
         | 
| 224 236 |  | 
| 237 | 
            +
                # Check whether a message should trigger command execution, and if it does, return the raw chain
         | 
| 238 | 
            +
                def trigger?(message)
         | 
| 239 | 
            +
                  if @prefix.is_a? String
         | 
| 240 | 
            +
                    standard_prefix_trigger(message, @prefix)
         | 
| 241 | 
            +
                  elsif @prefix.is_a? Array
         | 
| 242 | 
            +
                    @prefix.map { |e| standard_prefix_trigger(message, e) }.reduce { |a, e| a || e }
         | 
| 243 | 
            +
                  elsif @prefix.respond_to? :call
         | 
| 244 | 
            +
                    @prefix.call(message)
         | 
| 245 | 
            +
                  end
         | 
| 246 | 
            +
                end
         | 
| 247 | 
            +
             | 
| 248 | 
            +
                def standard_prefix_trigger(message, prefix)
         | 
| 249 | 
            +
                  return nil unless message.start_with? prefix
         | 
| 250 | 
            +
                  message[prefix.length..-1]
         | 
| 251 | 
            +
                end
         | 
| 252 | 
            +
             | 
| 253 | 
            +
                def required_permissions?(member, required, channel = nil)
         | 
| 254 | 
            +
                  required.reduce(true) do |a, action|
         | 
| 255 | 
            +
                    a && member.permission?(action, channel)
         | 
| 256 | 
            +
                  end
         | 
| 257 | 
            +
                end
         | 
| 258 | 
            +
             | 
| 225 259 | 
             
                def execute_chain(chain, event)
         | 
| 226 260 | 
             
                  t = Thread.new do
         | 
| 227 261 | 
             
                    @event_threads << t
         | 
| @@ -9,6 +9,9 @@ module Discordrb::Commands | |
| 9 9 | 
             
              module CommandContainer
         | 
| 10 10 | 
             
                include RateLimiter
         | 
| 11 11 |  | 
| 12 | 
            +
                # @return [Array<Command>] the list of commands this container has.
         | 
| 13 | 
            +
                attr_reader :commands
         | 
| 14 | 
            +
             | 
| 12 15 | 
             
                # Adds a new command to the container.
         | 
| 13 16 | 
             
                # @param name [Symbol] The name of the command to add.
         | 
| 14 17 | 
             
                # @param attributes [Hash] The attributes to initialize the command with.
         | 
| @@ -17,6 +20,8 @@ module Discordrb::Commands | |
| 17 20 | 
             
                # @option attributes [String, false] :permission_message Message to display when a user does not have sufficient
         | 
| 18 21 | 
             
                #   permissions to execute a command. %name% in the message will be replaced with the name of the command. Disable
         | 
| 19 22 | 
             
                #   the message by setting this option to false.
         | 
| 23 | 
            +
                # @option attributes [Array<Symbol>] :required_permissions Discord action permissions (e.g. `:kick_members`) that
         | 
| 24 | 
            +
                #   should be required to use this command. See {Discordrb::Permissions::Flags} for a list.
         | 
| 20 25 | 
             
                # @option attributes [true, false] :chain_usable Whether this command is able to be used inside of a command chain
         | 
| 21 26 | 
             
                #   or sub-chain. Typically used for administrative commands that shouldn't be done carelessly.
         | 
| 22 27 | 
             
                # @option attributes [true, false] :help_available Whether this command is visible in the help command. See the
         | 
| @@ -19,6 +19,9 @@ module Discordrb::Commands | |
| 19 19 | 
             
                    # Message to display when a user does not have sufficient permissions to execute a command
         | 
| 20 20 | 
             
                    permission_message: (attributes[:permission_message].is_a? FalseClass) ? nil : (attributes[:permission_message] || "You don't have permission to execute command %name%!"),
         | 
| 21 21 |  | 
| 22 | 
            +
                    # Discord action permissions required to use this command
         | 
| 23 | 
            +
                    required_permissions: attributes[:required_permissions] || [],
         | 
| 24 | 
            +
             | 
| 22 25 | 
             
                    # Whether this command is usable in a command chain
         | 
| 23 26 | 
             
                    chain_usable: attributes[:chain_usable].nil? ? true : attributes[:chain_usable],
         | 
| 24 27 |  | 
    
        data/lib/discordrb/container.rb
    CHANGED
    
    | @@ -56,6 +56,21 @@ module Discordrb | |
| 56 56 | 
             
                  register_event(DisconnectEvent, attributes, block)
         | 
| 57 57 | 
             
                end
         | 
| 58 58 |  | 
| 59 | 
            +
                # This **event** is raised every time the bot sends a heartbeat over the galaxy. This happens roughly every 40
         | 
| 60 | 
            +
                # seconds, but may happen at a lower rate should Discord change their interval. It may also happen more quickly for
         | 
| 61 | 
            +
                # periods of time, especially for unstable connections, since discordrb rather sends a heartbeat than not if there's
         | 
| 62 | 
            +
                # a choice. (You shouldn't rely on all this to be accurately timed.)
         | 
| 63 | 
            +
                #
         | 
| 64 | 
            +
                # All this makes this event useful to periodically trigger something, like doing some API request every hour,
         | 
| 65 | 
            +
                # setting some kind of uptime variable or whatever else. The only limit is yourself.
         | 
| 66 | 
            +
                # @param attributes [Hash] Event attributes, none in this particular case
         | 
| 67 | 
            +
                # @yield The block is executed when the event is raised.
         | 
| 68 | 
            +
                # @yieldparam event [HeartbeatEvent] The event that was raised.
         | 
| 69 | 
            +
                # @return [HeartbeatEventHandler] The event handler that was registered.
         | 
| 70 | 
            +
                def heartbeat(attributes = {}, &block)
         | 
| 71 | 
            +
                  register_event(HeartbeatEvent, attributes, block)
         | 
| 72 | 
            +
                end
         | 
| 73 | 
            +
             | 
| 59 74 | 
             
                # This **event** is raised when somebody starts typing in a channel the bot is also in. The official Discord
         | 
| 60 75 | 
             
                # client would display the typing indicator for five seconds after receiving this event. If the user continues
         | 
| 61 76 | 
             
                # typing after five seconds, the event will be re-raised.
         | 
    
        data/lib/discordrb/data.rb
    CHANGED
    
    | @@ -229,6 +229,10 @@ module Discordrb | |
| 229 229 | 
             
                # @return [Time] when this member joined the server.
         | 
| 230 230 | 
             
                attr_reader :joined_at
         | 
| 231 231 |  | 
| 232 | 
            +
                # @return [String, nil] the nickname this member has, or nil if it has none.
         | 
| 233 | 
            +
                attr_reader :nick
         | 
| 234 | 
            +
                alias_method :nickname, :nick
         | 
| 235 | 
            +
             | 
| 232 236 | 
             
                # @return [Array<Role>] the roles this member has.
         | 
| 233 237 | 
             
                attr_reader :roles
         | 
| 234 238 |  | 
| @@ -342,6 +346,8 @@ module Discordrb | |
| 342 346 | 
             
                  # Initialize the roles by getting the roles from the server one-by-one
         | 
| 343 347 | 
             
                  update_roles(data['roles'])
         | 
| 344 348 |  | 
| 349 | 
            +
                  @nick = data['nick']
         | 
| 350 | 
            +
             | 
| 345 351 | 
             
                  @deaf = data['deaf']
         | 
| 346 352 | 
             
                  @mute = data['mute']
         | 
| 347 353 | 
             
                  @joined_at = data['joined_at'] ? Time.parse(data['joined_at']) : nil
         | 
| @@ -379,6 +385,23 @@ module Discordrb | |
| 379 385 | 
             
                  API.update_user_roles(@bot.token, @server.id, @user.id, new_role_ids)
         | 
| 380 386 | 
             
                end
         | 
| 381 387 |  | 
| 388 | 
            +
                # Sets or resets this member's nickname. Requires the Change Nickname permission for the bot itself and Manage
         | 
| 389 | 
            +
                # Nicknames for other users.
         | 
| 390 | 
            +
                # @param nick [String, nil] The string to set the nickname to, or nil if it should be reset.
         | 
| 391 | 
            +
                def nick=(nick)
         | 
| 392 | 
            +
                  # Discord uses the empty string to signify 'no nickname' so we convert nil into that
         | 
| 393 | 
            +
                  nick ||= ''
         | 
| 394 | 
            +
             | 
| 395 | 
            +
                  API.change_nickname(@bot.token, @server.id, @user.id, nick)
         | 
| 396 | 
            +
                end
         | 
| 397 | 
            +
             | 
| 398 | 
            +
                alias_method :nickname=, :nick=
         | 
| 399 | 
            +
             | 
| 400 | 
            +
                # @return [String] the name the user displays as (nickname if they have one, username otherwise)
         | 
| 401 | 
            +
                def display_name
         | 
| 402 | 
            +
                  nickname || username
         | 
| 403 | 
            +
                end
         | 
| 404 | 
            +
             | 
| 382 405 | 
             
                # Update this member's roles
         | 
| 383 406 | 
             
                # @note For internal use only.
         | 
| 384 407 | 
             
                # @!visibility private
         | 
| @@ -388,6 +411,13 @@ module Discordrb | |
| 388 411 | 
             
                  end
         | 
| 389 412 | 
             
                end
         | 
| 390 413 |  | 
| 414 | 
            +
                # Update this member's nick
         | 
| 415 | 
            +
                # @note For internal use only.
         | 
| 416 | 
            +
                # @!visibility private
         | 
| 417 | 
            +
                def update_nick(nick)
         | 
| 418 | 
            +
                  @nick = nick
         | 
| 419 | 
            +
                end
         | 
| 420 | 
            +
             | 
| 391 421 | 
             
                # Update this member's voice state
         | 
| 392 422 | 
             
                # @note For internal use only.
         | 
| 393 423 | 
             
                # @!visibility private
         | 
| @@ -540,6 +570,10 @@ module Discordrb | |
| 540 570 | 
             
                # @return [true, false] whether or not this role should be displayed separately from other users
         | 
| 541 571 | 
             
                attr_reader :hoist
         | 
| 542 572 |  | 
| 573 | 
            +
                # @return [true, false] whether this role can be mentioned using a role mention
         | 
| 574 | 
            +
                attr_reader :mentionable
         | 
| 575 | 
            +
                alias_method :mentionable?, :mentionable
         | 
| 576 | 
            +
             | 
| 543 577 | 
             
                # @return [ColourRGB] the role colour
         | 
| 544 578 | 
             
                attr_reader :colour
         | 
| 545 579 |  | 
| @@ -567,10 +601,18 @@ module Discordrb | |
| 567 601 | 
             
                  @permissions = Permissions.new(data['permissions'], RoleWriter.new(self, @bot.token))
         | 
| 568 602 | 
             
                  @name = data['name']
         | 
| 569 603 | 
             
                  @id = data['id'].to_i
         | 
| 604 | 
            +
             | 
| 570 605 | 
             
                  @hoist = data['hoist']
         | 
| 606 | 
            +
                  @mentionable = data['mentionable']
         | 
| 607 | 
            +
             | 
| 571 608 | 
             
                  @colour = ColourRGB.new(data['color'])
         | 
| 572 609 | 
             
                end
         | 
| 573 610 |  | 
| 611 | 
            +
                # @return [String] a string that will mention this role, if it is mentionable.
         | 
| 612 | 
            +
                def mention
         | 
| 613 | 
            +
                  "<@&#{@id}>"
         | 
| 614 | 
            +
                end
         | 
| 615 | 
            +
             | 
| 574 616 | 
             
                # Updates the data cache from another Role object
         | 
| 575 617 | 
             
                # @note For internal use only
         | 
| 576 618 | 
             
                # @!visibility private
         | 
| @@ -853,7 +895,7 @@ module Discordrb | |
| 853 895 | 
             
                # @param tts [true, false] Whether or not this message should be sent using Discord text-to-speech.
         | 
| 854 896 | 
             
                # @return [Message] the message that was sent.
         | 
| 855 897 | 
             
                def send_message(content, tts = false)
         | 
| 856 | 
            -
                  @bot.send_message(@id, content, tts)
         | 
| 898 | 
            +
                  @bot.send_message(@id, content, tts, @server && @server.id)
         | 
| 857 899 | 
             
                end
         | 
| 858 900 |  | 
| 859 901 | 
             
                # Sends multiple messages to a channel
         | 
| @@ -963,9 +1005,11 @@ module Discordrb | |
| 963 1005 | 
             
                  JSON.parse(logs).map { |message| Message.new(message, @bot) }
         | 
| 964 1006 | 
             
                end
         | 
| 965 1007 |  | 
| 966 | 
            -
                # Deletes the last N messages on this channel.
         | 
| 967 | 
            -
                #  | 
| 968 | 
            -
                # | 
| 1008 | 
            +
                # Deletes the last N messages on this channel. Each delete request is performed in a separate thread for performance
         | 
| 1009 | 
            +
                # reasons, so if a large number of messages are pruned, many threads will be created.
         | 
| 1010 | 
            +
                # @note As of the April 29 update, the message delete request is rate limited, which means this method will take
         | 
| 1011 | 
            +
                #   a long time. It will eventually be updated to use batch deletes once those are released, but that will be in the
         | 
| 1012 | 
            +
                #   far future.
         | 
| 969 1013 | 
             
                # @param amount [Integer] How many messages to delete. Must be 100 or less (Discord limitation)
         | 
| 970 1014 | 
             
                # @raise [ArgumentError] if more than 100 messages are requested.
         | 
| 971 1015 | 
             
                def prune(amount)
         | 
| @@ -1097,6 +1141,9 @@ module Discordrb | |
| 1097 1141 | 
             
                # @return [Array<User>] the users that were mentioned in this message.
         | 
| 1098 1142 | 
             
                attr_reader :mentions
         | 
| 1099 1143 |  | 
| 1144 | 
            +
                # @return [Array<Role>] the roles that were mentioned in this message.
         | 
| 1145 | 
            +
                attr_reader :role_mentions
         | 
| 1146 | 
            +
             | 
| 1100 1147 | 
             
                # @return [Array<Attachment>] the files attached to this message.
         | 
| 1101 1148 | 
             
                attr_reader :attachments
         | 
| 1102 1149 |  | 
| @@ -1129,6 +1176,15 @@ module Discordrb | |
| 1129 1176 | 
             
                    @mentions << bot.ensure_user(element)
         | 
| 1130 1177 | 
             
                  end if data['mentions']
         | 
| 1131 1178 |  | 
| 1179 | 
            +
                  @role_mentions = []
         | 
| 1180 | 
            +
             | 
| 1181 | 
            +
                  # Role mentions can only happen on public servers so make sure we only parse them there
         | 
| 1182 | 
            +
                  unless @channel.private?
         | 
| 1183 | 
            +
                    data['mention_roles'].each do |element|
         | 
| 1184 | 
            +
                      @role_mentions << @channel.server.role(element.to_i)
         | 
| 1185 | 
            +
                    end if data['mention_roles']
         | 
| 1186 | 
            +
                  end
         | 
| 1187 | 
            +
             | 
| 1132 1188 | 
             
                  @attachments = []
         | 
| 1133 1189 | 
             
                  @attachments = data['attachments'].map { |e| Attachment.new(e, self, @bot) } if data['attachments']
         | 
| 1134 1190 | 
             
                end
         | 
| @@ -22,4 +22,10 @@ module Discordrb::Events | |
| 22 22 |  | 
| 23 23 | 
             
              # Event handler for {DisconnectEvent}
         | 
| 24 24 | 
             
              class DisconnectEventHandler < TrueEventHandler; end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
              # @see Discordrb::EventContainer#heartbeat
         | 
| 27 | 
            +
              class HeartbeatEvent < LifetimeEvent; end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
              # Event handler for {HeartbeatEvent}
         | 
| 30 | 
            +
              class HeartbeatEventHandler < TrueEventHandler; end
         | 
| 25 31 | 
             
            end
         | 
| @@ -32,7 +32,9 @@ module Discordrb | |
| 32 32 | 
             
                  22 => :mute_members,         # 4194304
         | 
| 33 33 | 
             
                  23 => :deafen_members,       # 8388608
         | 
| 34 34 | 
             
                  24 => :move_members,         # 16777216
         | 
| 35 | 
            -
                  25 => :use_voice_activity | 
| 35 | 
            +
                  25 => :use_voice_activity,   # 33554432
         | 
| 36 | 
            +
                  26 => :change_nickname,      # 67108864
         | 
| 37 | 
            +
                  27 => :manage_nicknames      # 134217728
         | 
| 36 38 | 
             
                }.freeze
         | 
| 37 39 |  | 
| 38 40 | 
             
                Flags.each do |position, flag|
         | 
    
        data/lib/discordrb/version.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: discordrb
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 2.0 | 
| 4 | 
            +
              version: 2.1.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - meew0
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: exe
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2016-04- | 
| 11 | 
            +
            date: 2016-04-30 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: rest-client
         |