medusae.cr
Medusae (Crystal Edition)
Medusae is now a Crystal-first Discord interaction toolkit focused on building payloads and routing interaction events with a strongly typed API.
Features
- Gateway intent bitmask helpers (
Medusae::Gateway::GatewayIntent) - Discord client configuration model (
Medusae::Client::DiscordClientConfig) - Interaction router (
Medusae::Client::SlashCommandRouter) - REST API helper for Discord callbacks and authenticated requests (
Medusae::Client::DiscordRestApi) - Rich payload builders:
- messages and embeds
- buttons and action rows
- string/entity/channel select menus
- modals and text inputs
Install
Add to your shard:
dependencies:
medusae:
github: cybellereaper/medusae.cr
Development
shards install
crystal spec
Example: build a component-rich message
require "medusae"
button_row = Medusae::Client::DiscordActionRow.of([
Medusae::Client::DiscordButton.primary("confirm", "Confirm"),
Medusae::Client::DiscordButton.link("https://discord.com/developers/docs", "Docs"),
])
select_row = Medusae::Client::DiscordActionRow.of([
Medusae::Client::DiscordStringSelectMenu.of("theme", [
Medusae::Client::DiscordSelectOption.of("Dark", "dark").as_default,
Medusae::Client::DiscordSelectOption.of("Light", "light"),
]).with_placeholder("Choose a theme").with_selection_range(1, 1),
])
payload = Medusae::Client::DiscordMessage.of_content("Choose your settings")
.with_components([button_row, select_row])
.as_ephemeral
.to_payload
puts payload.to_json
Example: macro-based command bot
require "medusae"
class DemoBot
include Medusae::Client::CommandBot
slash_command "ping" do |interaction|
respond_with_message(interaction, "Pong from macro bot")
end
component "confirm" do |interaction|
puts "button clicked: #{interaction}"
end
global_component do |interaction|
puts "fallback component: #{interaction}"
end
end
bot = DemoBot.new(
->(response : Medusae::Client::InteractionResponse) {
puts "Responding id=#{response.id} token=#{response.token} type=#{response.type.value} data=#{response.data}"
}
)
bot.handle_interaction(Medusae::Client::Interaction.slash_command("ping", id: "1", token: "abc"))
bot.handle_interaction(Medusae::Client::Interaction.component("confirm", id: "2", token: "def"))
See runnable files in examples/.
Example: REST interaction responder
require "medusae"
config = Medusae::Client::DiscordClientConfig.new(ENV["DISCORD_TOKEN"])
rest_api = Medusae::Client::DiscordRestApi.new(config)
router = Medusae::Client::SlashCommandRouter.new(rest_api.interaction_responder)
router.register_slash_handler("ping") do |interaction|
router.respond_with_message(interaction, "pong")
end
Repository
medusae.cr
Owner
Statistic
- 0
- 0
- 0
- 0
- 0
- about 4 hours ago
- April 5, 2026
License
Links
Synced at
Sat, 25 Apr 2026 10:03:11 GMT
Languages