NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
crates.io · #4035 most downloaded on crates.io
A Rust library for the Discord API.
Last release 9 months ago
20 Dec 2025
Release timing varies
gaps range from 9 days to 1.1 years
Nearly every release is documented
notes for 59 of the last 60 stable releases
2 versions withdrawn
withdrawn after publishing
10 years old
97 releases · first in 2016
🎉 It has finally come for the biggest release of Serenity yet! 🎉
🎉 It has finally come for the biggest release of Serenity yet! 🎉
Thanks to the following for their contributions:
Nothing published for this version
One column per quarter.
Thanks to the following for their contributions:
Thanks to the following for their contributions:
A crucial release fixing a lot of misbehaviour:
lacking_ownership. ([@acdenisSK]) [c:15e7fde]#[example] text in help ([@Flat]) [c:7aea26c]AttachmentId. ([@Lakelezz]) [c:c8a5f69]channel_id_from_name-method on Guild. ([@xacrimon]) [c:aae22a2]GuildChannel::members. ([@Lakelezz]) [c:ddf7a3]EmbedMessageBuilding-trait. ([@zeyla]) [c:7c61f95]&mut self on voice_channel. ([@Lakelezz]) [c:0e55b73]s, owner_only became owners_only. ([@acdenisSK]) [c:3cf673e]voice_states doc. ([@nycex]) [c:0a640a4]methods to utils. ([@Lakelezz]) [c:c970f44]owners_privilege to bypass all permission-checks. ([@Flat]) [c:98532da]send_message. ([@acdenisSK]) [c:3902caf]contains_case_insensitive and starts_with_case_insensitive. ([@Flat]) [c:d27d391]ToString on builder-arguments instead of Display. ([@acdenisSK]) [c:13fae29]cached's name and documentation. ([@Lakelezz]) [c:7706475]only to only_in. ([@acdenisSK]) [c:26b072f]group! parsing. ([@acdenisSK]) [c:7f9c4e1]_HELP_COMMAND to the generated instance from #[help] ([@acdenisSK]) [c:9783b35]*Id::created_at() to return a DateTime<FixedOffset> instead. ([@AregevDev]) [c:8d50840]Context as argument ([@Lakelezz]) [c:62e19a7] [c:58fa50c]1.35.0. ([@Lakelezz]) [c:8c83fec]build-method. ([@Lakelezz]) [c:c6ae140]quit method. ([@zeyla]) [c:f7109ee]VecMap. ([@acdenisSK]) [c:9450d4b]Thanks to the following for their contributions:
Thanks to the following for their contributions:
A short release for some things we overlooked.
Thanks to the following for their contributions:
Thanks to the following for their contributions:
This is a testing release for receiving feedback regarding the new big changes introduced, whether they’re satisfactory, or horrid and should be revised, before we officially stabilise them.
Please inform us of any suggestions, or bugs you might have!
Serenity has migrated to the 2018 Rust edition, whose lints and idioms are enforced in its codebase.
The cache and http are no longer globally accessible. The Context now carries instances to them, and as such, all functions that had used the cache and http before, now accept the context as their first parameter in order to operate. Passing the fields present on the context is acceptable too.
The framework had been swayed off of builders, and proselytised to procedural, macro-based attributes. Giving options to your commands might have looked like this:
command!(foo(ctx, msg, args) {
...
});
framework.command("foo", |c|
c.description("I am foobar")
.min_args(1)
.max_args(2)
.usage("#foo bar baz")
.cmd(foo));
But now, it will be:
#[command] // Marks this function as a command.
#[description = "I am foobar"] // These are the "parameter" attributes, for providing the options to the attribute macro.
#[min_args(1)]
#[max_args(2)]
#[usage("#foo bar baz")]
fn foo(ctx: &mut Context, msg: &Message, args: Args) -> CommandResult {
...
Ok(())
}
The same happened to creating groups, but with macro! style flavour, which have become a compulsory step in registering your commands:
group!({
name: "fizzbuzz",
options: {
prefix: "fezz",
...
},
commands: [foo],
});
All .commands and .ons are thus replaced with simple calls to .group:
framework.group(&FIZZBUZZ_GROUP); // !
! - procedural macros are functions that accept Rust code, return Rust code. The Rust code that the #[command] (and similarly, group!) macro generates is the function you supplied it with, and a static instance of options that you've configured the command with. The static is assigned a suffixed, all uppercase version of the function’s name (or in the case of group!, of the name field). Hence this weird identifier from nowhere.
To help new (and existing) users familiarise themselves with the library better, we have decided to write a book similar to one of Rust's official learning material to the language, The Book.
It's no ready yet, but we hope that on its release that it will clear misunderstandings (if any), explain the why and how of the library and put you in the right direction of Discord bot making!
Thanks to the following for their contributions:
This release fixes a few bugs.
Thanks to the following for their contributions:
Thanks to the following for their contributions:
Thanks to the following for their contributions:
As unusual as it may sound for a patch version, we had to bump our minimum supported Rust version to 1.31.1 as a consequence of certain dependencies publishing releases containing uncompilable code for 1.25 rustc.
This is a celebratory release for Valentine's day, which we present to you with utmost courtesy.
This is a celebratory release for Valentine's day, which we present to you with utmost courtesy.
Thanks to the following for their contributions:
typemap does not need to be pulled in as a dependency for serenity anymore.
You can remove typemap from your #[dependencies] table in your Cargo.toml and simply import its types from the prelude:
use serenity::prelude::{ShareMap, TypeMapKey};
Channel ([@Erk-]) [c:2cb67df]Into<u64> and Into<i64> for ID types ([@Lakelezz]) [c:794393c]ShareMap and Key types from typemap ([@zeyla]) [c:b11b4e2]colour in example 11 ([@Erk-]) [c:7066ed2]guild_member_removal ([@Lakelezz]) [c:dd75410]Region’s Japan-variant lowercase (fixes inconsistency) ([@Lakelezz]) [c:065f55b]create_channel’s example. ([@acdenisSK]) [c:bca1530]cmd. ([@Mishio595]) [c:e8d0628]User::nick_in. ([@zeyla], [@acdenisSK]) [c:11d5b72] [c:98bece3]Emoji::url to use .gif for animated emoji ([@mshenrick]) [c:ae0fc14]Route::guild_ban_optioned ([@Mishio595]) [c:3c166e3]has_role temporarily (@Erk-) [c:204e0b9]Thanks to the following for their contributions:
Mini-release.
Thanks to the following for their contributions:
Voice on Windows wiki entry to README.md ([@Lakelezz]) [c:99b72358]base64 and sodiumoxide dependencies ([@DoumanAsh]) [c:5f9ed749]unwraps to expects and update to nested imports ([@Lakelezz]) [c:d6c4beea]Per [c:75fb5c04], the utils::is_nsfw has been deprecated. Instead, the is_nsfw methods on the channel structs (as in GuildChannel::is_nfsw) are to be…
This is a celebration release for the anniversary of the failed Gunpowder Plot enacted against King James of England and Scotland in 1605.
Thanks to the following for their contributions:
Systems with OpenSSL 1.x.x installed will not be able to compile Serenity as it depends on an older version of OpenSSL (0.9.x). To circumvent this, you need to add a patch section to your Cargo.toml for ishitatsuyuki's fork, which is compatible with 1.x.x, like so:
[patch.crates-io]
openssl = { git = "https://github.com/ishitatsuyuki/rust-openssl", branch = "0.9.x" }
Discord no longer considers channels with the prefix nsfw- in their name as NSFW. Per [c:75fb5c04], the utils::is_nsfw has been deprecated. Instead, the is_nsfw methods on the channel structs (as in GuildChannel::is_nfsw) are to be used for checking their nsfw-ness.
cache feature ([@Erk-]) [c:176fde29]cache feature ([@Bond-009]) [c:9f834b2b]travis_wait to extend build-time ([@Lakelezz]) [c:5b6574c3]This is a maintenance release fixing a number of bugs with a few miscellaneous internal changes.
This is a maintenance release fixing a number of bugs with a few miscellaneous internal changes.
Thanks to the following for their contributions:
BotGateway ([@zeyla]) [c:12bbc1a]Member::user_id ([@zeyla]) [c:669da40]http::create_private_channel (regression from 0.5.6)
([@zeyla]) [c:30a325e]GuildChannel::_permissions_for on no-cache builds (regression
from 0.5.8) ([@zeyla]) [c:e59f766]is_command_visible work with DMs ([@Roughsketch])
[c:7295079]MessageBuilder::push_codeblock_safe ([@zeyla])
[c:e66812a]has_correct_permissions when no guild is available
([@Lakelezz]) [c:19c65bd]unrecognised_command ([@Lakelezz]) [c:966cb3e]http::raw and re-export ([@zeyla])
[c:6157f61]MessageBuilder ([@zeyla]) [c:14c6099]Message::is_private ([@zeyla])
[c:fe69ef0]Per [c:71edc3a], methods on ID structs like ChannelId::find have been deprecated and replace with UserId::to_channel_cached. Similarly, methods like G…
This is a hotfix release for incorrect routing and to fix a large number of broken documentation links.
Thanks to the following for their contributions:
Per [c:71edc3a], methods on ID structs like ChannelId::find have been
deprecated and replace with UserId::to_channel_cached. Similarly, methods like
GuildId::get have been replaced with GuildId::to_partial_guild. While the
original methods have not been removed, they have been deprecated.
Colour::hex ([@Mishio595]) [c:8bec4af]to_*, as_* methods on Id types, deprecate get and find
methods ([@Lakelezz]) [c:71edc3a]Args::iter_quoted ([@acdenisSK]) [c:7b0cff6]This is a hotfix release for an incorrect warning about cache deadlocking during event dispatches in the client and fixing some routing method typos d
This is a hotfix release for an incorrect warning about cache deadlocking during event dispatches in the client and fixing some routing method typos due to the HTTP rewrite.
Thanks to the following for their contributions:
Per [c:01e3c33], Context::edit_profile has been deprecated. Call serenity::edit_profile instead.
This is a bugfix release that fixes a long-standing bug causing shards to
randomly die under certain rare conditions when dispatching the Ready event,
and compilation of the cache and client features without the framework
feature. This also contains an internal rewrite of the HTTP module.
The minimum required rustc version is now pinned at 1.25.0.
Thanks to the following for their contributions:
Per [c:01e3c33], Context::edit_profile has been deprecated. Call
serenity::http::edit_profile instead.
impl AsRef<MessageId> for Message ([@Mishio595]) [c:1de3937]From impls for Game, genericify Game params ([@zeyla])
[c:e1332a5], [c:a4c3fec]http::fire, http::request public ([@zeyla]) [c:0d55363]Args ([@acdenisSK])
[c:73ab20f]PRIORITY_SPEAKER permission ([@Erk-])
[c:2179623]Args ([@acdenisSK]) [c:e5ea6c1],
[c:9568e3b]mut, fixing no-framework compilation ([@acdenisSK])
[c:90c7ec4]Args ([@acdenisSK]) [c:0501020]Context::edit_profile ([@zeyla]) [c:01e3c33]ChannelId::send_message's dead links ([@acdenisSK]) [c:7a93557]UserId::get docs ([@zeyla]) [c:e2873c8]GuildId::member use cache when possible ([@Roughsketch])
[c:21eb42f]StandardFramework::complex_bucket docs
([@acdenisSK]) [c:02de778]positions ([@acdenisSK]) [c:2a6c3b1]Configuration default value listings ([@zeyla])
[c:602c5a7]This release is mostly a bugfix release. Thanks to the following for their contributions:
This release is mostly a bugfix release. Thanks to the following for their contributions:
Args::rest ([@acdenisSK]) [c:9b2cd75]Message::guild_id structfield ([@foxbot], [@zeyla]) [c:a9e8626],
[c:3121f90]http::ratelimiting::offset ([@zeyla]) [c:55555b8]utils::Colour ([@zeyla]) [c:bbfc8e2]impl From<&ID> for ID for all Id types ([@zelya]) [c:9e45642],
[c:530ea76]streamer::ffmpeg_optioned ([@zeyla]) [c:5dab87b], [c:1f3a57e]GuildChannel ([@Mishio595]) [c:ce8da79]Mentionable for ChannelCategory, Group,
PrivateChannel ([@zeyla]) [c:dd3744b], [c:8ce8234], [c:d11d916], [c:5abc7d1]Args::find{,_n} to be quote-aware ([@acdenisSK])
[c:f0f06b7]Args test ([@zeyla]) [c:2ef660e]Send + Sync bounds on Check ([@acdenisSK])
[c:f09b661]utils::is_nsfw slicing ([@acdenisSK], [@zeyla]) [c:0067c33],
[c:ccd2506]nsfw- case in utils::is_nsfw ([@zeyla]) [c:bd4aa0a]Invite::guild and RichInvite::guild optional ([@zeyla])
[c:3a647e3]Args ([@acdenisSK]) [c:04b0be1]CreateEmbed::fields ([@acdenisSK]) [c:703d135]CreateEmbed::field ([@acdenisSK]) [c:5b66ace]CreateEmbed::field and CreateEmbed::fields usage to example
11 ([@drklee3]) [c:a9a2c27]Args::new ([@acdenisSK]) [c:b520ec7]Thanks to the following for their contributions:
Thanks to the following for their contributions:
Message::member structfield ([@zeyla]) [c:0e1e8fb]Mentionable for CurrentUser ([@zeyla]) [c:4a24c90]From<CurrentUser> for User and
From<&CurrentUser> for User ([@zeyla]) [c:af7f176]Args docs ([@acdenisSK]) [c:2603063]Message::mentions_user_id, Message::mentions_user
([@Lakelezz]) [c:1162e68]Member::highest_role_info ([@zeyla])
[c:c659bbd]str::match_indices for some Args ops ([@acdenisSK])
[c:cc6b567]if length == 1 branch in Args functions ([@acdenisSK])
[c:6346975]Args::find, Args::find_n ([@acdenisSK]) [c:5ba521b]Args from the ground up ([@acdenisSK]) [c:ff9edc0]Thanks to the following for their contributions:
Thanks to the following for their contributions:
Date header into account when ratelimiting ([@zeyla])
[c:40db3c0]This release contains the usual bugfixes and helper methods.
This release contains the usual bugfixes and helper methods.
Thanks to the following for their contributions:
CreateEmbed method parameters ([@acdenisSK])
[c:f115c17]unrecognized_command method ([@Lakelezz]) [c:2937792]EventHandler ([@acdenisSK]) [c:80dfcb0]Drop impl for ffmpeg container ([@FelixMcFelix]) [c:3d67a4e]content_safe ([@megumisonoda]) [c:2ab714f]Args input is empty ([@acdenisSK])
[c:beebff5]CreateEmbed and CreateMessage consistent ([@acdenisSK])
[c:77c399b]help command precedence ([@acdenisSK]) [c:c6a5fe4]Args::is_empty behaviour ([@acdenisSK]) [c:e5bcee7]Args::full_quotes ([@acdenisSK]) [c:24d2233]AuditLogEntry::target_id ([@acdenisSK])
[c:0d779ba]AuditLogOptions to be correct types ([@acdenisSK], [@jkcclemens]) [c:217e1c6], [c:2791ed7]CreateEmbed builder methods
([@xentec], [@acdenisSK], [@zeyla]) [c:2e1eb4c] [c:d8c9d89], [c:a4cc582],
[c:ffc5ea1]no_run to doctests that instantiate a Client
([@Roughsketch]) [c:003dc2e]Args ([@acdenisSK]) [c:b9fa745]This release contains a number of fixes, a few more model helper methods, and additional framework features.
This release contains a number of fixes, a few more model helper methods, and additional framework features.
Thanks to the following for their contributions:
CreateCommand ([@acdenisSK]) [c:d193975]Message::member ([@zeyla]) [c:ce2952a]delete_messages ([@zeyla]) [c:92c91b8]Into<Option<Box<T>>> bound ([@zeyla]) [c:eee3168]This release is a rewrite of the client and gateway internals with a minimal amount of breaking changes for userland code. These changes are mainly to…
This release is a rewrite of the client and gateway internals with a minimal amount of breaking changes for userland code. These changes are mainly to prepare for Tokio and to reduce the number of atomic operations per received event, reducing the number of atomic operations by roughly 85%. The framework has also seen a rewrite, and is now centered around a trait-based design.
Thanks to the following for their contributions:
Per [c:91c8ec4], the Guild::default_channel and
Guild::default_channel_guarenteed methods now return
Option<Arc<Mutex<GuildChannel>>> instead of Option<GuildChannel>. This
avoids a clone. To access the channel, you just have to retrieve a read or write
lock by doing guild.default_channel()?.read() or
guild.default_channel()?.write().
Per [c:14b9222], there is a new Member::default_channel() function that
returns the default channel for the user. This no longer returns the channel
with the same ID as the guild itself, as this behaviour was changed by Discord.
A member's "default channel" is now the top-most channel that it has permission
to view. Accordingly, Guild::default_channel matches this behaviour.
Per [c:93e0a42], the library now uses the parking_lot crate's Mutex and
RwLock implementations over the stdlib's. parking_lots implementations are
more efficient, do not poison due to lock drops on unwinding, and implement
eventual fairness.
To account for this, change all Mutex lock retrievals and RwLock read and
write lock retrievals to not unwrap. parking_lot's Mutex::lock,
RwLock::read, and RwLock::write don't return Results, unlike the stdlib's.
Per [c:78c6df9], the Guild::features structfield is no longer a
Vec<Feature>. Discord adds guild features over time, which can cause guilds
with those new features to fail in deserialization. Instead, we're
future-proofing by making this a Vec<String>.
Per [c:65e3279], the CreateEmbed builder's field and fields functions no
longer take a builder as the argument, and instead take 3 arguments. For
example, code like this:
channel.send_message(|m| m
.embed(|e| e
.title("This is an embed")
.field(|f| f
.name("Test field")
.value("Test value")
.inline(true))));
Would now be this:
channel.send_message(|m| m
.embed(|e| e
.title("This is an embed")
.field("Test field", "Test value", true)))
Per [c:ad0dcb3], shards can no longer have their afk property set, as this was
a leftover from user account support. This removes the afk parameter of the
Context::set_presence function, removal of the parameter from the
Shard::set_presence function, and the Shard::set_afk function.
Per [c:b328b3e], the client::EventHandler no longer prefixes all trait methods
with on_. An implementation that looks like this:
use serenity::client::{Context, EventHandler};
use serenity::model::Message;
struct Handler;
impl EventHandler for Handler {
fn on_message(&self, _: Context, msg: Message) {
// ...
}
}
Now looks like this:
use serenity::client::{Context, EventHandler};
use serenity::model::channel::Message;
struct Handler;
impl EventHandler for Handler {
fn message(&self, _: Context, msg: Message) {
// ...
}
}
(a note on the serenity::model::channel::Message import later.)
Per [c:b19b031], Client::new returns a Result, as it now creates some
essential information on instantiation instead of deferring it to when a
connection is started. You can probably just unwrap this Result.
Per [c:b8efeaf], [c:d5a9aa8], and [c:65233ad], the client and gateway internals
have been rebuilt to significantly reduce the number of atomic operations
(upwards of ~85%). This means that retrieval of shard information (like the
shard latency to the Discord gateway or the current connection status) are
retrieved via the encompassing ShardManager located on
the client. This can be inserted into the client's data structfield if you
need to access that information in event or framework command handlers. See
this example for more information. Additionally,
Context::quit to shutdown the shard no longer exists; go through the
ShardManager instead.
Per [c:aad4744], the framework's Args::list function has been renamed to
Args::multiple for consistency.
Per [c:f10b9d7], [c:1fd652b], [c:0aa55a2], the framework has been reworked to be trait-based; thus as per [c:f61816c], [c:4e20277], allowed more useful functionality to commands.
Per [c:05f6ed4], the client's close handle has been removed, in favour of
doing so through the ShardManager.
Per [c:8c9baa7], the Guild::default_message_notifications, Guild::mfa_level,
PartialGuild::default_message_notifications, and PartialGuild::mfa_level
structfields are now enums to represent a stronger type, instead of u64s.
Per [c:bcd16dd], the model module has been broken up: instead of a giant root
module full of imports, types have been moved to where they fit. For example,
the Message, Reaction, and Channel structs are now in the model::channel
module. The RichInvite, Member, Role, and MfaLevel types are now in
model::guild. Refer to the commit message or the
model module docs for more information.
Per [c:be43836], the http::HttpError enum's InvalidRequest variant no longer
gives just the HTTP status code of the response. It now includes the full
Response instance.
Per [c:2edba81], the builder re-export in the utils module no longer exists
after being there in deprecation for a long time. Please import it like so:
// old
use serenity::utils::builder;
// new
use serenity::builder;
ConnectionStage derive Copy ([@acdenisSK]) [c:551f166]Vec<T> parameter with more generic
IntoIterator<Item=T> ([@ftriquet]) [c:b146501], [c:934eb3a]AsRef ([@acdenisSK]) [c:e0e7617], [c:b62dfd4]impl BanOptions for &str ([@acdenisSK]) [c:7c911d5]Default on IDs and CurrentUser ([@acdenisSK]) [c:0881e18]str::parse if parse_username fails ([@acdenisSK])
[c:8c85664]RoleId ([@acdenisSK]) [c:5d4301b]Command::aliases public ([@acdenisSK]) [c:8c83866]impl FromStr for ReactionType ([@acdenisSK]) [c:2032a40],
[c:84706f1]Into<String> to Display
([@acdenisSK]) [c:05dad71]Debug on more public types
([@thelearnerofcode]) [c:e5a6f3a]PrivateChannel::say to accept a more generic argument
([@fenhl]) [c:a359f77]impl From<EmojiId, EmojiIdentifier> for ReactionType ([@fenhl])
[c:68156c9]impl From<&Path> for AttachmentType ([@zeyla]) [c:7a5aa3c]GameType::Listening ([@hsiW], [@zeyla]) [c:40c5c12], [c:a17fea7]cmd function to CreateCommand and CreateGroup
([@acdenisSK]) [c:e748d1f]Reaction::message function ([@Roughsketch]) [c:fd19446]Reaction::channel function ([@zeyla]) [c:e02a842]Reaction::user function ([@zeyla]) [c:82b87f1]Deserialize for {,Gateway,Voice}Event ([@zeyla])
[c:c3aa63f]help() to CreateGroup ([@Lakelezz]) [c:39a1435]before/after middleware to Command ([@acdenisSK])
[c:4e20277]try_opt! macro to using ? operator ([@hsiW])
[c:2d23d8b]VIEW_AUDIT_LOG permission ([@Lakelezz]) [c:612e973]str::parse on ChannelId FromStr impl ([@acdenisSK])
[c:0525ede]Guild ([@zeyla]) [c:3d24033], [c:99d17d2],
[c:2abeea5]Args::len ([@acdenisSK]) [c:2c9b682], [c:b60d037],
[c:143fddd]Channel ([@timotree3]) [c:f0a56f4]animated field to Emoji and ReactionType ([@zeyla])
[c:f2fa349]Args ([@Lakelezz])
[c:62647f5]Region to include new voice regions ([@Flat]) [c:d264cc3]Args::iter_quoted ([@acdenisSK]) [c:032c5a7]num implementations on models ([@zeyla]) [c:0b1f684]serde::Serialize on all models ([@zeyla])
[c:25dddb6]reaction_users' after parameter ([@zeyla])
[c:85d7d5f]Member::highest_role ([@zeyla]) [c:b7542f4]Guild::greater_member_hierarchy ([@zeyla]) [c:84ff27b]webhook_id a majour parameter in ratelimiting ([@zeyla])
[c:1735e57]multiple_quoted ([@Lakelezz]) [c:9aad1aa]# finding in Guild::member_named ([@tahahawa]) [c:a7b67df]impl Form<Embed> for CreateEmbed
([@drklee3]) [c:9aaa555]Shard::latency, avoiding panics ([@zeyla])
[c:08db9fa]correct roles checks in help commands ([@Lakelezz])
[c:470f366]Guild::{default_channel, default_channel_guarenteed} now return
an Arc<Mutex<GuildChannel>> instead of a clone of the channel ([@acdenisSK])
[c:91c8ec4]" " ([@jhelwig])
[c:3a4cb18]default_channel to match Discord's new
behaviour ([@hsiW]) [c:14b9222]I from being user-implemented
([@acdenisSK]) [c:7cf1e52]parking_lot::{Mutex, RwLock} ([@zeyla]) [c:93e0a42]{Guild, PartialGuild}::features a Vec<String> ([@zeyla])
[c:78c6df9]&'static strs and
a VecMap ([@acdenisSK], [@zeyla]) [c:9908999], [c:3a0c890], [c:26fe139]CreateEmbed::field{,s} to not take builders ([@zeyla])
[c:65e3279]afk field ([@zeyla])
[c:ad0dcb3]on_ prefix to EventHandler tymethods ([@zeyla])
[c:b328b3e]Args::list -> Args::multiple ([@acdenisSK]) [c:aad4744]Guild and PartialGuild structfields
([@zeyla]) [c:8c9baa7]builder module re-export ([@zeyla]) [c:2edba81]is_bot state boolean ([@zeyla]) [c:524b8f8]InterMessage enum to
communicate over the gateway ([@zeyla]) [c:9232b8f]Error's Display impl ([@zeyla]) [c:ee2bbca]Reaction::{message, users} methods hit the API
([@zeyla]) [c:141bbfc]ToString blanket impl for Displays ([@acdenisSK])
[c:3ca7e15]Args::parse_quotes ([@zeyla]) [c:60613ef]Client::new ([@zeyla]) [c:25d79ac]User ([@Lakelezz]) [c:9da642a]User::has_role ([@zeyla]) [c:b52eb9f]Nothing published for this version
Nothing published for this version
Nothing published for this version
This release contains a hotfix for the hotfix release, as well as a slight behaviour change to the EditRole builder.
This release contains a hotfix for the hotfix release, as well as a slight
behaviour change to the EditRole builder.
The last release contained a deserialization implementation fix which seemed to work after running tests, but it turns out that not all deserialization issues were fixed.
The EditRole builder's Default implementation no longer sets a value for each
field, as this causes problems with stateless editing of roles.
EditRole::default implementation [c:795eaa1]This release contains a hotfix for snowflake deserialization on serde_json v1.0.8. Primary development is continuing on the v0.5.x branch and the [lib
This release contains a hotfix for snowflake deserialization on serde_json
v1.0.8. Primary development is continuing on the v0.5.x branch and the
[library organization].
This release contains bugfixes and marks the final release of the v0.4.x branch. Future development will continue on the v0.5.x branch.
This release contains bugfixes and marks the final release of the v0.4.x branch. Future development will continue on the v0.5.x branch.
Thanks to the following for their contributions:
Guild::member_permissions ([@zeyla]) [c:2ba4d03]Guild::permissions_for to Guild::permissions_in, keep an
alias ([@zeyla]) [c:dcac271]Member::permissions return guild-level permissions ([@zeyla])
[c:d3eddc6]BanOptions ([@acdenisSK]) [c:c99091d]Guild::has_perms use Guild::member_permissions ([@zeyla])
[c:1b7101f][model] Deprecate some methods on Channel ([@zeyla]) [c:23ff6f]
This release contains the regular bugfixes, new features and slight behaviour changes.
Thanks to the following people for their contributions:
PartialEq impls and doc-tests to Args ([@acdenisSK]) [c:f9e5e76]Args ([@acdenisSK]) [c:9428787]DispatchError ([@acdenisSK]) [c:a58de97]str::parse if utils::parse_username fails ([@acdenisSK]) [c:292ceda]User::has_role ([@zeyla]) [c:d3015a0ff]Context ([@zeyla]) [c:3616585]allow_whitespace ([@ConcurrentMarxistGC]) [c:e694766]help_commands.rs ([@Lakelezz]) [c:e02d5fb]delete_message if there's just one message to delete ([@acdenisSK]) [c:c7aa27d]ChannelType ([@acdenisSK]) [c:e57b510]Mutex and RwLock from the prelude ([@zeyla]) [c:74ec713]Cargo.toml to actually be v0.4.2 ([@Caemor]) [c:5829c67]Shard ([@efyang]) [c:fcc4e2c]Channel ([@zeyla]) [c:23ff6f]This release contains bugfixes and some newly added or newly exposed functionality.
This release contains bugfixes and some newly added or newly exposed functionality.
Thanks to the following for their contributions this release:
IntoIterator ([@ftriquet])[c:55167c3]IntoIterator ([@ftriquet]) [c:022e35d]Guild::members_starting_with ([@Lakelezz]) [c:b3aa441]Guild::members_containing ([@Lakelezz]) [c:1b167b5]impl<'a> BanOptions for &'a str ([@acdenisSK]) [c:cf40386]Default on CurrentUser and IDs ([@acdenisSK]) [c:09a8a44]Guild::members_username_containing, members_nick_containing
([@Lakelezz]) [c:002ce3a]Args ([@acdenisSK]) [c:0ed1972]has_all_requirements public ([@Lakelezz]) [c:08d390c]request_client! for attachment downloading ([@lolzballs])
[c:71f709d]User::tag and CurrentUser::tag discrim output ([@zeyla])
[c:6b9dcf5]initialized method purpose ([@acdenisSK]) [c:05f158f]to_owned -> to_string ([@acdenisSK]) [c:1bf4d9c]Args ([@acdenisSK]) [c:8572943]env_logger bot example [c:0df77b9]Member::roles ([@hsiW]) [c:8565fa2]try_opt! macro ([@hsiW]) [c:9b0c053]Per commit [c:ebc4e51], deprecated functions were finally removed. The following can simply have their usage renamed:
This release contains a lot of added functionality, minor-scale rewrites, bugfixes, documentation work, and the beginning of a rewrite to use the tokio ecosystem.
The release was delayed due to a [fairly majour bug][rust-websocket:issue:137] in rust-websocket that we have forked over to temporarily fix.
This release was lead in development by [@acdenisSK].
Thanks to the following for their contributions this release:
Per commits [c:af1061b], [c:cdedf36], and [c:aa307b1], Direct Messaging other bot users is now disallowed by the API. To fix this, simply don't do it.
Per commit [c:ebc4e51], deprecated functions were finally removed. The following can simply have their usage renamed:
Cache::get_channel --> Cache::channelCache::get_guild --> Cache::guildCache::get_guild_channel --> Cache::guild_channelCache::get_member --> Cache::memberCache::get_private_channel --> Cache::private_channelCache::get_role --> Cache::roleCache::get_user --> Cache::userChannelId::get_invites --> ChannelId::invitesChannelId::get_message --> ChannelId::messageChannelId::get_messages --> ChannelId::messagesChannelId::get_reaction_users --> ChannelId::get_reaction_usersChannelId::get_webhooks --> ChannelId::webhooksChannel::get_message --> Channel::messageChannel::get_messages --> Channel::messagesChannel::get_reaction_users --> Channel::reaction_usersClient::login_bot --> Client::newClient::login --> Client::newColour::get_b --> Colour::bColour::get_g --> Colour::gColour::get_r --> Colour::rColour::get_tuple --> Colour::tupleCurrentUser::distinct --> CurrentUser::tagGroup::get_message --> Group::messageGroup::get_messages --> Group::messagesGroup::get_reaction_users --> Group::reaction_usersGuild::get_bans --> Guild::bansGuild::get_channels --> Guild::channelsGuild::get_emoji --> Guild::emojiGuild::get_emojis --> Guild::emojisGuild::get_integrations --> Guild::integrationsGuild::get_invites --> Guild::invitesGuild::get_member --> Guild::memberGuild::get_members --> Guild::membersGuild::get_member_named --> Guild::member_namedGuild::get_prune_count --> Guild::prune_countGuild::get_webhooks --> Guild::webhooksGuildId::get_bans --> GuildId::bansGuildId::get_channels --> GuildId::channelsGuildId::get_emoji --> GuildId::emojiGuildId::get_emojis --> GuildId::emojisGuildId::get_integrations --> GuildId::integrationsGuildId::get_invites --> GuildId::invitesGuildId::get_member --> GuildId::memberGuildId::get_members --> GuildId::membersGuildId::get_prune_count --> GuildId::prune_countGuildId::get_webhooks --> GuildId::webhooksMessage::get_reaction_users --> Message::reaction_usersPartialGuild::get_bans --> PartialGuild::bansPartialGuild::get_channels --> PartialGuild::channelsPartialGuild::get_emoji --> PartialGuild::emojiPartialGuild::get_emojis --> PartialGuild::emojisPartialGuild::get_integrations --> PartialGuild::integrationsPartialGuild::get_invites --> PartialGuild::invitesPartialGuild::get_member --> PartialGuild::memberPartialGuild::get_members --> PartialGuild::membersPartialGuild::get_prune_count --> PartialGuild::prune_countPartialGuild::get_webhooks --> PartialGuild::webhooksPrivateChannel::get_message --> PrivateChannel::messagePrivateChannel::get_messages --> PrivateChannel::messagesPrivateChannel::get_reaction_users --> PrivateChannel::reaction_usersRole::edit_role --> Role::editUser::distinct --> User::taghttp::send_file has been replaced by http::send_files. Instead of using http::send_file like so:
use serde_json::Map;
use serenity::http;
use serenity::model::ChannelId;
use std::fs::File;
let channel_id = ChannelId(253635665344987136);
let filename = "mr-sakamoto.png";
let file = File::open(&format!("./img/{}", filename))?;
let map = Map::<String, Value>::new();
http::send_file(channel_id, file, filename, map)?;
Instead send an attachment of files, such as:
use serde_json::Map;
use serenity::http;
use serenity::model::ChannelId;
use std::fs::File;
let channel_id = ChannelId(253635665344987136);
let files = vec![
(File::open(&format!("./img/{}", filename))?, filename),
];
let map = Map::<String, Value>::new();
http::send_files(channel_id, files, map)?;
Similar logic can be applied to shortcut methods which have been removed, namely:
Channel::send_file (instead use Channel::send_files)ChannelId::send_file (instead use ChannelId::send_files)Group::send_file (instead use Group::send_files)GuildChannel::send_file (instead use GuildChannel::send_files)PrivateChannel::send_file (instead use PrivateChannel::send_files)Instead of using the now-removed Channel::delete_messages and
Channel::delete_permission, use the inner channel's method:
use serenity::model::{Channel, ChannelId};
let channel = ChannelId(253635665344987136).get()?;
let message_ids = vec![
MessageId(359845483356749825),
MessageId(359854838403694592),
];
if let Channel::Guild(c) = channel {
c.delete_messages(&message_ids)?;
}
Similar logic can be applied to Channel::delete_permission.
Member::find_guild ended up being only a shortcut to the Member::guild_id
structfield. Instead of calling the find_guild method like
member.find_guild(), instead access the structfield directly via
member.guild_id.
The model::permissions::{general, text, voice} methods have been removed, as
they ended up being shortcuts to the model::permissions::PRESET_GENERAL,
model::permissions::PRESET_TEXT, and model::permissions::PRESET_VOICE
constants, respectively.
Per commit [c:ea432af], event handling is now done via implementing a trait. Instead of passing functions to the client directly like:
use serenity::Client;
use std::env;
let mut client = Client::new(env::var("DISCORD_TOKEN")?);
client.on_message(|ctx, msg| {
// code
});
Instead implement the new EventHandler trait:
use serenity::client::{Client, Context, EventHandler};
use serenity::model::Message;
struct Handler;
impl EventHandler for Handler {
fn on_message(&self, ctx: Context, msg: Message) {
// code
}
}
let client = Client::new(env::var("DISCORD_TOKEN")?);
Per commit [c:4f2e47f], the deprecated ext module (which has recently only
been a series of re-exports for the cache, framework, and voice modules)
was removed. Instead of using serenity::ext::cache for example, use
serenity::cache.
Per commit [c:878684f], due to the concept of default channels being changed,
GuildId::as_channel_id has been deprecated due to the fact that the ID of the
default channel of a guild will no longer necessarily be the same as the guild's
ID.
If you require this same exact functionality (the GuildId as a ChannelId),
rewrite your code from:
use serenity::model::GuildId;
let channel_id = GuildId(81384788765712384).as_channel_id();
to:
use serenity::model::{ChannelId, GuildId};
let guild_id = GuildId(81384788765712384);
let channel_id = ChannelId(guild_id.0);
Per commits [c:2b053ea], [c:8cc2300], [c:8e29694], and [c:948b27c], custom frameworks can now be implemented, meaning that a built implementation is now passed instead of a base framework being provided and mutated. To use the old framework, modify code from:
use serenity::Client;
use std::env;
let mut client = Client::new(&env::var("DISCORD_TOKEN")?);
client.with_framework(|f| f
// method calls to mutate framework here
);
to the new style:
use serenity::client::{Client, EventHandler};
use serenity::framework::standard::StandardFramework;
use std::env;
struct Handler;
impl EventHandler for Handler { }
let mut client = Client::new(&env::var("DISCORD_TOKEN")?, Handler);
client.with_framework(StandardFramework::new()
// method calls here to mutate framework here
);
Per commit [c:fc9eba3d], if you were pattern matching on the
serenity::framework::DispatchError::CheckFailed variant, instead either use or
ignore the matched data by rewriting code from:
use serenity::framework::DispatchError;
// Code to begin dispatch error handling here.
match dispatch_error {
DispatchError::CheckFailed => {
// Handle operation here.
},
// Other variants.
}
to:
// The standard implementation is now in a "standard" framework module, but
// that's unrelated.
use serenity::framework::standard::DispatchError;
match dispatch_error {
DispatchError::CheckFailed(_) => {
// Handle operation here.
},
// Other variants.
}
Per commits [c:45d72ef], [c:03b6d78], and [c:d35d719], the framework's
command! macro no longer parses arguments' types for you. You are now given an
Args struct that you can retrieve arguments from and parse from to a requested
type that implements FromStr.
For example, a simple sum function that looked like:
#[macro_use] extern crate serenity;
command!(sum(_ctx, msg, _args, x: i64, y: i64) {
let _ = msg.reply(&format!("Result: {}", x + y));
});
Now looks like:
use serenity::client::Context;
use serenity::framework::standard::Args;
use serenity::model::Message;
fn sum(_: &mut Context, msg: &Message, args: Args) -> Result<(), String> {
let x = match args.single::<i64>() {
Ok(x) => x,
Err(_) => return Ok(()),
};
let y = match args.single::<i64>() {
Ok(y) => y,
Err(_) => return Ok(()),
};
let _ = msg.reply(&format!("Result: {}", x + y));
}
Per commit [c:562ce49], serenity::model::User's FromStr implementation can
now hit the REST API. No code changes required, but do note the possibility.
Per commit [c:40031d9], the following routes have been removed for being userbot routes, which are leftovers from when serenity supported them and had them removed:
http::get_application_infohttp::get_applicationshttp::get_emojihttp::get_emojismodel::Guild::emojimodel::Guild::emojismodel::GuildId::emojimodel::GuildId::emojismodel::PartialGuild::emojimodel::PartialGuild::emojisPer commit [c:092f288], bitflags has been upgraded, which introduces a minor change in how to use permissions.
Update code from:
use serenity::model::permissions::{ADD_REACTIONS, MANAGE_MESSAGES};
foo(vec![ADD_REACTIONS, MANAGE_MESSAGES]);
to:
use serenity::model::Permissions;
foo(vec![Permissions::ADD_REACTIONS, Permissions::MANAGE_MESSAGES]);
CommandOrAlias and CommandGroup.commands
public ([@joek13]) [c:3db42c9]on_cached event ([@acdenisSK]) [c:6d6063f]is_new paramenter to the guild_create handler ([@acdenisSK])
[c:3017f6d]Guild::members_with_status ([@acdenisSK]) [c:a7a0945],
[c:29ee627]Ban and User impl Eq, Hash, and PartialEq
([@acdenisSK]) [c:64bfc54]BanOptions take and return an &str ([@acdenisSK]) [c:1ab8b31]{ChannelId, GuildChannel, PrivateChannel}::name functions
([@acdenisSK]) [c:ca0f113]CloseHandle derive Copy ([@blaenk]) [c:b249c82]nsfw property to channels ([@acdenisSK], [@Bond-009])
[c:b602805], [c:fd89d09], [c:fd47b86]Message::is_own ([@acdenisSK], [@zeyla]) [c:5a96724],
[c:fdbfbe0], [c:6572580]From<(u8, u8, u8)> for Colour ([@acdenisSK]) [c:6f147e1]Display bound instead of
&str ([@acdenisSK]) [c:7e913b6], [c:05162aa], [c:0810ab7]UserId::get ([@Roughsketch]) [c:bfdb57c]with_config{,_mut} ([@acdenisSK]) [c:1a08904]CreateCommand::num_args ([@Roughsketch]) [c:aace5fd]Context::handle ([@acdenisSK]) [c:97e84fe]MessageBuilder::push_mono_safeuse_quotes is active ([@acdenisSK]) [c:e7a5ba3]Reaction::name optional ([@acdenisSK]) [c:8f37f78]permissions::PRESET_GENERAL bits ([@zeyla]) [c:9f02720]ext module ([@acdenisSK]) [c:4f2e47f]GuildId::as_channel_id ([@acdenisSK]) [c:878684f]I bound for MessageBuilder language params ([@acdenisSK])
[c:f16af97]DispatchError::CheckFailed ([@Lakelezz])
[c:fc9eba3]FromStr parsing errors
([@acdenisSK]) [c:8bf77fa], [c:8d51ead]User's FromStr impl to hit REST ([@Roughsketch]) [c:562ce49]ModelError doctest ([@zeyla]) [c:bd9fcf7]EventHandler ([@acdenisSK]) [c:fdfd5bc]EventHandler changes ([@acdenisSK]) [c:511ec87]PrivateChannel::name ([@acdenisSK]) [c:14fd41b]match to an and_then ([@acdenisSK]) [c:5e5f161]Send + Sync bounds ([@acdenisSK]) [c:3c2716b]http::set_token ([@zeyla]) [c:cb18d42]This release contains a number of added methods, fixes, deprecations, and documentation improvements. It brings a module restructure and an upgrade to…
This release contains a number of added methods, fixes, deprecations, and
documentation improvements. It brings a module restructure and an upgrade to
rust-websocket v0.20, hyper v0.10, and switching to native-tls, meaning
using an up-to-date rust-openssl v0.9 on Linux, schannel on Windows, and
Secure Transport on Mac. The long-standing issue [#56][issue:56] was closed.
Thanks to the following for their contributions this release:
Invite retrieval functions now accept a stats argument. If you don't need
stats, just pass false.
ChannelId::create_permission and GuildChannel::create_permission now accept
a reference, as they do not need to own the overwrite.
The deprecated GuildChannel methods (get_invites, get_message,
get_messages, get_reaction_users, get_webhooks) have been removed. Use
their equivalents without the get_ prefix.
The send_file functions have been deprecated. Use send_files instead by
passing a Vec.
CurrentUser::distinct and User::distinct have been deprecated. Instead use
CurrentUser::tag and User::tag.
User::get has been deprecated. Instead, use UserId::get.
Role::edit_role has been deprecated, renaming it to Role::edit.
time has been removed as a direct dependency, moving to chrono.
Public-facing fields that return time::Timespec or were a String in ISO-3339
format are now chrono::DateTime<UTC>s. Instead use its methods for what was
being done with the Timespecs or strings.
User::direct_message and User::dm now accept a builder to allow for more
complete, yet simple use out of the methods. Instead of passing a &str, use
the provided builder:
// old
user.dm("hello")?;
// new
user.dm(|m| m.content("hello"))?;
Client::login has been deprecated. Instead use Client::new:
use serenity::Client;
use std::env;
// old
let client = Client::login(&env::var("DISCORD_TOKEN")?);
// new
let client = Client::new(&env::var("DISCORD_TOKEN")?);
Member::guild_id is now no longer an Option<GuildId> -- just a GuildId.
Since this is now always present, Member::find_guild has been deprecated since
the cache now never searches the cache for the guild ID.
The deprecated GuildChannel methods get_invites, get_message,
get_messages, get_reaction_users, and get_webhooks have been removed. Use
their alternatives, such as GuildChannel::invites, instead.
GuildChannel::permissions_for [c:6502ded]Invite::url(), RichInvite::url() [c:3062981]VerificationLevel::Higher [c:7dbae6b]CurrentUser::invite_url ([@Roughsketch], [@Flat]) [c:e033ff3],
[c:0b95db9]impl From<char> for ReactionType [c:2afab7c]_line + _line_safe methods to MessageBuilder ([@Roughsketch])
[c:543b604]CurrentUser ([@Roughsketch]) [c:921f7f4]Content for MessageBuilder ([@eLunate]) [c:060b06e]User::refresh [c:8c04d31]Message::channel() [c:063a52f]CurrentUser::default_avatar_url [c:2d09152]CurrentUser::face(), User::face() [c:d033909]Member::permissions [c:39a28d3] ([@acdenisSK])wait parameter to http::execute_webhook [c:dc73d1a]@everyone role when checking channel overwrites ([@Roughsketch])
[c:b468cbf]unreachable_code lint in command! macro ([@Flat]) [c:eb43b9c]send_file deserialization [c:0102706]create_permission to take a reference [c:aea9885]GuildChannel methods [c:ab7f113]Guild::create_channel doesn't require mutability [c:494cc50]*User::distinct, add *User::tag [c:6579b1f]User::get [c:afc571f]Role::edit_role, add Role::edit [c:c00f349]User::direct_message/User::dm accept a builder [c:11a02db]Client::login, add Client::new [c:7990381]Member::guild_id non-optional [c:b4bd771]Context::channel_id and Context::queue [c:8b504ad]dynamic_prefix accept an &Message [c:2845681]Channel::delete_messages, Channel::delete_permission [c:7fc49d8]Message::nonce a serde_json::Value [c:c832009]login_bot usage from docs ([@hsiW]) [c:ae395f4]VoiceManager::join in example 06 ([@barzamin]) [c:6853daf]CreateGroup docs to the struct [c:71f3dbb]cookie dependency [c:92f4ec2]#[doc(hidden)] to pub(crate) [c:32e07e4] ([@acdenisSK])Deprecate methods prefixed with get_ [c:3f03f9a]
This is a very large release with a number of rewritten components. The cache
has been rewritten to make use of memory more efficiently, the models directory
has been re-organized, structures are now deserialized via serde and
serde_derive - instead of the custom decoding build script we had - with a
number of bugfixes and other various changes and additions.
Thanks to the following for their contributions this release:
Replace uses of ext::cache::ChannelRef with model::Channel.
The following ext::cache::Cache method signatures are now encased in
Arc<RwLock>s and should be handled appropriately:
callchannelguildguild_channelgroupmemberroleuserAdditionally, GuildId::find and UserId::find now return
Option<Arc<RwLock>>s.
Member::display_name now returns a Cow<String> instead of a &str.
client::Context has had most of its methods removed. The methods were mostly
a copy of those on ChannelId. Upgrade by instead calling methods on
ChannelId:
command!(foo(ctx) {
let _ = ctx.say("hello");
});
// is now written as:
command!(bar(_ctx, msg) {
let _ = msg.channel_id.say("hello");
});
CreateMessage::nonce has been removed. Instead, simply do not provide a nonce.
ChannelId::edit_message now has an argument signature of:
&self, message_id: M, f: F
where F: FnOnce(CreateMessage) -> CreateMessage, M: Into<MessageId>
instead of
&self, message_id: M, text: &str, f: F
where F: FnOnce(CreateEmbed) -> CreateEmbed, M: Into<MessageId>
To account for this change, modify code like so:
channel_id.edit_message(message_id, "new content", |e| e);
// now:
channel_id.edit_message(message_id, |m| m.content("new content"));
Message::edit has also had an argument signature updated to:
&mut self, f: F where F: FnOnce(CreateMessage) -> CreateMessage
from:
&mut self, new_content: &str, embed: F where F: FnOnce(CreateEmbed) -> CreateEmbed
To account for this change, modify code like so:
message.edit("new content", |e| e.description("test"));
// now:
message.edit(|m| m.content("new content").embed(|e| e.description("test")));
client::rest::accept_invite, Invite::accept, and RichInvite::accept have
been removed. Instead, do not attempt this, as they were userbot functions.
Selfbot support has been completely removed. Review the [commit message][c:d9118c0] for the long list of details.
Group calls and guild sync have [also been removed][c:c74cc15]. Read the commit message for all the details.
Instead of defining multiple separate error messages for command framework message dispatches, match the dispatch error in a single method:
// old code:
client.with_framework(|f| f
.configure(|c| c
.command_disabled_message("The command `%command%` was disabled")
.blocked_guild_message("The owner of this guild has been blocked")
.invalid_permission_message("You don't have permission to use this command")));
// new code:
client.with_framework(|f| f.on_dispatch_error(|_, msg, err| {
match err {
DispatchError::CommandDisabled(command_name) => {
let _ = msg.channel_id.say(&format!("The command `{}` was disabled", command_name));
},
DispatchError::BlockedGuild => {
// this change also allows for more intelligent error messages:
if let Some(guild) = msg.guild() {
let owner_id = guild.read().unwrap().owner_id;
if let Some(user) = CACHE.read().unwrap().user(owner_id) {
let c = format!("The owner - {} - has been blocked", user.name);
let _ = msg.channel_id.say(&c);
return;
}
}
let _ = msg.channel_id.say("The owner of this guild has been blocked");
},
DispatchError::LackOfPermissions(_) => {
let _ = msg.channel_id.say("You don't have permission to use this command");
},
}
}));
All functions prefixed with get_ have had the prefix removed. For example,
Guild::get_webhooks() is now Guild::webhooks().
Instead of using model::permissions::general(), model::permissions::text(),
and model::permissions::voice(), use
model::permissions::{PRESET_GENERAL, PRESET_TEXT, PRESET_VOICE}.
say method to Group, GuildChannel, PrivateChannel [c:a0bb306]send_file/send_message impls [c:bad9ac3]Message::guild [c:9ef5522]From<&str> for ReactionType [c:e7110ad]is_nsfw check to channels [c:9268f9c]Member::kick helper [c:83b1d96]Eq, Hash, PartialEq on ReactionType [c:86a4e00] ([@acdenisSK])joined_at values [c:cd914f5][0, 1] shards [c:f0d1157]Route::None routes [c:5bf6c2d]dynamic_prefix result [c:9ec05e7] ([@Roughsketch])Context methods [c:585af23]get_ [c:3f03f9a]User.discriminator a u16 [c:0f41ffc]This is a release to fix broken nightly builds, due to a change in how rustc handles lifetimes, with a few performance optimizations and other fixes.
This is a release to fix broken nightly builds, due to a change in how rustc handles lifetimes, with a few performance optimizations and other fixes.
For Group::send_message, PrivateChannel::send_message,
and GuildChannel::send_message, instead of passing in only a &str of
content, use a CreateMessage builder:
// assuming a `channel` is bound
// old signature:
channel.send_message("hello");
// new signature:
channel.send_message(|m| m.content("hello"));
Instead of calling message_id.get_reaction_users and passing in a ChannelId,
call channel_id.get_reaction_users and pass in the MessageId. Note that the
latter already existed.
// assuming `channel_id`, `message_id`, and `reaction_type` are bound
// removed method:
message_id.get_reaction_users(channel_id, reaction_type, Some(10), None);
// alternative method:
channel_id.get_reaction_users(message_id, reaction_type, Some(10), None);
status user setting for user accounts (e.g. online, invisible)
[c:0b9bf91]EditGuild to transfer ownership [c:f00e165]command! macro [c:97f9bd1]MessageId::get_reaction_users [c:268f356]GLOBAL ratelimit mutex a unit (opt.) [c:55ccaca]This is a general release for pretty much everything, from new features to bugfixes to a switch to a more OOP style. The current minimum supported ver
This is a general release for pretty much everything, from new features to bugfixes to a switch to a more OOP style. The current minimum supported version is rustc 1.13+.
The next release will be v0.2.0, which will feature serde codegen support along with a rewrite of the framework. It will be a more modularized version of the library. v0.2.0 will require rustc 1.15+, due to the stabilization of Macros 1.1.
Thanks to the following for contributions this release:
Two of the major highlights of this release are that the broken pipe issue has
been fixed, and the library is more OOP now and therefore no longer relies on
the Context to get stuff done. The methods feature flag has been removed.
When formatting using Display for ChannelIds, RoleIds, and UserId,
instead of formatting use their Mentionable equivilants:
use serenity::model::{ChannelId, RoleId, UserId};
// old
assert_eq!(format!("{}", ChannelId(1)), "<#1>");
assert_eq!(format!("{}", RoleId(2)), "<@&2>");
assert_eq!(format!("{}", UserId(3)), "<@3>");
// new
assert_eq!(format!("{}", ChannelId(1).mention()), "<#1>");
assert_eq!(format!("{}", RoleId(2)).mention()), "<@&2>");
assert_eq!(format!("{}", UserId(3).mention()), "<@3>");
When using EmbedBuilder::{image, thumbnail}, instead of calling another
builder, provide urls directly:
use serenity::model::Embed;
// old
Embed::fake(|e| e
.image(|i| i.url("https://not.zey.moe/me.png"))
.thumbnail(|t| t.url("https://not.zey.moe/me2.png")));
// new
Embed::fake(|e| e
.image("https://not.zey.moe/me.png")
.thumbnail("https://not.zey.moe/me2.png"));
When specifying a sharding method, instead of passing a u8 for sharding info,
pass a u64:
use serenity::Client;
let client = Client::login_bot(&env::var("DISCORD_TOKEN").unwrap());
// old
client.start_shard(1u8, 5u8); // or
client.start_shards(5u8); // or
client.start_shard_range([1u8, 3u8], 8u8);
// new
client.start_shard(1u64, 5u64); // or
client.start_shards(5u64); // or
client.start_shard_range([1u64, 3u64], 8u64);
Client.shards is now private. Instead of accessing it, don't.
When creating a Colour struct yourself, instead of specifying a single value
field, pass a single tuple value:
use serenity::utils::Colour;
// old
Colour {
value: 0,
}
// new
Colour(0);
Instead of using Attachment::download_to_directory to download an attachment
to a directory, do it yourself:
use std::fs::File;
use std::io::Write;
// assuming an `attachment` has already been bound
// old
attachment.download_to_directory("./attachments");
// new
let bytes = attachment.download().unwrap();
let filepath: PathBuf = path.as_ref().join(&attachment.filename);
let mut f = File::create(&filepath);
let _ = f.write(&bytes);
Instead of calling Message::is_webhook():
// assuming a `message` has already been bound
// old
let _ = message.is_webhook();
// new
let _ = message.webhook_id.is_some();
Instead of PartialGuild::find_role(role_id):
use serenity::model::RoleId;
// assuming a `guild` has already been bound
// old
let _ = guild.find_role(RoleId(1));
// new
let _ = guild.roles.get(RoleId(1));
Instead of Guild::{get_channel, get_member}, call:
use serenity::model::{ChannelId, UserId};
// assuming a `guild` has already been bound
// old
let _ = guild.get_channel(ChannelId(1));
let _ = guild.get_member(UserId(2));
// new
let _ = guild.channels.get(ChannelId(1));
let _ = guild.members.get(UserId(2));
Instead of using Context methods, use their Id or other struct equivalents.
voice feature no longer requires the cache feature to be enabled
[c:7b45f16]framework feature no longer requires the cache feature to be enabled
[c:86cd00f]Guild, InviteGuild, and PartialGuild now have splash_url methods
[c:d58c544]Message::webhook_id for messages sent via webhooks ([@fwrs])
[c:a2cbeb6]time::Tm to be passed into the embed timestamp field, in addition to
a direct string [c:b001234]Client::on_message() example ([@indiv0]) [c:bcb70e8]CurrentUser/User::static_avatar_url() methods to generate webp URLs
[c:c36841d]Colour struct ([@hsiW]) [c:2cb607d]4011 code (too many shards) ([@SunDwarf]) [c:93f3c60]Colour struct ([@bippum]) [c:345e140]User::default_avatar_url() [c:e85e901]Message::content_safe() to avoid @everyone/@heres ([@fwrs])
[c:e5a83dd]Member::distinct(), User::distinct() ([@fwrs]) [c:e5a83dd]User::avatar_url no longer mentions the user in the generated URL
[c:0708ccf]owners_only check now functions only if the author of a message
is an owner ([@fwrs]) [c:6355288]i64::MAX
seconds) [c:fafa363]before closure is now properly run when a message is sent by
the owner [c:760a47a]CurrentApplicationInfo now properly decodes due to flags no longer being
sent [c:2a743ce]Message::delete() permission check [c:4229034]command! macro signature as returning std::result::Result
[c:e9aae9c]User from rest::get_user -- not a CurrentUser [c:f57a187]Resumed event payload decoding [c:c2e8b69]CurrentApplicationInfo decoding without rpc_origins [c:38db32e]rest::execute_webhook be a POST [c:c050c59]format!("{}", UserId(7)) will format into "7" instead of "<@7>"
[c:933ee89]use_quotes for quote parsing to false (was true)
[c:38a484d]CreateEmbed builder now has direct image and thumbnail methods
instead of one-method builders [c:68c473d]u64 shard counts to allow using more than 255 shards (instead of
u8s) [c:ada07fa]Colour struct to be a tuplestruct [c:a8acd61]webhooks methods to get_webhooks
(eg: GuildChannel::webhooks() --> GuildChannel::get_webhooks())
[c:e8a9086]Guild::create_channel and related functions return a GuildChannel
[c:5918d01]Role's' Ord impl ([@emoticon]) [c:6a887b2]Shard::set_presence [c:5c40e85]serenity.rs to serenity ([@fwrs]) [c:3348178]Reaction::delete() [c:1594961]Arc/Message/RwLock clones [c:8c5ee70]This is a hotfix for applying a PR and fixing a major bug in the plain help command.
This is a hotfix for applying a PR and fixing a major bug in the plain help command.
Thanks to the following for contributions this release:
None.
Deprecate CreateEmbedImage::{height, width} and CreateEmbedThumbnail::{height, width}
This release focuses on revamping the framework, adding a large amount of configuration and overall features. v0.1.3 will be focused on performance optimizations and code cleanup.
Thanks to the following for contributions this release:
v0.1.2 can now be retrieved from the [crates.io listing].
When using EmbedBuilder::{image, thumbnail}, instead of calling another
builder, provide urls directly:
use serenity::model::Embed;
// old
Embed::fake(|e| e
.image(|i| i.url("https://not.zey.moe/me.png"))
.thumbnail(|t| t.url("https://not.zey.moe/me2.png")));
// new
Embed::fake(|e| e
.image("https://not.zey.moe/me.png")
.thumbnail("https://not.zey.moe/me2.png"));
From<Embed> for CreateEmbed [c:7914274]{Emoji,EmojiIdentifier}::url [c:ef6eba3]MessageBuilder ([@fwrs]) [c:13de5c2]CreateEmbedImage::{height, width} and
CreateEmbedThumbnail::{height, width}try!s have been converted to use ? syntax ([@acdenisSK])
[c:f69512b]v0.1.1 is a "features that v0.1.0 should have had" and "miscellaneous work" release. v0.1.2 will be focused on the framework, while v0.1.3 will be foc
v0.1.1 is a "features that v0.1.0 should have had" and "miscellaneous work" release. v0.1.2 will be focused on the framework, while v0.1.3 will be focused on performance optimizations.
Thanks to the following for contributions this release:
v0.1.1 can now be retrieved from the [crates.io listing].
When calling rest::get_guilds, instead of passing no parameters, pass a
GuildPagination variant and a limit:
use serenity::client::rest::{self, GuildPagination};
use serenity::model::GuildId;
// before
rest::get_guilds();
// after
rest::get_guilds(GuildPagination::After(GuildId(777)), 50);
Message::guild_id as a quick method for retrieving the Id of a message's
guild [c:bceb049]CurrentUser::guilds() to get the current user's guilds. Meant for use with
selfbots [c:57c060f]CurrentUser::edit() to edit the current user's profile settings [c:16d1b3c]User::distinct to format a string with the username#discriminator
combination ([@fwrs]) [c:31becb1]Member::colour to retrieve the member's colour ([@fwrs]) [c:43a5c5d]role1 < role2) for hierarchy [c:143337a]EditMember and EditProfile ([@Kiseii]) [c:e2557ac]Context.data's ShareMap. See
example 06 for an examplerest::start_integration_sync/Context::start_integration_sync now properly
work ([@abalabahaha]) [c:7f04179]Context::move_member's signature is now correct [c:4de39da]command! macro now publicly exports functions. This allows commands
created via this macro to be separated into different modules or crates
[c:62ed564]rest::get_guilds now supports pagination of guilds, as the output is now
limited to 100 [c:57c060f]Colour::dark_green is now sorted alphabetically ([@khazhyk]) [c:4a14b92]Colour::blitz_blue ([@Kiseii]) [c:daa24ec][0.12.5]: https://github.com/serenity-rs/serenity/compare/v0.12.4...v0.12.5 [0.12.4]: https://github.com/serenity-rs/serenity/compare/v0.12.3...v0.12.
Initial commit.
<!-- COMPARISONS -->
<!-- AUTHORS -->
<!-- COMMITS -->
Your coding agent can read these notes before it upgrades. Set up the MCP server →