topgg crates.io crates.io downloads license BLAZINGLY FAST!!!

The official Rust SDK for the Top.gg API.

Getting Started

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:

toml topgg = "1.1"

Features

This library provides several feature flags that can be enabled/disabled in Cargo.toml. Such as:

Examples

More things can be read in the documentation.

api: Fetching a single Discord user from it's Discord ID

```rust,no_run use topgg::Client;

[tokio::main]

async fn main() { let client = Client::new(env!("TOPGG_TOKEN"));

let user = client.get_user(661200758510977084).await.unwrap();

asserteq!(user.username, "null"); asserteq!(user.id, 661200758510977084);

println!("{:?}", user); } ```

api: Fetching a single Discord bot from it's Discord ID

```rust,no_run use topgg::Client;

[tokio::main]

async fn main() { let client = Client::new(env!("TOPGG_TOKEN"));

let bot = client.get_bot(264811613708746752).await.unwrap();

asserteq!(bot.username, "Luca"); asserteq!(bot.id, 264811613708746752);

println!("{:?}", bot); } ```

api: Querying several Discord bots

```rust,no_run use topgg::{Client, Filter, Query};

[tokio::main]

async fn main() { let client = Client::new(env!("TOPGG_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); } } ```

api: Posting your Discord bot's statistics

```rust,no_run use topgg::{Client, NewStats};

[tokio::main]

async fn main() { let client = Client::new(env!("TOPGG_TOKEN"));

let servercount = 1234; // be TRUTHFUL! let shardcount = 10;

let stats = NewStats::countbased(servercount, Some(shard_count));

client.post_stats(stats).await.unwrap(); } ```

api: Checking if a user has voted for your Discord bot

```rust,no_run use topgg::Client;

[tokio::main]

async fn main() { let client = Client::new(env!("TOPGG_TOKEN"));

if client.has_voted(661200758510977084).await.unwrap() { println!("checks out"); } } ```

autoposter: Automating the process of periodically posting your Discord bot's statistics

In your Cargo.toml:

toml [dependencies] topgg = { version = "1.1", features = ["autoposter"] }

In your code:

```rust,no_run use core::time::Duration; use topgg::{Autoposter, Client, NewStats};

[tokio::main]

async fn main() { let client = Client::new(env!("TOPGG_TOKEN"));

// creates an autoposter that posts data to Top.gg every 1800 seconds (15 minutes). // the autopost thread will stop once it's dropped. let autoposter = client.newautoposter(Duration::fromsecs(1800));

// ... then in some on ready/new guild event ... let servercount = 12345; let stats = NewStats::countbased(server_count, None); autoposter.feed(stats).await; } ```

actix: Writing an actix-web webhook for listening to your bot/server's vote events

In your Cargo.toml:

toml [dependencies] topgg = { version = "1.1", default-features = false, features = ["actix"] }

In your code:

```rust,norun use actixweb::{ error::{Error, ErrorUnauthorized}, get, post, App, HttpServer, }; use std::io; use topgg::IncomingVote;

[get("/")]

async fn index() -> &'static str { "Hello, World!" }

[post("/webhook")]

async fn webhook(vote: IncomingVote) -> Result<&'static str, Error> { match vote.authenticate(env!("TOPGGWEBHOOKPASSWORD")) { Some(vote) => { println!("{:?}", vote);

  Ok("ok")
},
_ => Err(ErrorUnauthorized("401")),

} }

[actix_web::main]

async fn main() -> io::Result<()> { HttpServer::new(|| App::new().service(index).service(webhook)) .bind("127.0.0.1:8080")? .run() .await } ```

axum: Writing an axum webhook for listening to your bot/server's vote events

In your Cargo.toml:

toml [dependencies] topgg = { version = "1.1", default-features = false, features = ["axum"] }

In your code:

```rust,no_run use axum::{routing::get, Router, Server}; use topgg::{Vote, VoteHandler};

struct MyVoteHandler {}

[axum::async_trait]

impl VoteHandler for MyVoteHandler { async fn voted(&self, vote: Vote) { println!("{:?}", vote); } }

async fn index() -> &'static str { "Hello, World!" }

[tokio::main]

async fn main() { let password = env!("TOPGGWEBHOOKPASSWORD").to_owned(); let state = MyVoteHandler {};

let app = Router::new() .route("/", get(index)) .nest("/webhook", topgg::axum::webhook(password, state));

// this will always be a valid SocketAddr syntax, // therefore we can safely unwrapunchecked this. let addr = unsafe { "127.0.0.1:8080".parse().unwrapunchecked() };

Server::bind(&addr) .serve(app.intomakeservice()) .await .unwrap(); } ```

rocket: Writing a rocket webhook for listening to your bot/server's vote events

In your Cargo.toml:

toml [dependencies] topgg = { version = "1.1", default-features = false, features = ["rocket"] }

In your code:

```rust,no_run

![feature(decl_macro)]

use rocket::{get, http::Status, post, routes}; use topgg::IncomingVote;

[get("/")]

fn index() -> &'static str { "Hello, World!" }

[post("/webhook", data = "")]

fn webhook(vote: IncomingVote) -> Status { match vote.authenticate(env!("TOPGGWEBHOOKPASSWORD")) { Some(vote) => { println!("{:?}", vote);

  // 200 and 401 will always be a valid status code,
  // therefore we can safely unwrap_unchecked these.
  unsafe { Status::from_code(200).unwrap_unchecked() }
},
_ => {
  println!("found an unauthorized attacker.");

  unsafe { Status::from_code(401).unwrap_unchecked() }
},

} }

fn main() { rocket::ignite() .mount("/", routes![index, webhook]) .launch(); } ```

warp: Writing a warp webhook for listening to your bot/server's vote events

In your Cargo.toml:

toml [dependencies] topgg = { version = "1.1", default-features = false, features = ["warp"] }

In your code:

```rust,no_run use std::net::SocketAddr; use topgg::{Vote, VoteHandler}; use warp::Filter;

struct MyVoteHandler {}

[asynctrait::asynctrait]

impl VoteHandler for MyVoteHandler { async fn voted(&self, vote: Vote) { println!("{:?}", vote); } }

[tokio::main]

async fn main() { let password = env!("TOPGGWEBHOOKPASSWORD").to_owned(); let state = MyVoteHandler {};

// POST /webhook let webhook = topgg::warp::webhook("webhook", password, state);

let routes = warp::get() .map(|| "Hello, World!") .or(webhook);

// this will always be a valid SocketAddr syntax, // therefore we can safely unwrapunchecked this. let addr: SocketAddr = unsafe { "127.0.0.1:8080".parse().unwrapunchecked() };

warp::serve(routes) .run(addr) .await } ```