Struct serenity::client::Client
[−]
[src]
pub struct Client<H: EventHandler + Send + Sync + 'static> { pub data: Arc<Mutex<ShareMap>>, pub shard_runners: Arc<Mutex<HashMap<ShardId, ShardRunnerInfo>>>, pub threadpool: ThreadPool, // some fields omitted }
The Client is the way to be able to start sending authenticated requests
over the REST API, as well as initializing a WebSocket connection through
Shard
s. Refer to the documentation on using sharding
for more information.
Event Handlers
Event handlers can be configured. For example, the event handler
[EventHandler::on_message
] will be dispatched to whenever a Event::MessageCreate
is
received over the connection.
Note that you do not need to manually handle events, as they are handled internally and then dispatched to your event handlers.
Examples
Creating a Client instance and adding a handler on every message receive, acting as a "ping-pong" bot is simple:
use serenity::prelude::*; use serenity::model::*; struct Handler; impl EventHandler for Handler { fn on_message(&self, _: Context, msg: Message) { if msg.content == "!ping" { let _ = msg.channel_id.say("Pong!"); } } } let mut client = Client::new("my token here", Handler); client.start();
Fields
data: Arc<Mutex<ShareMap>>
A ShareMap which requires types to be Send + Sync. This is a map that can be safely shared across contexts.
The purpose of the data field is to be accessible and persistent across contexts; that is, data can be modified by one context, and will persist through the future and be accessible through other contexts. This is useful for anything that should "live" through the program: counters, database connections, custom user caches, etc.
In the meaning of a context, this data can be accessed through
Context::data
.
Examples
Create a MessageEventCounter
to track the following events:
extern crate serenity; extern crate typemap; use serenity::prelude::*; use serenity::model::*; use std::collections::HashMap; use std::env; use typemap::Key; struct MessageEventCounter; impl Key for MessageEventCounter { type Value = HashMap<String, u64>; } macro_rules! reg { ($ctx:ident $name:expr) => { { let mut data = $ctx.data.lock(); let counter = data.get_mut::<MessageEventCounter>().unwrap(); let entry = counter.entry($name).or_insert(0); *entry += 1; } }; } struct Handler; impl EventHandler for Handler { fn on_message(&self, ctx: Context, _: Message) { reg!(ctx "MessageCreate") } fn on_message_delete(&self, ctx: Context, _: ChannelId, _: MessageId) { reg!(ctx "MessageDelete") } fn on_message_delete_bulk(&self, ctx: Context, _: ChannelId, _: Vec<MessageId>) { reg!(ctx "MessageDeleteBulk") } fn on_message_update(&self, ctx: Context, _: ChannelId, _: MessageId) { reg!(ctx "MessageUpdate") } } let mut client = Client::new(&env::var("DISCORD_TOKEN").unwrap(), Handler); { let mut data = client.data.lock(); data.insert::<MessageEventCounter>(HashMap::default()); } client.start().unwrap();
Refer to example 05 for an example on using the data
field.
A HashMap of all shards instantiated by the Client.
The key is the shard ID and the value is the shard itself.
Examples
If you call client.start_shard(3, 5)
, this
HashMap will only ever contain a single key of 3
, as that's the only
Shard the client is responsible for.
If you call client.start_shards(10)
, this
HashMap will contain keys 0 through 9, one for each shard handled by the
client.
Printing the number of shards currently instantiated by the client every 5 seconds:
struct Handler; impl EventHandler for Handler { } let mut client = Client::new(&env::var("DISCORD_TOKEN")?, Handler); let shard_runners = client.shard_runners.clone(); thread::spawn(move || { loop { println!("Shard count instantiated: {}", shard_runners.lock().len()); thread::sleep(Duration::from_millis(5000)); } });
threadpool: ThreadPool
The threadpool shared by all shards.
Defaults to 5 threads, which should suffice small bots. Consider increasing this number as your bot grows.
Methods
impl<H: EventHandler + Send + Sync + 'static> Client<H>
[src]
fn new(token: &str, handler: H) -> Self
[src]
Creates a Client for a bot user.
Discord has a requirement of prefixing bot tokens with "Bot "
, which
this function will automatically do for you if not already included.
Examples
Create a Client, using a token from an environment variable:
struct Handler; impl EventHandler for Handler {} use serenity::Client; use std::env; let token = env::var("DISCORD_TOKEN")?; let client = Client::new(&token, Handler);
fn with_framework<F: Framework + Send + 'static>(&mut self, f: F)
[src]
Sets a framework to be used with the client. All message events will be
passed through the framework after being passed to the on_message
event handler.
See the framework module-level documentation for more information on usage.
Examples
Create a simple framework that responds to a ~ping
command:
use serenity::framework::StandardFramework; struct Handler; impl EventHandler for Handler {} use serenity::Client; use std::env; let mut client = Client::new(&env::var("DISCORD_TOKEN")?, Handler); client.with_framework(StandardFramework::new() .configure(|c| c.prefix("~")) .command("ping", |c| c.exec_str("Pong!")));
Using your own framework:
use serenity::Framework; use serenity::client::Context; use serenity::model::*; use tokio_core::reactor::Handle; use std::collections::HashMap; struct MyFramework { commands: HashMap<String, Box<Fn(Message, Vec<String>)>>, } impl Framework for MyFramework { fn dispatch(&mut self, _: Context, msg: Message, tokio_handle: &Handle) { let args = msg.content.split_whitespace(); let command = match args.next() { Some(command) => { if !command.starts_with('*') { return; } command }, None => return, }; let command = match self.commands.get(&command) { Some(command) => command, None => return, }; tokio_handle.spawn_fn(move || { (command)(msg, args); Ok() }); } } struct Handler; impl EventHandler for Handler {} use serenity::Client; use std::env; let mut client = Client::new(&env::var("DISCORD_TOKEN")?, Handler); client.with_framework(MyFramework { commands: { let mut map = HashMap::new(); map.insert("ping".to_string(), Box::new(|msg, _| msg.channel_id.say("pong!"))); map }});
Refer to the documentation for the framework
module for more in-depth
information.
fn start(&mut self) -> Result<()>
[src]
Establish the connection and start listening for events.
This will start receiving events in a loop and start dispatching the events to your registered handlers.
Note that this should be used only for users and for bots which are in less than 2500 guilds. If you have a reason for sharding and/or are in more than 2500 guilds, use one of these depending on your use case:
Refer to the Gateway documentation for more information on effectively using sharding.
Examples
Starting a Client with only 1 shard, out of 1 total:
struct Handler; impl EventHandler for Handler {} use serenity::client::Client; use std::env; let mut client = Client::new(&env::var("DISCORD_TOKEN")?, Handler); if let Err(why) = client.start() { println!("Err with client: {:?}", why); }
fn start_autosharded(&mut self) -> Result<()>
[src]
Establish the connection(s) and start listening for events.
This will start receiving events in a loop and start dispatching the events to your registered handlers.
This will retrieve an automatically determined number of shards to use from the API - determined by Discord - and then open a number of shards equivalent to that amount.
Refer to the Gateway documentation for more information on effectively using sharding.
Examples
Start as many shards as needed using autosharding:
struct Handler; impl EventHandler for Handler {} use serenity::client::Client; use std::env; let mut client = Client::new(&env::var("DISCORD_TOKEN")?, Handler); if let Err(why) = client.start_autosharded() { println!("Err with client: {:?}", why); }
Errors
Returns a ClientError::Shutdown
when all shards have shutdown due to
an error.
fn start_shard(&mut self, shard: u64, shards: u64) -> Result<()>
[src]
Establish a sharded connection and start listening for events.
This will start receiving events and dispatch them to your registered handlers.
This will create a single shard by ID. If using one shard per process, you will need to start other processes with the other shard IDs in some way.
Refer to the Gateway documentation for more information on effectively using sharding.
Examples
Start shard 3 of 5:
struct Handler; impl EventHandler for Handler {} use serenity::client::Client; use std::env; let mut client = Client::new(&env::var("DISCORD_TOKEN")?, Handler); if let Err(why) = client.start_shard(3, 5) { println!("Err with client: {:?}", why); }
Start shard 0 of 1 (you may also be interested in start
or
start_autosharded
):
struct Handler; impl EventHandler for Handler {} use serenity::client::Client; use std::env; let mut client = Client::new(&env::var("DISCORD_TOKEN")?, Handler); if let Err(why) = client.start_shard(0, 1) { println!("Err with client: {:?}", why); }
Errors
Returns a ClientError::Shutdown
when all shards have shutdown due to
an error.
fn start_shards(&mut self, total_shards: u64) -> Result<()>
[src]
Establish sharded connections and start listening for events.
This will start receiving events and dispatch them to your registered handlers.
This will create and handle all shards within this single process. If
you only need to start a single shard within the process, or a range of
shards, use start_shard
or start_shard_range
, respectively.
Refer to the Gateway documentation for more information on effectively using sharding.
Examples
Start all of 8 shards:
struct Handler; impl EventHandler for Handler {} use serenity::client::Client; use std::env; let mut client = Client::new(&env::var("DISCORD_TOKEN")?, Handler); if let Err(why) = client.start_shards(8) { println!("Err with client: {:?}", why); }
Errors
Returns a ClientError::Shutdown
when all shards have shutdown due to
an error.
fn start_shard_range(
&mut self,
range: [u64; 2],
total_shards: u64
) -> Result<()>
[src]
&mut self,
range: [u64; 2],
total_shards: u64
) -> Result<()>
Establish a range of sharded connections and start listening for events.
This will start receiving events and dispatch them to your registered handlers.
This will create and handle all shards within a given range within this
single process. If you only need to start a single shard within the
process, or all shards within the process, use start_shard
or
start_shards
, respectively.
Refer to the Gateway documentation for more information on effectively using sharding.
Examples
For a bot using a total of 10 shards, initialize shards 4 through 7:
struct Handler; impl EventHandler for Handler {} use serenity::Client; use std::env; let token = env::var("DISCORD_TOKEN").unwrap(); let mut client = Client::new(&token, Handler); let _ = client.start_shard_range([4, 7], 10);
struct Handler; impl EventHandler for Handler {} use serenity::client::Client; use std::env; let mut client = Client::new(&env::var("DISCORD_TOKEN")?, Handler); if let Err(why) = client.start_shard_range([4, 7], 10) { println!("Err with client: {:?}", why); }
Errors
Returns a ClientError::Shutdown
when all shards have shutdown due to
an error.
fn close_handle(&self) -> CloseHandle
[src]
Returns a thread-safe handle for closing shards.
Trait Implementations
impl<H: Clone + EventHandler + Send + Sync + 'static> Clone for Client<H>
[src]
fn clone(&self) -> Client<H>
[src]
Returns a copy of the value. Read more
fn clone_from(&mut self, source: &Self)
1.0.0[src]
Performs copy-assignment from source
. Read more