Serenity is a Rust library for the Discord API

Overview

ci-badge docs-badge guild-badge crates.io version rust 1.51.0+ badge

serenity

serenity logo

Serenity is a Rust library for the Discord API.

View the examples on how to make and structure a bot.

Serenity supports bot login via the use of Client::builder.

You may also check your tokens prior to login via the use of validate_token.

Once logged in, you may add handlers to your client to dispatch Events, by implementing the handlers in a trait, such as EventHandler::message. This will cause your handler to be called when a Event::MessageCreate is received. Each handler is given a Context, giving information about the event. See the client's module-level documentation.

The Shard is transparently handled by the library, removing unnecessary complexity. Sharded connections are automatically handled for you. See the gateway's documentation for more information.

A Cache is also provided for you. This will be updated automatically for you as data is received from the Discord API via events. When calling a method on a Context, the cache will first be searched for relevant data to avoid unnecessary HTTP requests to the Discord API. For more information, see the cache's module-level documentation.

Note that - although this documentation will try to be as up-to-date and accurate as possible - Discord hosts official documentation. If you need to be sure that some information piece is accurate, refer to their docs.

Example Bot

A basic ping-pong bot looks like:

CommandResult { msg.reply(ctx, "Pong!").await?; Ok(()) }">
use serenity::async_trait;
use serenity::client::{Client, Context, EventHandler};
use serenity::model::channel::Message;
use serenity::framework::standard::{
    StandardFramework,
    CommandResult,
    macros::{
        command,
        group
    }
};

use std::env;

#[group]
#[commands(ping)]
struct General;

struct Handler;

#[async_trait]
impl EventHandler for Handler {}

#[tokio::main]
async fn main() {
    let framework = StandardFramework::new()
        .configure(|c| c.prefix("~")) // set the bot's prefix to "~"
        .group(&GENERAL_GROUP);

    // Login with a bot token from the environment
    let token = env::var("DISCORD_TOKEN").expect("token");
    let mut client = Client::builder(token)
        .event_handler(Handler)
        .framework(framework)
        .await
        .expect("Error creating client");

    // start listening for events by starting a single shard
    if let Err(why) = client.start().await {
        println!("An error occurred while running the client: {:?}", why);
    }
}

#[command]
async fn ping(ctx: &Context, msg: &Message) -> CommandResult {
    msg.reply(ctx, "Pong!").await?;

    Ok(())
}

Full Examples

Full examples, detailing and explaining usage of the basic functionality of the library, can be found in the examples directory.

Installation

Add the following to your Cargo.toml file:

[dependencies]
serenity = "0.10"

Serenity supports a minimum of Rust 1.51.

Features

Features can be enabled or disabled by configuring the library through Cargo.toml:

[dependencies.serenity]
default-features = false
features = ["pick", "your", "feature", "names", "here"]
version = "0.10"

The default features are: builder, cache, client, framework, gateway, http, model, standard_framework, utils, and rustls_backend.

There are these alternative default features, they require to set default-features = false:

  • default_tokio_0_2: Uses the default backend with tokio version 0.2.
  • default_native_tls: Uses native_tls_backend instead of the default rustls_backend.
  • default_native_tls_tokio_0_2: Uses native_tls_backend with tokio version 0.2.
  • default_no_backend: Excludes the default backend, pick your own backend instead.

If you are unsure which to pick, use the default features by not setting default-features = false.

The following is a full list of features:

  • builder: The builders used in conjunction with models' methods.
  • cache: The cache will store information about guilds, channels, users, and other data, to avoid performing REST requests. If you are low on RAM, do not enable this.
  • collector: A collector awaits events, such as receiving a message from a user or reactions on a message, and allows for responding to the events in a convenient fashion. Collectors can be configured to enforce certain critera the events must meet.
  • client: A manager for shards and event handlers, abstracting away the work of handling shard events and updating the cache, if enabled.
  • framework: Enables the framework, which is a utility to allow simple command parsing, before/after command execution, prefix setting, and more.
  • gateway: A Shard, used as a higher-level interface for communicating with the Discord gateway over a WebSocket client.
  • http: Functions providing a wrapper over Discord's REST API at a low enough level that optional parameters can be provided at will via a JsonMap.
  • model: Method implementations for models, acting as helper methods over the HTTP functions.
  • standard_framework: A standard, default implementation of the Framework
  • utils: Utility functions for common use cases by users.
  • voice: Enables registering a voice plugin to the client, which will handle actual voice connections from Discord. lavalink-rs or Songbird are recommended voice plugins.
  • default_native_tls: Default features but using native_tls_backend instead of rustls_backend.
  • absolute_ratelimits: Whether the library should use your system clock to avoid ratelimits, or use the interval given by Discord that might be less efficient due to latency in the network. If you turn this feature on, it is recommended to synchronise your clock with an NTP server (such as Google's).
  • unstable_discord_api: Enables features of the Discord API that do not have a stable interface. The features might not have official documentation or are subject to change.

Serenity offers two TLS-backends, rustls_backend by default, you need to pick one if you do not use the default features:

  • rustls_backend: Uses Rustls for all platforms, a pure Rust TLS implementation.
  • native_tls_backend: Uses SChannel on Windows, Secure Transport on macOS, and OpenSSL on other platforms.

If you need to use tokio version 0.2 use the backends below:

  • rustls_tokio_0_2_backend: Combines rustls_backend with tokio version 0.2.
  • native_tls_tokio_0_2_backend: Combines native_tls_backend with tokio version 0.2.

If you want all of the default features except for cache for example, you can list all but that:

[dependencies.serenity]
default-features = false
features = [
    "builder",
    "client",
    "framework",
    "gateway",
    "http",
    "model",
    "standard_framework",
    "utils",
    "rustls_backend",
]
version = "0.10"

Dependencies

If you use the native_tls_backend and you are not developing on macOS or Windows, you will need:

  • openssl

Projects extending Serenity

  • lavalink-rs: An interface to Lavalink, an audio sending node based on Lavaplayer
  • Songbird: An async Rust library for the Discord voice API.
  • Poise: Experimental command framework, with advanced features like edit tracking, single function slash and prefix commands and flexible argument parsing.
Comments
  • Serenity.await (continued)

    Serenity.await (continued)

    The author of the Serenity.await PR has been absent for months, with no words from them at all. It is also in a bad shape in terms of its mergebility. It contains several merge conflicts and hasn't been updated to the latest state of the next branch.

    This PR eliminates these issues, and until a response is received from the author, the development of asyncifying Serenity will go forward here.

    In order to update the previous PR, I had to manually recommit all of the changes present in it. This was a painful process, but the changes should be basically the same between the PRs. I introduced improvements myself in a few places while I was rummaging through the previous PR. Also to note, while the commits are under my name, it is actually @Lakelezz and her efforts who made the port to async. This PR is to continue the efforts and prepare it for being merged into the repository.

    The problem of OOMs has not been fixed yet. It is still misunderstood where the root of the problem is, and occurs (and doesn't occur) in people's bots differently.

    Use this PR by putting the url of my repository and branch in your Cargo.toml:

    [dependencies.serenity]
    git = "https://github.com/acdenisSK/serenity"
    branch = "await_next"
    
    enhancement docs help wanted framework voice model client builder cache http utils gateway breaking change command_attr dependencies examples 
    opened by acdenisSK 25
  • Refactor http module

    Refactor http module

    This PR contains 5 small refactor commits, but the bulk of this PR is the final commit (7628216860688c8829d3d516a85e60b5ab2a277d), which changes the required code for each Http method from

    impl Http {
        pub async fn add_member_role(
            &self,
            guild_id: GuildId,
            user_id: UserId,
            role_id: RoleId,
            audit_log_reason: Option<&str>,
        ) -> Result<()> {
            self.wind(204, Request {
                body: None,
                multipart: None,
                headers: audit_log_reason.map(reason_into_header),
                route: RouteInfo::AddMemberRole {
                    guild_id,
                    role_id,
                    user_id,
                },
            })
            .await
        }
    
        // ...
    }
    
    impl Route {
        pub fn guild_member_role(guild_id: GuildId, user_id: UserId, role_id: RoleId) -> String {
            api!("/guilds/{}/members/{}/roles/{}", guild_id, user_id, role_id)
        }
    
        // ...
    }
    
    pub enum RouteInfo {
        AddMemberRole {
            guild_id: GuildId,
            role_id: RoleId,
            user_id: UserId,
        },
        // ...
    }
    
    impl RouteInfo {
        pub fn deconstruct(self) -> (LightMethod, Route, Cow<'static, str>) {
            match self {
                RouteInfo::AddMemberRole {
                    guild_id,
                    role_id,
                    user_id,
                } => (
                    LightMethod::Put,
                    Route::GuildsIdMembersIdRolesId(guild_id),
                    Cow::from(Route::guild_member_role(guild_id, user_id, role_id)),
                ),
                // ...
            }
        }
    }
    

    to

    impl Http {
        pub async fn add_member_role(
            &self,
            guild_id: GuildId,
            user_id: UserId,
            role_id: RoleId,
            audit_log_reason: Option<&str>,
        ) -> Result<()> {
            self.wind(204, Request {
                body: None,
                multipart: None,
                headers: audit_log_reason.map(reason_into_header),
                method: LightMethod::Put,
                bucket: RatelimitBucket::GuildsIdMembersIdRolesId(guild_id),
                path: api!(self, "/guilds/{}/members/{}/roles/{}", guild_id, user_id, role_id),
            })
            .await
        }
        // ...
    }
    
    model client http examples 
    opened by kangalioo 22
  • Voice Rework -- Events, Track Queues

    Voice Rework -- Events, Track Queues

    Following on from #633, this implements a proof-of-concept for an improved audio frontend. The largest change is the introduction of events and event handling: both by time elapsed and by track events, such as ending or looping. Following on from this, the library now includes a basic, event-driven track queue system (which people seem to ask for unusually often). A new sample, examples/13_voice_events, demonstrates both the TrackQueue system and some basic events via the ~queue and ~play_fade commands.

    Locks are removed from around the control of Audio objects, which should allow the backend to be moved to a more granular futures-based backend solution in a cleaner way. There are more issues I would like to tackle before merging:

    User-facing tasks:

    • [x] Global track/time events.
    • [x] Seekable/loopable audio streams.
    • [x] In-memory buffering (compressed/uncompressed) of streams.
    • [x] Audio input metadata discovery/use.
    • [x] Migrate audio control/query functions to async.
    • [x] Move to subcrate.
    • [x] Twilight support.
    • [x] (Provably) survive rebalances.

    Backend tasks:

    • [x] Rework RTP parsing (since packet decoding appears to have somehow broken down when there are multiple senders). I'm currently writing a library based on pnet.
    • [x] Voice gateway version 4 support.
    • [x] Rework input system for audio tracks.
    • [x] Rework container/decoding system for audio tracks.
    • [x] Separate tasks (audio mixing, collection, event handling, network) out from single thread.
    • [x] Async conversion of above tasks.

    Primarily, I'm looking for feedback on the user-facing API. Audio state queries moving to what is an essentially async API is a large semantic change -- while I'm convinced it's for the better (and will prevent people from hitting audio glitches, and lock contention due to constantly checking state), it's not what people are used to. This could probably be made sync-ish by having the audio threads update a shared AudioState which the handles have a reference to, if need be.

    enhancement voice breaking change 
    opened by FelixMcFelix 22
  • send_message creating 403 responses

    send_message creating 403 responses

    Using message.channel_id.send_message() creates a 403 forbidden response from discord, but making a direct http request to https://discordapp.com/api/channels/123/messages myself works fine. The bot connects and receives messages fine so it's not something obvious like providing the wrong token or something. Just when replying to messages I need to construct a manual http request.

    The main difference I see right now is that I'm setting my Authorization header to Authorization: Bot REDUCTED and I think serenity is setting it to just Authorization: REDUCTED? In request.rs I see headers.set(Authorization(TOKEN.lock().clone()));

    possible bug 
    opened by thepixelmonk 22
  • Serenity.await

    Serenity.await

    This pull request rewrites Serenity to be asynchronous.

    As highly demanded (#729), Serenity is finally async. For a long time, it was nothing but a dream, but now it's reality.

    There are still a few things following in this PR, but it's ready to be used, see example 5.

    Missing bits:

    • [x] voice-module;
    • [x] voice-examples (6, 10);
    • [x] scheduling/eventing example (12);
    • [x] updating all docs, doc-tests, and code examples in other files;
    • [x] native_tls_backend;
    • [ ] final code refactoring;

    To fix:

    • [x] Serenity becomes unresponsive, no shard activity, goes offline;

    Also, collectors (as mentioned in #786) were added too.

    You can test it already!

    enhancement docs help wanted framework voice model client builder cache http utils gateway breaking change command_attr dependencies examples 
    opened by Lakelezz 20
  • Unable to compile sodiumoxide v 0.1.0 on debian-9

    Unable to compile sodiumoxide v 0.1.0 on debian-9

    I have clang-9.0 installed on debian stretch and am running into this issue:

    clang --version
    clang version 9.0.0-svn354826-1~exp1+0~20190225221945.1090~1.gbpd90386 (trunk)
    Target: x86_64-pc-linux-gnu
    Thread model: posix
    InstalledDir: /usr/bin
    
    Compiling sodiumoxide v0.1.0
    error[E0432]: unresolved imports `ffi::crypto_stream_xchacha20`, `ffi::crypto_stream_xchacha20_xor`, `ffi::crypto_stream_xchacha20_xor_ic`, `ffi::crypto_stream_xchacha20_KEYBYTES`, `ffi::crypto_stream_xchacha20_NONCEBYTES`
     --> /home/epicblood/.cargo/registry/src/github.com-1ecc6299db9ec823/sodiumoxide-0.1.0/src/crypto/stream/xchacha20.rs:5:11
      |
    5 | use ffi::{crypto_stream_xchacha20,
      |           ^^^^^^^^^^^^^^^^^^^^^^^ no `crypto_stream_xchacha20` in the root. Did you mean to use `crypto_stream_chacha20`?
    6 |           crypto_stream_xchacha20_xor,
      |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `crypto_stream_xchacha20_xor` in the root. Did you mean to use `crypto_stream_chacha20_xor`?
    7 |           crypto_stream_xchacha20_xor_ic,
      |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `crypto_stream_xchacha20_xor_ic` in the root. Did you mean to use `crypto_stream_chacha20_xor_ic`?
    8 |           crypto_stream_xchacha20_KEYBYTES,
      |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `crypto_stream_xchacha20_KEYBYTES` in the root. Did you mean to use `crypto_stream_chacha20_KEYBYTES`?
    9 |           crypto_stream_xchacha20_NONCEBYTES};
      |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `crypto_stream_xchacha20_NONCEBYTES` in the root. Did you mean to use `crypto_stream_chacha20_NONCEBYTES`?
    
    error[E0425]: cannot find value `crypto_kx_PUBLICKEYBYTES` in module `ffi`
     --> /home/epicblood/.cargo/registry/src/github.com-1ecc6299db9ec823/sodiumoxide-0.1.0/src/crypto/kx/x25519blake2b.rs:6:40
      |
    6 | pub const PUBLICKEYBYTES: usize = ffi::crypto_kx_PUBLICKEYBYTES as usize;
      |                                        ^^^^^^^^^^^^^^^^^^^^^^^^ did you mean `crypto_box_PUBLICKEYBYTES`?
    
    error[E0425]: cannot find value `crypto_kx_SECRETKEYBYTES` in module `ffi`
     --> /home/epicblood/.cargo/registry/src/github.com-1ecc6299db9ec823/sodiumoxide-0.1.0/src/crypto/kx/x25519blake2b.rs:9:40
      |
    9 | pub const SECRETKEYBYTES: usize = ffi::crypto_kx_SECRETKEYBYTES as usize;
      |                                        ^^^^^^^^^^^^^^^^^^^^^^^^ did you mean `crypto_box_SECRETKEYBYTES`?
    
    error[E0425]: cannot find value `crypto_kx_SEEDBYTES` in module `ffi`
      --> /home/epicblood/.cargo/registry/src/github.com-1ecc6299db9ec823/sodiumoxide-0.1.0/src/crypto/kx/x25519blake2b.rs:12:35
       |
    12 | pub const SEEDBYTES: usize = ffi::crypto_kx_SEEDBYTES as usize;
       |                                   ^^^^^^^^^^^^^^^^^^^ did you mean `crypto_box_SEEDBYTES`?
    
    error[E0425]: cannot find value `crypto_kx_SESSIONKEYBYTES` in module `ffi`
      --> /home/epicblood/.cargo/registry/src/github.com-1ecc6299db9ec823/sodiumoxide-0.1.0/src/crypto/kx/x25519blake2b.rs:15:41
       |
    15 | pub const SESSIONKEYBYTES: usize = ffi::crypto_kx_SESSIONKEYBYTES as usize;
       |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^ did you mean `crypto_box_SECRETKEYBYTES`?
    
    error[E0425]: cannot find function `crypto_kx_keypair` in module `ffi`
      --> /home/epicblood/.cargo/registry/src/github.com-1ecc6299db9ec823/sodiumoxide-0.1.0/src/crypto/kx/x25519blake2b.rs:55:14
       |
    55 |         ffi::crypto_kx_keypair(pk.0.as_mut_ptr(), sk.0.as_mut_ptr());
       |              ^^^^^^^^^^^^^^^^^ did you mean `crypto_box_keypair`?
    
    error[E0425]: cannot find function `crypto_kx_seed_keypair` in module `ffi`
      --> /home/epicblood/.cargo/registry/src/github.com-1ecc6299db9ec823/sodiumoxide-0.1.0/src/crypto/kx/x25519blake2b.rs:66:14
       |
    66 |         ffi::crypto_kx_seed_keypair(pk.0.as_mut_ptr(), sk.0.as_mut_ptr(), seed.0.as_ptr());
       |              ^^^^^^^^^^^^^^^^^^^^^^ did you mean `crypto_box_seed_keypair`?
    
    error[E0425]: cannot find function `crypto_kx_server_session_keys` in module `ffi`
      --> /home/epicblood/.cargo/registry/src/github.com-1ecc6299db9ec823/sodiumoxide-0.1.0/src/crypto/kx/x25519blake2b.rs:84:18
       |
    84 |             ffi::crypto_kx_server_session_keys(
       |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in `ffi`
    
    error[E0425]: cannot find function `crypto_kx_client_session_keys` in module `ffi`
       --> /home/epicblood/.cargo/registry/src/github.com-1ecc6299db9ec823/sodiumoxide-0.1.0/src/crypto/kx/x25519blake2b.rs:112:18
        |
    112 |             ffi::crypto_kx_client_session_keys(
        |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in `ffi`
    
    error[E0080]: evaluation of constant value failed
      --> /home/epicblood/.cargo/registry/src/github.com-1ecc6299db9ec823/sodiumoxide-0.1.0/src/crypto/stream/stream_macros.rs:27:17
       |
    27 |       nonce Nonce(NONCEBYTES);
       |                   ^^^^^^^^^^ referenced constant has errors
       | 
      ::: /home/epicblood/.cargo/registry/src/github.com-1ecc6299db9ec823/sodiumoxide-0.1.0/src/crypto/stream/xchacha20.rs:11:1
       |
    11 | / stream_module!(crypto_stream_xchacha20,
    12 | |                crypto_stream_xchacha20_xor,
    13 | |                crypto_stream_xchacha20_xor_ic,
    14 | |                crypto_stream_xchacha20_KEYBYTES,
    15 | |                crypto_stream_xchacha20_NONCEBYTES);
       | |___________________________________________________- in this macro invocation
    
    error[E0080]: evaluation of constant value failed
      --> /home/epicblood/.cargo/registry/src/github.com-1ecc6299db9ec823/sodiumoxide-0.1.0/src/crypto/kx/x25519blake2b.rs:19:22
       |
    19 |     public PublicKey(PUBLICKEYBYTES);
       |                      ^^^^^^^^^^^^^^ referenced constant has errors
    
    error: aborting due to 11 previous errors
    
    Some errors occurred: E0080, E0425, E0432.
    For more information about an error, try `rustc --explain E0080`.
    error: Could not compile `sodiumoxide`.
    warning: build failed, waiting for other jobs to finish...
    error: build failed
    
    Process finished with exit code 101
    

    I have just installed rust-lang, so I (should) have the latest version of all the tools, I also have libsodium-dev installed from the debian repo. I have successfully built sodiumoxide v0.2, from their github

    I made an issue here but it seems v0.1.0 is no longer supported

    bug 
    opened by JorisBolsens 13
  • Mutexes and RwLocks being used where concurrent datastructures will work better

    Mutexes and RwLocks being used where concurrent datastructures will work better

    As it currently stands the Mutex/RwLock pattern is used a lot particularly with the cache. In large scale highly concurrent scenarios concurrent datastructures like chashmap and transactional memory rbtrees should do better.

    enhancement feature-request 
    opened by xacrimon 13
  • Expected Args.single_quoted behaviour

    Expected Args.single_quoted behaviour

    From the documentation of Args.single_quoted it looked like it would handle grabbing first argument from a command like !command "first argument" second, but it ends up grabbing first.

    single_quoted is passing the first element of delimiter_split to parse_quotes, and since the delimiter is " ", by the time single_quoted gets to look at anything, all it has to work with is "first.

    What is the expected usage, and behavior of Args.single_quoted?

    question 
    opened by jhelwig 13
  • Remove redundant builders and add Discord docs

    Remove redundant builders and add Discord docs

    Some of the builders were representations of the exact same Discord types as model types, so I deduplicated them

    And I added Discord docs links to the builders and some model types

    model builder examples 
    opened by kangalioo 11
  • Rewrite the lib in Go - Attempt 2

    Rewrite the lib in Go - Attempt 2

    Please re-evaluate https://github.com/serenity-rs/serenity/issues/524 as GOLANG now added generics. Also Denis is asleep, we may get this accepted before he wakes up!

    No more lifetimes, only go(od) times!

    serenity.go already has such a positive vibe :)

    enhancement fix help wanted feature-request 
    opened by Lakelezz 11
  • Initial implementation for inline replies

    Initial implementation for inline replies

    Initial implementation for https://github.com/discord/discord-api-docs/pull/2118

    I also added in the support for v8, which will need to be uncommented when that gets implemented. Do you guys keep track of a v8 TODO list somewhere?

    Full disclaimer though, I have no idea if this works as it is untested vs the Discord API (~~they haven't implemented this yet, so don't merge until they have~~).

    enhancement discord feature model 
    opened by ikkerens 11
  • Race condition when `SUPPRESS_EMBEDS` is set when editing a message

    Race condition when `SUPPRESS_EMBEDS` is set when editing a message

    Discord does not cancel their async task when they receive a request to edit a message with the flag SUPPRESS_EMBEDS. So when a message is sent and the flag is set when sending the message edit request right after that, Discord will still display the embed.

    For that reason, Serenity should queue a task to edit the message after MESSAGE_UPDATE event is fired to fix this race condition. A certain timeout should be considered as well which Discord does not document.

    If this is too abstract for Serenity, this race condition should be documented in the inline docs.

    opened by oSumAtrIX 0
  • Add owner_id for group dms, threads and forum posts

    Add owner_id for group dms, threads and forum posts

    Allows retrieving the creator/owner of a group dm or thread. In code it just adds the owner_id (Option) field for deserialization upon to_channel invocation.

    model 
    opened by Web-44 0
  • support for task loops

    support for task loops

    Is there any way to run a task on a loop for example this python snippet changes the status to online and sends a message.

    import discord,asyncio,os
    from discord.ext import commands, tasks
    
    
    token = 'xxx'
    bot = commands.Bot(command_prefix='.')
    
    @bot.event
    async  def on_ready():
        change_status.start()
        print('bot in active')
    
    @tasks.loop(seconds=30)
    async def change_status():
        channel = bot.get_channel(ch_id)
        await bot.change_presence(activity=discord.Game('online'))
        await bot.channel.send('here')
    bot.run(token)
    

    looked in the source code and the docs, couldn't find any thing related.

    opened by MrJico 0
  • `CreateButton` builder should have `custom_id` method

    `CreateButton` builder should have `custom_id` method

    CreateSelectMenu has a method to change the custom_id of the menu. This is easy on this type since there is already a field custom_id on this struct.

    It would be good to have this behaviour on CreateButton as well. The problem here is that the type is defined as:

    pub struct CreateButton(Button);
    

    where Button doesn't contain a custom_id directly, but as part of its data field of type ButtonKind, as long as its ButtonKind::NonLink instead of ButtonKind::Link.

    On CreateButton, this method could set the custom_id:

    pub fn custom_id(mut self, id: impl Into<String>) -> Self {
        // Make sure we're not a link button
        if let ButtonKind::NonLink {
            custom_id, ..
        } = &mut self.0.data
        {
            *custom_id = id.into();
        }
        self
    }
    

    However, it isn't great for rejecting a new id in the case that ButtonKind::Link is the kind.

    opened by AngelOnFira 0
  • Implement `Deserialize` on all builder types

    Implement `Deserialize` on all builder types

    As I've been looking through types in the builder on the next branch, it seems that many are Serialize, but few are Deserialize. I'm hoping to have both traits implemented, as so I can store builders in my database to be used later. For example:

    /// A builder for creating a [`SelectMenu`].
    ///
    /// [`SelectMenu`]: crate::model::application::SelectMenu
    #[derive(Clone, Debug, Serialize)]
    #[must_use]
    pub struct CreateSelectMenu {
      ...
    }
    

    I'm curious about what complications lie in just adding Deserialize? (Other than having to do it on any sub types).

    opened by AngelOnFira 2
Releases(v0.11.5)
Owner
serenity
A Rust library for Discord.
serenity
🦜 A hassle-free, highly performant, host it yourself Discord music bot built with Serenity in Rust. Powered by youtube-dl and Genius.

?? A hassle-free, highly performant and fast evolving Discord music bot built with Serenity in Rust. Deployment Usage Just create a bot account, copy

Miguel Mano 82 Dec 14, 2022
This is a Discord bot written in Rust to translate to and from the Bottom Encoding Standard using bottom-rs and Serenity.

bottom-bot This is a Discord bot written in Rust to translate to and from the Bottom Encoding Standard using bottom-rs and Serenity. Ever had this pro

Bottom Software Foundation 11 Dec 10, 2022
An experimental Discord bot using Serenity.

VoidBot An experimental Discord bot using Serenity. Environment Variables Can be set with a .env file. DISCORD_TOKEN: The token for your bot. (require

null 1 May 21, 2022
A library for creating/parsing Serenity slash commands.

Serenity Commands A library for creating/parsing Serenity slash commands. Usage See the examples directory for more examples. use serenity::all::{

Vidhan Bhatt 4 Dec 9, 2023
Chains - a bot written in Rust using the serenity crate

Chains (Rusty) Chains is a bot written in Rust using the serenity crate. Chains primarily focuses on easy to set up, easy to use moderation tools such

Quin 3 Mar 28, 2022
A repository full of manually generated hand curated JSON files, which contain the API Types that the Discord API returns.

Discord API Types A repository full of manually generated hand curated JSON files, which contain the API Types that the Discord API returns. Also did

Unofficial Discord Documentation 1 Sep 16, 2022
A Discord bot focused on addressing the inherent problems with Discord, to allow a more socialist/anarchist organization of servers.

ACABot A Discord bot focused on addressing the inherent problems with Discord, to allow a more socialist/anarchist organization of servers (or "guilds

null 4 May 3, 2022
A Discord bot for sending GeoGuessr challenge links that uses the GeoGuessr API written in rust.

GeoGuessr-bot-rs This is a simple implementation of a discord bot that send GeoGuessr-challenge links on demand. Features: Slash-commands Lightning-fa

Luukas Pörtfors 6 Nov 18, 2022
A high-level Rust crate around the Discord API, aimed to be easy and straight-forward to use.

rs-cord A high-level Rust crate around the Discord API, aimed to be easy and straight-forward to use. Documentation • Crates.io • Discord Navigation M

Jay3332 4 Sep 24, 2022
A minimal discord api wrapper.

descord Descord is a discord api wrapper. Example use descord::prelude::*; #[tokio::main] async fn main() { let mut client = Client::new(

null 12 May 6, 2024
Modrinth API is a simple library for using, you guessed it, the Modrinth API in Rust projects

Modrinth API is a simple library for using, you guessed it, the Modrinth API in Rust projects. It uses reqwest as its HTTP(S) client and deserialises responses to typed structs using serde.

null 21 Jan 1, 2023
A rust library for interacting with multiple Discord.com-compatible APIs and Gateways at the same time.

Chorus A rust library for interacting with (multiple) Spacebar-compatible APIs and Gateways (at the same time). Explore the docs » Report Bug · Reques

polyphony 4 Apr 30, 2023
A webhook-based Discord slash command library

Slashook A webhook-based Discord slash command library. This is a WIP project. Please note breaking changes can occur within minor releases until vers

Tonkku 11 Oct 18, 2022
Edgelord is a library for Cloudflare Workers. You can scaffold a basic bot for discord, slack, etc.

Edge Computing + chūnibyō = Edgelord ✨ ?? Edgelord Edgelord is now working. You can contribute for it. Edgelord is a Rust library for cloudflare worke

null 23 Dec 26, 2022
API wrapper for the tankerkönig api

tankerkoenig-rs API wrapper for the tankerkoenig-api written in rust. Gives you ready deserialized structs and a easy to use and strictly typed api. I

Jonathan 2 Feb 27, 2022
A discord bot that safely executes whatever rust you throw at it. Remote code execution as a service

RustBot Bot is still under development and not ready for production use RustBot is a discord bot that executes whatever rust code you throw at it. In

Conner Bradley 7 Jan 3, 2022
A little command-line script written in Rust to interface with Discord webhooks.

Rust Discord Webhook Agent This is a little "script" I wrote for practice with Rust and asynchronous operations within Rust. Getting started Clone thi

David Chen 2 Sep 7, 2022
A pure-Rust serverless discord chatbot hosted on Cloudflare Workers.

About A pure-Rust serverless discord chatbot hosted on Cloudflare Workers. With a free account you have up to 100k requests per day. For storing state

Mike Dallas 31 Nov 21, 2022
A multipurpose (including music) Discord bot written in Rust

filloabot-rs A multipurpose (including music) Discord bot. This is a full rewrite using Rust of the original FilloaBot. Some features that were consid

FilloaBot 2 Oct 21, 2022