Rust Library
The community-maintained Rust library for Top.gg. If you experience any issues, please submit an issue on GitHub.
Installation
Make sure to have a Top.gg API token handy, you can have an API token if you own a listed Discord bot on Top.gg (open the edit page, see in Webhooks section) then add the following to your Cargo.toml's dependencies:
topgg = "1.0"
Features
This library provides several feature flags that can be enabled/disabled in Cargo.toml. Such as:
api: Interacting with the Top.gg API and accessing thetop.gg/api/*endpoints. (enabled by default)autoposter: Automating the process of periodically posting bot statistics to the Top.gg API.
webhook: Accessing theserdedeserializabletopgg::Votestruct.
Examples
More things can be found in the documentation.
Fetching a single Discord user from it's Discord ID
use topgg::Client;
#[tokio::main]
async fn main() {
let token = env!("TOPGG_TOKEN").to_owned();
let client = Client::new(token);
let user = client.get_user(661200758510977084u64).await.unwrap();
assert_eq!(user.username, "null");
assert_eq!(user.discriminator, "8626");
assert_eq!(user.id, 661200758510977084u64);
println!("{:?}", user);
}
Fetching a single Discord bot from it's Discord ID
use topgg::Client;
#[tokio::main]
async fn main() {
let token = env!("TOPGG_TOKEN").to_owned();
let client = Client::new(token);
let bot = client.get_bot(264811613708746752u64).await.unwrap();
assert_eq!(bot.username, "Luca");
assert_eq!(bot.discriminator, "1375");
assert_eq!(bot.id, 264811613708746752u64);
println!("{:?}", bot);
}
Querying several Discord bots
use topgg::{Client, Filter, Query};
#[tokio::main]
async fn main() {
let token = env!("TOPGG_TOKEN").to_owned();
let client = Client::new(token);
// inputting a string searches a bot that matches that username
for bot in client.get_bots("shiro").await.unwrap() {
println!("{:?}", bot);
}
// advanced query with filters
let filter = Filter::new()
.username("shiro")
.certified(true);
let query = Query::new()
.limit(250)
.skip(50)
.filter(filter);
for bot in client.get_bots(query).await.unwrap() {
println!("{:?}", bot);
}
}
Posting your Discord bot's statistics
use topgg::{Client, NewStats};
#[tokio::main]
async fn main() {
let token = env!("TOPGG_TOKEN").to_owned();
let client = Client::new(token);
let server_count = 1234; // be TRUTHFUL!
let shard_count = 10;
let stats = NewStats::count_based(server_count, Some(shard_count));
client.post_stats(stats).await.unwrap();
}
Checking if a user has voted for your Discord bot
use topgg::Client;
#[tokio::main]
async fn main() {
let token = env!("TOPGG_TOKEN").to_owned();
let client = Client::new(token);
if client.has_voted(661200758510977084u64).await.unwrap() {
println!("checks out");
}
}
Automating the process of periodically posting your Discord bot's statistics
In your Cargo.toml:
[dependencies]
topgg = { version = "1.0", features = ["autoposter"] }
In your code:
use topgg::{Autoposter, Client, NewStats};
#[tokio::main]
async fn main() {
let token = env!("TOPGG_TOKEN").to_owned();
let client = Client::new(token);
// make sure to make this autoposter instance live
// throughout most of the bot's lifetime to keep running!
let autoposter = client.new_autoposter(1800);
// ... then in some on ready/new guild event ...
let server_count = 12345;
let stats = NewStats::count_based(server_count, None);
autoposter.feed(stats).await;
}
Writing an actix-web webhook for listening to your bot/server's vote events
In your Cargo.toml:
[dependencies]
topgg = { version = "1.0", default-features = false, features = ["actix"] }
In your code:
use actix_web::{post, App, HttpServer, Responder};
use std::io;
#[post("/dblwebhook")]
async fn webhook(vote: topgg::IncomingVote) -> impl Responder {
match vote.authenticate(env!("TOPGG_WEBHOOK_PASSWORD")) {
Some(vote) => /* your application logic here... */,
_ => /* handle 401 here... */,
}
}
#[tokio::main]
async fn main() -> io::Result<()> {
HttpServer::new(|| {
App::new().service(webhook)
})
.bind(("127.0.0.1", 8080))?
.run()
.await
}
Writing an axum webhook for listening to your bot/server's vote events
In your Cargo.toml:
[dependencies]
topgg = { version = "1.0", default-features = false, features = ["axum"] }
In your code:
use axum::{Router, Server};
use std::net::SocketAddr;
struct MyVoteHandler {}
#[async_trait::async_trait]
impl topgg::VoteHandler for MyVoteHandler {
async fn voted(&self, vote: topgg::Vote) {
// your application logic here
}
}
#[tokio::main]
async fn main() {
let password = env!("TOPGG_WEBHOOK_PASSWORD").to_owned();
let state = MyVoteHandler {};
let app = Router::new()
.nest("/dblwebhook", topgg::axum::webhook(password, state));
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
Server::bind(&addr)
.serve(app.into_make_service())
.await
.unwrap();
}
Writing a rocket webhook for listening to your bot/server's vote events
In your Cargo.toml:
[dependencies]
topgg = { version = "1.0", default-features = false, features = ["rocket"] }
In your code:
#![feature(proc_macro_hygiene, decl_macro)]
#[macro_use]
extern crate rocket;
use rocket::http::Status;
#[post("/", data = "<vote>")]
fn webhook(vote: topgg::IncomingVote) -> Status {
match vote.authenticate(env!("TOPGG_WEBHOOK_PASSWORD")) {
Some(vote) => /* your application logic here... */,
_ => /* handle 401 here... */,
}
}
fn main() {
rocket::ignite()
.mount("/dblwebhook", routes![webhook])
.launch();
}
Writing a warp webhook for listening to your bot/server's vote events
In your Cargo.toml:
[dependencies]
topgg = { version = "1.0", default-features = false, features = ["warp"] }
In your code:
struct MyVoteHandler {}
#[async_trait::async_trait]
impl topgg::VoteHandler for MyVoteHandler {
async fn voted(&self, vote: topgg::Vote) {
// your application logic here
}
}
#[tokio::main]
async fn main() {
let password = env!("TOPGG_WEBHOOK_PASSWORD").to_owned();
let state = MyVoteHandler {};
// POST /dblwebhook
let webhook = topgg::warp::webhook("dblwebhook", password, state);
let routes = warp::post().and(webhook);
warp::serve(routes).run(([127, 0, 0, 1], 3030)).await;
}

