Search code examples
rubydiscord

Unable to output correct hex color in Ruby using Discordrb


I have some code here that takes a hex value (clr) and converts it to a RGB value array using the Color Converter gem in Ruby to set a guild role using the discordrb library. The problem is that the color set differs from the hex value I specified. For example: If I input the hex colour #25107A I see it successfully outputs the integer value of: 3716122, but then the actual role colour that gets set in the client is #38b41a.

passthrough = ColorConverter.rgb(clr).join.to_s puts converted = passthrough.to_i

I tried only converting the array value to a string and integer respectively, but that seems to have no effect.

Currently, I'm using a slash command to prompt a user to input a hex colour and then passing that user input into the color-converter gem. Then I take the RGB value it outputs as an array and convert it into an integer. Finally, I pass the integer value as a parameter that creates the role.

require 'discordrb'

require "color_converter"

bot = Discordrb::Bot.new(token:'token_goes_here', intents: [:server_messages])

bot.ready do |event|
  puts "Logged in as #{bot.profile.username}"
end


bot.register_application_command(:booster, 'Example commands', server_id: ENV.fetch('SLASH_COMMAND_BOT_SERVER_ID', nil)) do |cmd|
  cmd.subcommand_group(:role, 'Fun things!') do |group|
    group.subcommand('claim', 'Claim your custom booster role!') do |sub|
      sub.string('name', 'Provide a name for your role.', required: true)
      sub.string('color', 'Provide a HEX color for your role.', required: true)
      sub.string('icon', 'Provide a role icon for you role. Currently, you can only use a server emoji as an icon.', required: false)

  
    end
    
  end
end


bot.application_command(:booster).group(:role) do |group|
  group.subcommand('claim') do |event|
    nme = event.options['name']
    clr = event.options['color']
    passthrough = ColorConverter.rgb(clr).join.to_i
    event.server.create_role(name: nme, colour: passthrough, hoist: false, mentionable: false, permissions: 0, reason: 'Server Booster claimed role.')
    event.respond(content: 'Your role has been successfully created. Please feel free to edit your role at any time using the ``/booster role edit`` command.', ephemeral: true)
  end

  bot.run

Solution

  • Your method of converting rgb [int, int, int] to a single 24 bit int is incorrect. Here's one way:

    r, g, b = ColorConverter.rgb(clr)
    passthrough = (r << 16) | (g << 8) | b
    

    Alternatively, you can use the ColorConverter.hex method, remove the first char which will be a "#", and then convert the 6 digit hex code to a 24 bit integer by parsing it in base 16:

    passthrough = ColorConverter.hex(clr).slice(1..).to_i(16)