15个稳定版本

1.4.2 2024年8月2日
1.4.1 2024年3月27日
1.3.1 2024年1月8日
1.2.1 2023年12月17日
1.0.4 2023年4月26日

#47 in HTTP客户端

Download history 2/week @ 2024-05-24 2/week @ 2024-05-31 1/week @ 2024-06-14 9/week @ 2024-06-28 83/week @ 2024-07-05 65/week @ 2024-07-26 125/week @ 2024-08-02 1/week @ 2024-08-09

每月191次下载
用于 natsuki

MIT 许可证

76KB
1.5K SLoC

topgg crates.io crates.io downloads

Top.gg API的官方Rust SDK。

入门指南

请确保您有 Top.gg API 令牌。如果没有,请查看如何获取令牌的教程。之后,将以下行添加到您的 Cargo.toml 文件的 dependencies 部分

topgg = "1.4"

有关更多信息,请参阅文档

功能

此库提供了一些功能标志,可以在 Cargo.toml 中启用/禁用。例如

  • api:与 Top.gg API 交互并访问 top.gg/api/* 端点。(默认启用)
    • autoposter:自动化定期将机器人统计信息发布到 Top.gg API 的过程。
  • webhook:访问 serde可反序列化topgg::Vote 结构体。
    • actix-web:用于处理 actix-web 网络框架的包装器。
    • axum:用于处理 axum 网络框架的包装器。
    • rocket:用于处理 rocket 网络框架的包装器。
    • warp:用于与 warp 网络框架一起工作的包装器。
  • serenity:用于与 serenity 库一起工作的额外辅助工具(禁用机器人缓存)。
    • serenity-cached:用于与 serenity 库一起工作的额外辅助工具(启用机器人缓存)。
  • twilight:用于与 twilight 库一起工作的额外辅助工具(禁用机器人缓存)。
    • twilight-cached:用于与 twilight 库一起工作的额外辅助工具(启用机器人缓存)。

示例

通过 Discord ID 获取用户

use topgg::Client;

#[tokio::main]
async fn main() {
  let client = Client::new(env!("TOPGG_TOKEN").to_string());
  let user = client.get_user(661200758510977084).await.unwrap();
  
  assert_eq!(user.username, "null");
  assert_eq!(user.id, 661200758510977084);
  
  println!("{:?}", user);
}

发布您的机器人统计数据

use topgg::{Client, Stats};

#[tokio::main]
async fn main() {
  let client = Client::new(env!("TOPGG_TOKEN").to_string());

  let server_count = 12345;
  client
    .post_stats(Stats::from(server_count))
    .await
    .unwrap();
}

检查用户是否为您的机器人投票

use topgg::Client;

#[tokio::main]
async fn main() {
  let client = Client::new(env!("TOPGG_TOKEN").to_string());

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

使用 serenity 进行自动发布

在您的 Cargo.toml

[dependencies]
# using serenity with guild caching disabled
topgg = { version = "1.4", features = ["autoposter", "serenity"] }

# using serenity with guild caching enabled
topgg = { version = "1.4", features = ["autoposter", "serenity-cached"] }

在您的代码中

use core::time::Duration;
use serenity::{client::{Client, Context, EventHandler}, model::{channel::Message, gateway::Ready}};
use topgg::Autoposter;

struct Handler;

#[serenity::async_trait]
impl EventHandler for Handler {
  async fn message(&self, ctx: Context, msg: Message) {
    if msg.content == "!ping" {
      if let Err(why) = msg.channel_id.say(&ctx.http, "Pong!").await {
        println!("Error sending message: {why:?}");
      }
    }
  }

  async fn ready(&self, _: Context, ready: Ready) {
    println!("{} is connected!", ready.user.name);
  }
}

#[tokio::main]
async fn main() {
  let topgg_client = topgg::Client::new(env!("TOPGG_TOKEN").to_string());
  let autoposter = Autoposter::serenity(&topgg_client, Duration::from_secs(1800));
  
  let bot_token = env!("DISCORD_TOKEN").to_string();
  let intents = GatewayIntents::GUILD_MESSAGES | GatewayIntents::GUILDS | GatewayIntents::MESSAGE_CONTENT;

  let mut client = Client::builder(&bot_token, intents)
    .event_handler(Handler)
    .event_handler_arc(autoposter.handler())
    .await
    .unwrap();

  if let Err(why) = client.start().await {
    println!("Client error: {why:?}");
  }
}

使用 twilight 进行自动发布

在您的 Cargo.toml

[dependencies]
# using twilight with guild caching disabled
topgg = { version = "1.4", features = ["autoposter", "twilight"] }

# using twilight with guild caching enabled
topgg = { version = "1.4", features = ["autoposter", "twilight-cached"] }

在您的代码中

use core::time::Duration;
use topgg::Autoposter;
use twilight_gateway::{Event, Intents, Shard, ShardId};

#[tokio::main]
async fn main() {
  let client = topgg::Client::new(env!("TOPGG_TOKEN").to_string());
  let autoposter = Autoposter::twilight(&client, Duration::from_secs(1800));

  let mut shard = Shard::new(
    ShardId::ONE,
    env!("DISCORD_TOKEN").to_string(),
    Intents::GUILD_MEMBERS | Intents::GUILDS,
  );

  loop {
    let event = match shard.next_event().await {
      Ok(event) => event,
      Err(source) => {
        if source.is_fatal() {
          break;
        }

        continue;
      }
    };
    
    autoposter.handle(&event).await;
    
    match event {
      Event::Ready(_) => {
        println!("Bot is ready!");
      },

      _ => {}
    }
  }
}

编写用于监听投票的 actix-web webhook

在您的 Cargo.toml

[dependencies]
topgg = { version = "1.4", default-features = false, features = ["actix-web"] }

在您的代码中

use actix_web::{
  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!("TOPGG_WEBHOOK_PASSWORD")) {
    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 webhook

在您的 Cargo.toml

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

在您的代码中

use axum::{routing::get, Router, Server};
use std::{net::SocketAddr, sync::Arc};
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 state = Arc::new(MyVoteHandler {});

  let app = Router::new().route("/", get(index)).nest(
    "/webhook",
    topgg::axum::webhook(env!("TOPGG_WEBHOOK_PASSWORD").to_string(), Arc::clone(&state)),
  );

  let addr: SocketAddr = "127.0.0.1:8080".parse().unwrap();

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

编写用于监听投票的 rocket webhook

在您的 Cargo.toml

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

在您的代码中

#![feature(decl_macro)]

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

#[get("/")]
fn index() -> &'static str {
  "Hello, World!"
}

#[post("/webhook", data = "<vote>")]
fn webhook(vote: IncomingVote) -> Status {
  match vote.authenticate(env!("TOPGG_WEBHOOK_PASSWORD")) {
    Some(vote) => {
      println!("{:?}", vote);

      Status::Ok
    },
    _ => {
      println!("found an unauthorized attacker.");

      Status::Unauthorized
    }
  }
}

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

编写用于监听投票的 warp webhook

在您的 Cargo.toml

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

在您的代码中

use std::{net::SocketAddr, sync::Arc};
use topgg::{Vote, VoteHandler};
use warp::Filter;

struct MyVoteHandler {}

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

#[tokio::main]
async fn main() {
  let state = Arc::new(MyVoteHandler {});

  // POST /webhook
  let webhook = topgg::warp::webhook(
    "webhook",
    env!("TOPGG_WEBHOOK_PASSWORD").to_string(),
    Arc::clone(&state),
  );

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

  let addr: SocketAddr = "127.0.0.1:8080".parse().unwrap();

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

依赖项

~0.4–36MB
~573K SLoC