github serenity-rs/serenity v0.4.0

latest releases: v0.12.1, v0.12.0, v0.12.0-rc2...
6 years ago

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
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:

Upgrade Path

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::channel
  • Cache::get_guild --> Cache::guild
  • Cache::get_guild_channel --> Cache::guild_channel
  • Cache::get_member --> Cache::member
  • Cache::get_private_channel --> Cache::private_channel
  • Cache::get_role --> Cache::role
  • Cache::get_user --> Cache::user
  • ChannelId::get_invites --> ChannelId::invites
  • ChannelId::get_message --> ChannelId::message
  • ChannelId::get_messages --> ChannelId::messages
  • ChannelId::get_reaction_users --> ChannelId::get_reaction_users
  • ChannelId::get_webhooks --> ChannelId::webhooks
  • Channel::get_message --> Channel::message
  • Channel::get_messages --> Channel::messages
  • Channel::get_reaction_users --> Channel::reaction_users
  • Client::login_bot --> Client::new
  • Client::login --> Client::new
  • Colour::get_b --> Colour::b
  • Colour::get_g --> Colour::g
  • Colour::get_r --> Colour::r
  • Colour::get_tuple --> Colour::tuple
  • CurrentUser::distinct --> CurrentUser::tag
  • Group::get_message --> Group::message
  • Group::get_messages --> Group::messages
  • Group::get_reaction_users --> Group::reaction_users
  • Guild::get_bans --> Guild::bans
  • Guild::get_channels --> Guild::channels
  • Guild::get_emoji --> Guild::emoji
  • Guild::get_emojis --> Guild::emojis
  • Guild::get_integrations --> Guild::integrations
  • Guild::get_invites --> Guild::invites
  • Guild::get_member --> Guild::member
  • Guild::get_members --> Guild::members
  • Guild::get_member_named --> Guild::member_named
  • Guild::get_prune_count --> Guild::prune_count
  • Guild::get_webhooks --> Guild::webhooks
  • GuildId::get_bans --> GuildId::bans
  • GuildId::get_channels --> GuildId::channels
  • GuildId::get_emoji --> GuildId::emoji
  • GuildId::get_emojis --> GuildId::emojis
  • GuildId::get_integrations --> GuildId::integrations
  • GuildId::get_invites --> GuildId::invites
  • GuildId::get_member --> GuildId::member
  • GuildId::get_members --> GuildId::members
  • GuildId::get_prune_count --> GuildId::prune_count
  • GuildId::get_webhooks --> GuildId::webhooks
  • Message::get_reaction_users --> Message::reaction_users
  • PartialGuild::get_bans --> PartialGuild::bans
  • PartialGuild::get_channels --> PartialGuild::channels
  • PartialGuild::get_emoji --> PartialGuild::emoji
  • PartialGuild::get_emojis --> PartialGuild::emojis
  • PartialGuild::get_integrations --> PartialGuild::integrations
  • PartialGuild::get_invites --> PartialGuild::invites
  • PartialGuild::get_member --> PartialGuild::member
  • PartialGuild::get_members --> PartialGuild::members
  • PartialGuild::get_prune_count --> PartialGuild::prune_count
  • PartialGuild::get_webhooks --> PartialGuild::webhooks
  • PrivateChannel::get_message --> PrivateChannel::message
  • PrivateChannel::get_messages --> PrivateChannel::messages
  • PrivateChannel::get_reaction_users --> PrivateChannel::reaction_users
  • Role::edit_role --> Role::edit
  • User::distinct --> User::tag

http::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_info
  • http::get_applications
  • http::get_emoji
  • http::get_emojis
  • model::Guild::emoji
  • model::Guild::emojis
  • model::GuildId::emoji
  • model::GuildId::emojis
  • model::PartialGuild::emoji
  • model::PartialGuild::emojis

Per 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]);

Added

Fixed

Changed

Misc.

Don't miss a new serenity release

NewReleases is sending notifications on new releases.