GithubHelp home page GithubHelp logo

discordrb's Introduction

discordrb

Gem Gem CircleCI Inline docs Join Discord

An implementation of the Discord API using Ruby.

Quick links to sections

See also: Documentation, Tutorials

Introduction

discordrb aims to meet the following design goals:

  1. Full coverage of the public bot API.
  2. Expressive, high level abstractions for rapid development of common applications.
  3. Friendly to Ruby beginners and beginners of open source contribution.

If you enjoy using the library, consider getting involved with the community to help us improve and meet these goals!

You should consider using discordrb if:

  • You need a bot - and fast - for small or medium sized communities, and don't want to be bogged down with "low level" details. Getting started takes minutes, and utilities like a command parser and tools for modularization make it simple to quickly add or change your bots functionality.
  • You like or want to learn Ruby, or want to contribute to a Ruby project. A lot of our users are new to Ruby, and eventually make their first open source contributions with us. We have an active Discord channel with experienced members who will happily help you get involved, either as a user or contributor.
  • You want to experiment with Discord's API or prototype concepts for Discord bots without too much commitment.

You should consider other libraries if:

  • You need to scale to large volumes of servers (>2,500) with lots of members. It's still possible, but it can be difficult to scale Ruby processes, and it requires more in depth knowledge to do so well. Especially if you already have a bot that is on a large amount of servers, porting to Ruby is unlikely to improve your performance in most cases.
  • You want full control over the library that you're using. While we expose some "lower level" interfaces, they are unstable, and only exist to serve the more powerful abstractions in the library.

Dependencies

  • Ruby >= 3.1 supported
  • An installed build system for native extensions (on Windows, make sure you download the "Ruby+Devkit" version of RubyInstaller)

Voice dependencies

This section only applies to you if you want to use voice functionality.

  • libsodium
  • A compiled libopus distribution for your system, anywhere the script can find it. See here for installation instructions.
  • FFmpeg installed and in your PATH

Installation

With Bundler

Using Bundler, you can add discordrb to your Gemfile:

gem 'discordrb'

And then install via bundle install.

Run the ping example to verify that the installation works (make sure to replace the token and client ID in there with your bots'!):

To run the bot while using bundler:

bundle exec ruby ping.rb

With Gem

Alternatively, while Bundler is the recommended option, you can also install discordrb without it.

Linux / macOS

gem install discordrb

Windows

Make sure you have the DevKit installed! See the Dependencies section)

gem install discordrb --platform=ruby

To run the bot:

ruby ping.rb

Installation Troubleshooting

See https://github.com/shardlab/discordrb/wiki/FAQ#installation for a list of common problems and solutions when installing discordrb.

Usage

You can make a simple bot like this:

require 'discordrb'

bot = Discordrb::Bot.new token: '<token here>'

bot.message(with_text: 'Ping!') do |event|
  event.respond 'Pong!'
end

bot.run

This bot responds to every "Ping!" with a "Pong!".

See additional examples here.

You can find examples of projects that use discordrb by searching for the discordrb topic on GitHub.

If you've made an open source project on GitHub that uses discordrb, consider adding the discordrb topic to your repo!

Webhooks Client

Also included is a webhooks client, which can be used as a separate gem discordrb-webhooks. This special client can be used to form requests to Discord webhook URLs in a high-level manner.

Usage

require 'discordrb/webhooks'

WEBHOOK_URL = 'https://discord.com/api/webhooks/424070213278105610/yByxDncRvHi02mhKQheviQI2erKkfRRwFcEp0MMBfib1ds6ZHN13xhPZNS2-fJo_ApSw'.freeze

client = Discordrb::Webhooks::Client.new(url: WEBHOOK_URL)
client.execute do |builder|
  builder.content = 'Hello world!'
  builder.add_embed do |embed|
    embed.title = 'Embed title'
    embed.description = 'Embed description'
    embed.timestamp = Time.now
  end
end

Note: The discordrb gem relies on discordrb-webhooks. If you already have discordrb installed, require 'discordrb/webhooks' will include all of the Webhooks features as well.

Support

If you need help or have a question, you can:

  1. Join our Discord channel. This is the fastest means of getting support.
  2. Open an issue. Be sure to read the issue template, and provide as much detail as you can.

Contributing

Thank you for your interest in contributing! Bug reports and pull requests are welcome on GitHub at https://github.com/shardlab/discordrb.

In general, we recommend starting by discussing what you would like to contribute in the Discord channel. There are usually a handful of people working on things for the library, and what you're looking for may already be on the way.

Additionally, there is a chance what you are looking for might already exist, or we decided not to pursue it for some reason. Be sure to use the search feature on our documentation, GitHub, and Discord to see if this might be the case.

Development setup

This section is for developing discordrb itself! If you just want to make a bot, see the Installation section.

After checking out the repo, run bin/setup to install dependencies. You can then run tests via bundle exec rspec spec. Make sure to run rubocop also: bundle exec rubocop. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.

License

The gem is available as open source under the terms of the MIT License.

discordrb's People

Contributors

anhnhan avatar apexal avatar birdie0 avatar brpeterman avatar chew avatar connorshea avatar dakurei avatar daniel-worrall avatar dreid avatar greenbigfrog avatar idk837384 avatar joshbuker avatar kaine119 avatar kirillian avatar likelakers2 avatar mackmm145 avatar mattantonelli avatar meew0 avatar omnilord avatar panissupraomnia avatar pixelinc avatar purintai avatar roughsketch avatar snapcase avatar soukouki avatar swarley avatar unleashy avatar vxjasonxv avatar xzanth avatar z64 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

discordrb's Issues

Support Slash Command Gateway Events

The following events need to be implemented.

  • INTERACTION_CREATE
  • APPLICATION_COMMAND_CREATE
  • APPLICATION_COMMAND_UPDATE
  • APPLICATION_COMMAND_DELETE

Voice Send mp3s without ffmpeg shows ambiguous error

Summary

When ffmpeg is not installed, and the example voice_send.rb is ran, the mp3 will give Exception: #<IOError: File or stream not found!> when it should output a more relevant error regarding ffmpeg.

This comes from a report in the discordrb channel in dAPI. It is currently unconfirmed in main.


Environment

Ruby version: ruby 3.1.0p0

Discordrb version: discordrb (3.4.0)

Bug: Message#reacted_with limit: nil gives a 400

bot.channel(c_id).load_message(m_id).reacted_with(emoji, limit: nil)
Traceback (most recent call last):
       16: from /.../discordrb/data/message.rb:284:in `reacted_with'
       15: from /.../discordrb/data/message.rb:284:in `to_a'
       14: from /.../discordrb/paginator.rb:28:in `each'
       13: from /.../discordrb/data/message.rb:281:in `block in reacted_with'
       12: from /.../discordrb/api/channel.rb:205:in `get_reactions'
       11: from /.../discordrb/api.rb:115:in `request'
       10: from /.../discordrb/api.rb:81:in `raw_request'
        9: from /.../restclient.rb:66:in `get'
        8: from /.../restclient/request.rb:63:in `execute'
        7: from /.../restclient/request.rb:163:in `execute'
        6: from /.../restclient/request.rb:727:in `transmit'
        5: from /.../ruby/2.7.0/net/http.rb:933:in `start'
        4: from /.../restclient/request.rb:743:in `block in transmit'
        3: from /.../restclient/request.rb:836:in `process_result'
        2: from /.../restclient/abstract_response.rb:129:in `return!'
        1: from /.../restclient/abstract_response.rb:249:in `exception_with_response'
RestClient::BadRequest (400 Bad Request)

Unsure if this is a problem with the Paginator or something else

Feature Request: Message#add_reaction_await(!)

To add Message#add_reaction_await and Message#add_reaction_await!

I feel like adding an await for a reaction is common enough to warrant a handy abstraction for it.

Currently, Messsage#add_await adds a MessageEvent await, and I thought we could extend this to have it parse a symbol (like :message or :reaction_add) for the type of event (and default to message), then allow for optional arguments like emoji.

Not sure if this is supported in the current await system, but it would be nice to support multiple emoji for the reaction awaits.

Support size parameter for images

To support User#avatar_url (and by extension API::User.avatar_url) size passing.

There will be other similar methods that return an image URL that should also support sizes.

Subcommands not routed to the top level slash command handler

Summary

Subcommand events are not handled by an application_command handler for the top-level command. For example:

bot.register_application_command(:foo, 'foo') do |cmd|
  cmd.subcommand(:bar, 'bar')
  cmd.subcommand(:baz, 'baz')
end

bot.application_command(:foo) do |evt|
  evt.respond(content: evt.subcommand)
end

If you do /foo bar, you should see bar. The bot will receive the interaction, but this handler will never fire, and the message will not be sent. You can avoid this by rewriting the handler like this.

bot.application_command(:foo).subcommand(:bar) do |evt|
  evt.respond(content: 'bar')
end
bot.application_command(:foo).subcommand(:baz) do |evt|
  evt.respond(content: 'baz')
end

Environment

Ruby version:

ruby 3.1.0p0 (2021-12-25 revision fb4df44d16) [x86_64-linux-gnu]

Discordrb version:

  * discordrb (3.4.2 fc98743)
        Summary: Discord API for Ruby
        Homepage: https://github.com/shardlab/discordrb
        Changelog: https://github.com/shardlab/discordrb/blob/master/CHANGELOG.md
        Path: /home/ajc/Code/scorebot/vendor/bundle/ruby/3.1.0/bundler/gems/discordrb-fc9874319798

Channel#reacted_with limit:nil Bug - Again

Summary

We fixed the Pagination without supplying a limit in #39, but discord has recently broke this.

discord/discord-api-docs#3053

An untested fix in the meantime could be to supply a known limit, but it'll still make additional requests and you'd have to call .uniq on the Array.

You could also supply custom pagination code.

Support v10

This is a tracking issue for v10

See discord/discord-api-docs#4510

Since latest gem (3.4) is on v6 and soon to be decommissioned, more work will be dedicated into pushing out a stable 3.5.

Main branch already includes v8, and the threads branch that is being worked on is running on v9.

We'll be targeting v9 for the 3.5 release, and probably v10 for 4.0.

Most of the work needed for these separate releases are nothing to do with the versioning changes, so no PR is needed and can be done when it is needed.

Please do stop by the discord channel in the dAPI server, or the ShardLab discord server for the most up to date information regarding discordrb development, though we will be trying our best to keep Github up to date with anything major.

`allowed_mentions` in webhook client results in Bad Request

Summary

Using allowed_mentions with Discordrb::Webhooks::Client.execute fails with Bad Request.

require "discordrb"
require "discordrb/webhooks"

client = Discordrb::Webhooks::Client.new(url: ENV["DISCORD_WEBHOOK_EN"])

begin
  client.execute do |builder|
    builder.content = "test"
    builder.allowed_mentions = Discordrb::AllowedMentions.new(parse: [])
  end
rescue RestClient::BadRequest => e
  puts e.response.body
end

Result:

{"allowed_mentions": ["Only dictionaries may be used in a ModelType"]}

Environment

Ruby version:
ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-linux]

Discordrb version:

API Mapping Audit

With 3.5 approaching and 4.0 being the target afterwards, one important task that the community can help with gets stronger in my mind.

We'd love to have 100% documentation to library mapping of objects, properties, and API calls.
Some things fall through the cracks and we can't have an eagle eye on every single documentation change (and the changelog isn't perfect).

What I'd like to propose is an audit of all the Objects/Properties/API calls that Discordrb exposes, and to find all the ones we're missing. There are some properties that are simply not useful to keep track of, but we can make that decision after the differences have been found. We'd then also have a reference of which ones we don't have and why.

I also have plans to track all documentation commits to assess whether anything needs to be changed and create tracking issues for them where relevant. This will come after the audit has happened to save on work.

If you'd like to work on this, please let it be known on the issue, so others don't duplicate your work. Please include which objects you're looking at, and update your post as you move onto others.

I will be starting on this task in the coming weeks, but feel free to get a headstart on this.

Stage Channels

Discord recently introduced Stage Channels!

These add a new type, a new property on VoiceState, a new permission (REQUEST_TO_SPEAK)
and 2 new endpoints to manage self/user's voice states.

Link to DAPI docs: discord/discord-api-docs#2751
The docs are still "in progress", they may change some things (the permission) but the rest should be good to implement.

If a PR is made, it should be made into a draft until the dapi docs are merged, and then we can merge it once we know nothing else will change randomly.

Sticker support

Message objects can have an array of stickers associated with them.

This will require a new class (Sticker) and an additional field (#stickers) on Message.

Membership Gates

Add support for detecting the guild feature, CRUD operations, and gateway events associated with it.

RL bucket depletion detected! Locking RL mutex for 3.859 seconds pre-emptively

First of all, I would like to thank every contributor of this project, because it's been tremendously easy and very straight-forward to create a bot for Discord with your help.

The main goal of my bot is to list files and directories inside Google Drive, as well as downloading them. For that, I'm using the Google Drive V3 API.

I've already managed to do all that.

My problem is: I'm using event.respond to list files individually. Because of that, after 5 messages posted by the bot, it waits 4 seconds and then resumes. (This is what causes "RL bucket depletion detected! Locking RL mutex for 3.859 seconds pre-emptively")

If the limit of files displayed that I imposed is equal to 1000 files, and the 3 first lines of the message correspond to the header (composed by a greeting, the name of the bot, and the name of the current directory), as well as a line that marks the end of the directory:

1000 + 3 + 1 = 1004 lines total
ย 
ย 

So if it stops after 5 messages continously until the end of the directory,
According to my calculations

1004 / 5 = 200.8 times that the directory listing would halt

200.8 * 4 = 803.2 seconds waiting = 13.38 minutes waiting
ย 
ย 

How can I overcome this?
How can I stop this from happening?

Thank you for your time.
And again, you have been making such an amazing work! Carry on!

Error when running the library with bundler/setup

Summary

Discordrb throws an error every time I use require "bundler/setup to load the gems when I'm building my own gem.
It is possible to run it locally without require "bundler/setup but as soon as I want to deploy the gem or use bundle install --deployment the script doesn't find the required gems in /vendor/bundle.

  1. Create new gem
    bundle gem tmpGem && cd tmpGem
  2. Add discordrb to Gemfile
    gem "discordrb", github: "shardlab/discordrb", branch: "main"
  3. Make gemspec valid and install gems
    bundle install
  4. Create class and uses the ping.rb example from discordrb
# frozen_string_literal: true

require 'discordrb'
require_relative "tmpGem/version"

module TmpGem
  class Bot
    def initialize(token)
      @bot = Discordrb::Bot.new token: token
  
      puts "This bot's invite URL is #{bot.invite_url}."
      puts 'Click on it to invite it to your server.'

      @bot.message(content: 'Ping!') do |event|
       event.respond 'Pong!'
      end
    end

    def run
      @bot.run
    end

  end
end
  1. Open console and run the bot
$ ./bin/console
irb(main):001:0> TmpGem::Bot.new("TOKEN").run
  1. Run into problem and panic:
This bot's invite URL is https://discord.com/oauth2/authorize?&client_id=<DELETED>&scope=bot.
Click on it to invite it to your server.
[ERROR : websocket @ 2022-03-19 17:32:01.574] The websocket connection has closed: (no information)
[ERROR : websocket @ 2022-03-19 17:32:01.574] Websocket close frame received!
[ERROR : websocket @ 2022-03-19 17:32:01.574] Code: 4014
[ERROR : websocket @ 2022-03-19 17:32:01.574] Message: Disallowed intent(s).
[ERROR : websocket @ 2022-03-19 17:32:01.574] You attempted to identify with privileged intents that your bot is not authorized to use
Please enable the privileged intents on the bot page of your application on the discord developer page.
Read more here https://discord.com/developers/docs/topics/gateway#privileged-intents
  1. Run not into the problem:
    Remove require "bundler/setup" in ./bin/console
    Change require "tmpGem" to require_relative "../lib/tmpGem" in ./bin/console
    run step 5. again
This bot's invite URL is https://discord.com/oauth2/authorize?&client_id=<DELETED>&scope=bot.
Click on it to invite it to your server.
[INFO : websocket @ 2022-03-19 17:45:21.662] Discord using gateway protocol version: 6, requested: 6

Environment

**Ruby version: **

ruby 3.1.1p18 (2022-02-18 revision 53f5fc4236) [x86_64-linux]

Discordrb version:
fc98743

Support Reaction with Message#reacted_with

A common flow could be to get all users who reacted on a message.

message = ... # Could be event.message or message.channel(c_id).load_message(m_id)
all_reactions = message.reactions.each_with_object({}) { |r, h| h[r.to_s] = message.reacted_with(r) }

Currently, this gives

Traceback (most recent call last):
        5: from /.../discordrb/data/message.rb:284:in `reacted_with'
        4: from /.../discordrb/data/message.rb:284:in `to_a'
        3: from /.../discordrb/paginator.rb:28:in `each'
        2: from /.../discordrb/data/message.rb:281:in `block in reacted_with'
        1: from /.../discordrb/api/channel.rb:203:in `get_reactions'
NoMethodError (undefined method `ascii_only?' for #<Discordrb::Reaction:0x0000000002a50fa8>)

and can be solved by doing message.reacted_with(r.to_s) but we already support Emoji, so why not Reaction for consistency?

Further, we could provide this flow as a method such as Message#all_reaction_users. I'd put a warning on it that it needs to paginate for every 100 reactions though.

Implement EventContainer methods on CommandContainer

https://gist.github.com/swarley/e7fcc68672f37083c00ecba28c47f6cc

this code will fail to clear CommandContainer since Discordrb::Commands::CommandContainer does not implement clear!

If we extended our CommandContainer with Discordrb::EventContainer, this code would run, but it would not clear the commands since they are implemented on @commands and clear! acts on @event_handler.

I'm unsure if module extending works with super, especially if it isn't already defined, but this would be a way around it.

This isn't a crucial feature, so could be delayed until the CommandBot rework.

E: I didn't check, but this should also apply to any other EventContainer methods for consistency

Error: Unknown Member in `Channel#history`

Description

When calling Channel#history with a limit larger than the amount of messages that exist in the channel, it would seem like the method is attempting to get author details for nil messages, and the result is this error appearing multiple times:

[ERROR : main @ 2022-01-10 11:00:39.235] Unknown Member
[ERROR : main @ 2022-01-10 11:00:39.511] Unknown Member
[ERROR : main @ 2022-01-10 11:00:39.803] Unknown Member
# ... Ctrl+C is required to abort
# and each line takes some 200ms to complete, hinting a web request is in progress.

Reproduction

Run the below code on a channel that has less than 100 messages.

require 'discordrb'
channel_id = 123 # replace me with a channel ID
bot = Discordrb::Bot.new token: ENV['BOT_TOKEN']
channel = bot.channel channel_id
pp channel.history 100

Environment

Ruby version:

ruby 3.0.1p64 (2021-04-05 revision 0fb782ee38) [x86_64-linux]

Discordrb version:

  * discordrb (3.4.2 a1083b0)
  * discordrb-webhooks (3.4.2 a1083b0)

#respond is misformatting request parameters

I've tried using both the main and slash_commands branches, but whenever I try to respond to an application command event, I see:

[ERROR : websocket @ 2021-09-15 13:29:02.026] Invalid Form Body
    - data.components[0]: Only dictionaries may be used in a ModelType

If it's helpful, when I debug the request parameters (attributes variable in the api.rb's #request method) just before it's sent in discordrb, it looks like:

["https://discord.com/api/v8/interactions/REDACTED/REDACTED/callback", "{\"type\":4,\"data\":{\"content\":\"\",\"embeds\":[],\"flags\":0,\"components\":{\"rows\":[]}}}", {:content_type=>:json, :user_agent=>"DiscordBot (https://github.com/shardlab/discordrb, v3.4.2) rest-client/2.1.0 ruby/3.0.2p107 discordrb/3.4.2 "}]

This is fixed if I set the components keyword on the #respond method to a blank array, like so:

bot.application_command(:play) do |event|
  event.respond(content: "done", components: []) # without `components: []`, the error is thrown.
end

Server channels don't cache without a websocket

Server methods involving channels rely on a populated channel list which only occurs with a persistent WebSocket connection.

We need to fetch the guild channels if the WebSocket is not active.

Additionally, channels fetched outside the WebSocket aren't added to the channel cache when they should be.

As an extension, there may be other information on a server that isn't cached or fetched without a WebSocket connection, so these should be checked too

I'll look into this tomorrow

Ruby 2.6 Sodium Error - Can't Use Discordrb

Summary

The error I am receiving is:
/usr/share/gems/gems/discordrb-3.4.0/lib/discordrb/voice/sodium.rb:6:in `module:Sodium': uninitialized constant Discordrb::Voice::Sodium::FFI (NameError)

I get this having installed Ruby 2.6. I have reinstalled all ruby components, cleared and rebundled, every possible step (other than rebuilding the code running box) and cannot get this to operate. Any advice as to what I must be doing wrong would be greatly appreciated, or, potentially what to fix if this is indeed a bug.

Environment

Ruby version:

ruby 2.6.7p197 (2021-04-05 revision 67941) [x86_64-linux]

Discordrb version:

*** LOCAL GEMS ***

discordrb (3.4.0)
discordrb-webhooks (3.3.0)

Support new slash commands

Describe your feature request in as much detail as you can here.

  • It is a feature supported by Discord's API, but missing from the library

https://discord.com/developers/docs/interactions/slash-commands

The python example is

url = "https://discord.com/api/v8/applications/<my_application_id>/commands"

json = {
    "name": "blep",
    "description": "Send a random adorable animal photo",
    "options": [
        {
            "name": "animal",
            "description": "The type of animal",
            "type": 3,
            "required": True,
            "choices": [
                {
                    "name": "Dog",
                    "value": "animal_dog"
                },
                {
                    "name": "Cat",
                    "value": "animal_dog"
                },
                {
                    "name": "Penguin",
                    "value": "animal_penguin"
                }
            ]
        },
        {
            "name": "only_smol",
            "description": "Whether to show only baby animals",
            "type": 5,
            "required": False
        }
    ]
}

# For authorization, you can use either your bot token 
headers = {
    "Authorization": "Bot 123456"
}

# or a client credentials token for your app with the applications.commmands.update scope
headers = {
    "Authorization": "Bearer abcdefg"
}

r = requests.post(url, headers=headers, json=json)

Implement ApplicationCommandContainer

Much like CommandContainer and EventContainer, it seems there'd be benefit to adding an ApplicationCommandContainer or something similar, to modularize adding slash commands.

RFC - Support optional API JSON parameters

In the documentation, we have optional and nullable fields. In the past, we have either provided optional fields with default values or not provided them as options at all.

To support them with our current implementation, we could build the hash separately to only include values when they are not nil. Unfortunately, this begs the question on what to do if the field is both optional and nullable. If we want to explicitly set it as nil, and not ignore nil values in the hash, how would we implement this?

Perhaps a symbol or constant on the API scope API::Nil for explicitly setting a field as nil, or the other way API::Empty to make it not included when the field is optional.
For the first, the methods would parse out the nils out of the hash, and then transpose API::Nil to nil (or maybe to_json will do this automatically)
For the second, we only remove fields that have the `API::Empty as the value.

In terms of user experience, I prefer the first, but I'd love to hear additional thoughts on the matter.

Also, with the rework of the API methods planned for 4.0, I would like to see a way to pass data, either JSON or Hash, to the method manually to give the user more control, and include support for any extra parameters without updating. This would be in addition to what we have right now.

Unable to return message reactions

Summary

The issue I'm facing is that message.reactions or message::reactions returns an empty array, even though there are reactions to the message. I can confirm the message is correct because message::channels and such return expected results. Please let me know if I'm doing something wrong!


Environment

  • uname -sr: Linux 5.11.7-arch1-1
  • CPU: R7 3800X

Ruby version:

ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-linux]

Discordrb version:

*** LOCAL GEMS ***

discordrb (3.4.0)
discordrb-webhooks (3.3.0)

`API::Channel.edit_message` does not support components

Summary

Channel#edit passes a 7th argument to API::Channel.edit_message for components, but edit_message can only support 6.

def edit_message(token, channel_id, message_id, message, mentions = [], embed = nil)

response = API::Channel.edit_message(@bot.token, @channel.id, @id, new_content, [], new_embed ? new_embed.to_hash : nil, components)


Environment

Ruby version:

Ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [x86_64-linux]

Discordrb version:

Latest main: discordrb (3.4.2 2e4ecc9)

Support message type methods

Create an internal mapping of type names to their integer value and expose methods to determine the type for Message objects.

API method review

Summary

While working on slash command routes, I've noticed that there are more than a few API methods with some common mistakes.

  1. The final argument is not a hash, for example:
  def token_webhook(webhook_token, webhook_id)
    Discordrb::API.request(
      :webhooks_wid,
      nil,
      :get,
      "#{Discordrb::API.api_base}/webhooks/#{webhook_id}/#{webhook_token}"
    )
  end

Where the correct fix would be to add an additional {} as the final argument

  1. Some POST/PATCH methods do not include a content_type: :json header entry.

  2. Some methods are missing their links to the Discord documentation, particularly in lib/discordrb/api.rb

If anyone wants to review the methods we have and open a PR with any changes, that would be great.

On any run of 3.40+: Gateway message error! Exception: #<ArgumentError: wrong number of arguments (given 2, expected 3)>

Summary

I feel like I must be doing something wrong, but it seems like any version of discordrb 3.4.0+ fails to run for me, even in the very basic hello world use case:

bot = Discordrb::Bot.new(token: 'xxx')
bot.run

Results in:

[ERROR : websocket @ 2021-05-23 19:37:06.054] Gateway message error!
[ERROR : websocket @ 2021-05-23 19:37:06.054] Exception: #<ArgumentError: wrong number of arguments (given 2, expected 3)>
[ERROR : websocket @ 2021-05-23 19:37:06.054] /Users/jjordan/.rvm/gems/ruby-2.6.2/bundler/gems/discordrb-c5f5ea8c03e8/lib/discordrb/data/member.rb:59:in `initialize'
[ERROR : websocket @ 2021-05-23 19:37:06.054] /Users/jjordan/.rvm/gems/ruby-2.6.2/bundler/gems/discordrb-c5f5ea8c03e8/lib/discordrb/data/message.rb:107:in `new'
[ERROR : websocket @ 2021-05-23 19:37:06.054] /Users/jjordan/.rvm/gems/ruby-2.6.2/bundler/gems/discordrb-c5f5ea8c03e8/lib/discordrb/data/message.rb:107:in `initialize'
[ERROR : websocket @ 2021-05-23 19:37:06.055] /Users/jjordan/.rvm/gems/ruby-2.6.2/bundler/gems/discordrb-c5f5ea8c03e8/lib/discordrb/bot.rb:1112:in `new'
[ERROR : websocket @ 2021-05-23 19:37:06.055] /Users/jjordan/.rvm/gems/ruby-2.6.2/bundler/gems/discordrb-c5f5ea8c03e8/lib/discordrb/bot.rb:1112:in `handle_dispatch'
[ERROR : websocket @ 2021-05-23 19:37:06.055] /Users/jjordan/.rvm/gems/ruby-2.6.2/bundler/gems/discordrb-c5f5ea8c03e8/lib/discordrb/bot.rb:709:in `dispatch'
[ERROR : websocket @ 2021-05-23 19:37:06.055] /Users/jjordan/.rvm/gems/ruby-2.6.2/bundler/gems/discordrb-c5f5ea8c03e8/lib/discordrb/gateway.rb:727:in `handle_dispatch'
[ERROR : websocket @ 2021-05-23 19:37:06.055] /Users/jjordan/.rvm/gems/ruby-2.6.2/bundler/gems/discordrb-c5f5ea8c03e8/lib/discordrb/gateway.rb:691:in `handle_message'
[ERROR : websocket @ 2021-05-23 19:37:06.055] /Users/jjordan/.rvm/gems/ruby-2.6.2/bundler/gems/discordrb-c5f5ea8c03e8/lib/discordrb/gateway.rb:628:in `websocket_loop'
[ERROR : websocket @ 2021-05-23 19:37:06.055] /Users/jjordan/.rvm/gems/ruby-2.6.2/bundler/gems/discordrb-c5f5ea8c03e8/lib/discordrb/gateway.rb:576:in `connect'
[ERROR : websocket @ 2021-05-23 19:37:06.056] /Users/jjordan/.rvm/gems/ruby-2.6.2/bundler/gems/discordrb-c5f5ea8c03e8/lib/discordrb/gateway.rb:470:in `block in connect_loop'
[ERROR : websocket @ 2021-05-23 19:37:06.056] /Users/jjordan/.rvm/gems/ruby-2.6.2/bundler/gems/discordrb-c5f5ea8c03e8/lib/discordrb/gateway.rb:469:in `loop'
[ERROR : websocket @ 2021-05-23 19:37:06.056] /Users/jjordan/.rvm/gems/ruby-2.6.2/bundler/gems/discordrb-c5f5ea8c03e8/lib/discordrb/gateway.rb:469:in `connect_loop'
[ERROR : websocket @ 2021-05-23 19:37:06.056] /Users/jjordan/.rvm/gems/ruby-2.6.2/bundler/gems/discordrb-c5f5ea8c03e8/lib/discordrb/gateway.rb:165:in `block in run_async'

This appears to be due to this commit: 751261c which calls Member.new with 2 arguments, but the Member#initialize method has taken 3 arguments for the past 3 years. Surely I'm not the only person who has run this server for the past few months, but I don't see another issue for this. So, I wonder what's unique about my usage -- it seems that this code path would always cause this error.


Environment

Mac OS, Ruby 2.6.2, discordrb 3.40 or 3.4.1 or 3.4.2

Interaction#button is unusable

Summary

The Interaction#button method attempts to return the button that triggered the interaction based on the value of @type. However, this value will always be type 3: component, because it is the interaction type, not the component type. As a result, the method will always return nil.

# @return [Hash, nil] Returns the button that triggered this interaction if applicable, otherwise nil
def button
  return unless @type == TYPES[:button]

  Components::Button.new(@data, @bot)
end

Additionally, various information about the button is unavailable because the button is being constructed from the top level data of the Interaction response. Values such as label and style are only accessible via the message.components, as shown here.

I believe both issues can be resolved by restoring the Interaction#button method from my original pull request to add button support.


Discordrb version:

3.4.2 87ae658

Buttons

Buttons are hitting the API soon, and will offer new methods of interacting with messages.

We will need to support the initial components; ActionRow and Button (Potentially the dropdown menu as well depending on how quickly I get this done ๐Ÿ˜… ).

Each will require a data class for receiving interactions, and a builder for sending them with messages.

Ideally we will also have some form of resuable "component collection", but this is still up in the air and an initial implementation can be shipped without it.

Add support for `COMPETING` activity type

Support for the new actitivty type should include adding an identification method, competing?, to Activity. And a method to set a competing status, Bot#competing=.

Relevent docs here.

a1083b0b944700f582356fec3babd3fe6804c2ca breaks Member.modify_roles

Summary

If I call modify_roles once, adding some roles, and then I call it again, adding different roles, the roles I added the first time will be removed. This only begins as of a1083b0. If I roll back and use the previous commit, I'm fine.


Environment

Heroku, Ruby 3.0.2. Repros on Heroku and my own machine.

Discordrb version:

Gems included by the bundle:

  • addressable (2.8.0)
  • ballchasing (1.0)
  • concurrent-ruby (1.1.9)
  • core (1.17)
  • csv (3.2.2)
  • datacache (1.2)
  • date (3.2.2)
  • discordrb (3.4.2 f9a94c9)
  • discordrb-webhooks (3.4.2 f9a94c9)
  • domain_name (0.5.20190701)
  • duration (1.6)
  • event_emitter (0.2.6)
  • ffi (1.15.5)
  • ffi-compiler (1.0.1)
  • http (5.0.4)
  • http-accept (1.7.0)
  • http-cookie (1.0.4)
  • http-form_data (2.3.0)
  • json (2.6.1)
  • jubibot (1.4)
  • linguistics (2.1.0)
  • llhttp-ffi (0.4.0)
  • loggability (0.18.2)
  • mime-types (3.4.1)
  • mime-types-data (3.2022.0105)
  • netrc (0.11.0)
  • opus-ruby (1.0.1)
  • pg (1.2.3)
  • public_suffix (4.0.6)
  • rake (13.0.6)
  • rest-client (2.1.0)
  • rlranks (1.0)
  • rstruct (1.5)
  • single-instance (0.2)
  • steam (1.4)
  • unf (0.1.4)
  • unf_ext (0.0.8)
  • websocket (1.2.9)
  • websocket-client-simple (0.5.1)
  • yaml (0.2.0)

undefined method 'register_application_command'

Summary

Bot command returns undefined method for register_application_command and application_command

I'm running through the example for slash commands an ultimately getting errors...

require 'discordrb'

bot = Discordrb::Bot.new(token: 'TOKEN')

bot.register_application_command(:spongecase, 'Are you mocking me?', server_id: 'SERVER_ID') do |cmd|
  cmd.string('message', 'Message to spongecase')
  cmd.boolean('with_picture', 'Show the mocking sponge?')
end

The bot.register_application_command line is outputting this error:

undefined method `register_application_command' for #<Discordrb::Bot:0x000000011c04c140 @should_parse_self=false, @client_id=nil, @type=:bot, @name="", @shard_key=nil, @prevent_ready=false, @compress_mode=:large, @token="Bot TOKEN", @gateway=#<Discordrb::Gateway:0x000000011c047f00 @token="Bot TOKEN", @bot=#<Discordrb::Bot:0x000000011c04c140 ...>, @shard_key=nil, @ws_success=false, @check_heartbeat_acks=true, @compress_mode=:large, @intents=nil>, @users={}, @voice_regions={}, @servers={}, @channels={}, @pm_channels={}, @restricted_channels=[], @voices={}, @should_connect_to_voice={}, @ignored_ids=#<Set: {}>, @ignore_bots=false, @event_threads=[], @current_thread=0, @status=:online> (NoMethodError)

There's a similar output for bot.application_command


Environment

Ruby version:

ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [arm64-darwin21]

Discordrb version:

discordrb (3.4.0)
discordrb-webhooks (3.3.0)

Server#members hangs when bot doesn't use SERVER_MEMBERS intent

Summary

Running a bot without the SERVER_MEMBERS intent will cause Server#members to hang.

Debug output looks like this:

[3] pry(main)> bot.servers[TEST_SERVER_ID].members
[DEBUG : main @ 2021-05-15 17:34:18.890] Members for server <TEST_SERVER_ID> not chunked yet - initiating
[OUT : main @ 2021-05-15 17:34:18.890] {"op":8,"d":{"guild_id":<TEST_SERVER_ID>,"query":"","limit":0}}

Environment

Ruby version:
ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-darwin18]

Discordrb version:
/Users/me/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/bundler/gems/discordrb-359326e8743c

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.