Skip to content

Instantly share code, notes, and snippets.

@Erk-
Created April 2, 2024 16:46
Show Gist options
  • Save Erk-/543cf55b3f87686dc717ab41ea5bde9e to your computer and use it in GitHub Desktop.
Save Erk-/543cf55b3f87686dc717ab41ea5bde9e to your computer and use it in GitHub Desktop.
[package]
name = "ping_bot"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
tokio = { version = "1.29.1", features = ["full"] }
twilight-gateway = { version = "=0.16.0-rc.1" }
twilight-http = { version = "=0.16.0-rc.1" }
twilight-model = { version = "=0.16.0-rc.1" }
tracing = "0.1.40"
tracing-subscriber = "0.3.18"
use std::{boxed::Box, sync::Arc};
use twilight_gateway::{
self, create_recommended, Config, ConfigBuilder, EventTypeFlags, Shard, StreamExt as _,
};
use twilight_http::Client as HttpClient;
use twilight_model::gateway::{event::Event, Intents};
use tokio::task::JoinSet;
use tracing::{info, warn};
const EVENT_FLAGS: EventTypeFlags =
EventTypeFlags::union(EventTypeFlags::READY, EventTypeFlags::MESSAGE_CREATE);
#[derive(Clone)]
struct Context {
http: Arc<HttpClient>,
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
tracing_subscriber::fmt::init();
let token = std::env::var("DISCORD_TOKEN")?;
let http = Arc::new(HttpClient::new(token.clone()));
let intents = Intents::all();
let config = Config::new(token.clone(), intents);
let config_callback = |_, builder: ConfigBuilder| builder.build();
let shards = create_recommended(&http, config, config_callback).await?;
println!("total shards: {}", shards.len());
let ctx = Context { http };
let mut set = JoinSet::new();
for shard in shards {
set.spawn(runner(shard, ctx.clone()));
}
set.join_next().await;
println!("closing down!");
Ok(())
}
async fn runner(mut shard: Shard, ctx: Context) {
while let Some(item) = shard.next_event(EVENT_FLAGS).await {
let event = match item {
Ok(event) => event,
Err(source) => {
warn!(?source, "error receiving event");
continue;
}
};
tokio::spawn({
let ctx = ctx.clone();
async move {
handle_event(event, ctx).await;
}
});
}
}
async fn handle_event(event: Event, ctx: Context) {
match event {
Event::Ready(ready) => {
info!("In {} guilds!", ready.guilds.len());
}
Event::MessageCreate(msg) => {
if msg.content == "!ping" {
if let Err(why) = ctx.http.create_message(msg.channel_id).content("pong!").await {
warn!("{}", why);
}
}
}
_ => (),
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment