📚 目录

April 8, 2026 · View on GitHub

Logo逃走啦~

OsynicOsuapi

🚀 高性能 · 🏗️ 结构优良 · 🔧 易于扩展
功能完整的 Rust osu! API 客户端库,支持 WASM 和 Native 环境

🇨🇳 中文 · 🇺🇸 English


📚 目录

📄 OSU!API 官方文档

🧻 API体验网站

OSUAPIV1CN.png

网站特色

🌐 在线体验:基于 leptos 框架构建的 osynic_osuapi 在线体验平台

✨ 核心功能

  • 支持 V1 和 V2 API 的 WASM 客户端演示
  • 基于 gloo-net 的网络请求
  • 通过 osynic-cors.deno.dev 代理解决 CORS 跨域问题
  • 多语言支持:中文、英语、日语、韩语、德语、法语、俄语

🚀 部署方式:使用 Deno 部署在 osynic-osuapi.deno.dev

💡 技术说明:由于浏览器 CORS 限制,WASM 客户端需要通过代理服务器来访问 osu! API

✨ 特性

  • 🔄 新旧 API 全支持: 完整支持 V1 所有端点 + V2 大部分端点(除文档未归类接口)
  • 🌐 WASM 兼容性: V1 和 V2 接口均提供 WebAssembly 支持,可直接在网页应用中使用
  • 🏗️ 架构设计优良: 基于 clientinterfacemodel 三层模块设计,易于扩展和维护
  • 📖 完整示例支持: examples 目录提供丰富的示例代码和返回数据,详见 API检查表
  • 🎓 示例驱动学习: 通过查看示例代码或运行 cargo run --example 示例名 快速上手

🚀 快速开始

步骤一:申请 OSU! API 授权

访问您的 osu! 设置页面,在以下位置申请相应的 API 授权:

  • V2 API: 在 "OAuth" 或 "开放授权" 部分申请
  • V1 API: 在 "Legacy API" 或 "旧版本 API" 部分申请

步骤二:配置环境变量

在项目根目录创建 .env 文件:

# V2 API 配置
CLIENT_ID="你的client_id"
CLIENT_SECRET="你的client_secret"
REDIRECT_URI="你的redirect_uri"
CODE="你的code"  # Authorization Code Grant 认证时需要

# V1 API 配置
API_KEY="你的api_key"

步骤三:添加依赖

Cargo.toml 中添加依赖:

[dependencies]
osynic_osuapi = "0.1.11"
dotenvy = "0.15.7"  # 用于读取 .env 文件

# WASM 环境配置(可选)
# osynic_osuapi = { version = "0.1.11", default-features = false, features = ["v1", "v2", "wasm"] }

💡 特性说明

  • 默认特性:["v1", "v2", "not-wasm"](适用于 Native 环境)
  • WASM 环境:需要关闭 not-wasm 并启用 wasm 特性

使用示例

示例一:V2 API - CCG 认证获取用户信息

使用 Client Credentials Grant 认证方式获取 peppy 的用户信息:

// examples/peppy.rs - 可运行 cargo run --example peppy 查看效果
use osynic_osuapi::error::Result;
use osynic_osuapi::v2::client::request::client::OsynicOsuApiV2Client;
use osynic_osuapi::v2::interface::oauth::IOauth;
use osynic_osuapi::v2::interface::users::IUsers;

// 也可以通过 prelude 导入所有客户端和接口模块
// use osynic_osuapi::prelude::*;

#[tokio::main]
async fn main() -> Result<()> {
    dotenvy::dotenv().ok();
    let client_id = std::env::var("CLIENT_ID").expect("CLIENT_ID not set");
    let client_secret = std::env::var("CLIENT_SECRET").expect("CLIENT_SECRET not set");
    
    let client = OsynicOsuApiV2Client::default();
    
    // 获取访问令牌
    let token = client
        .oauth
        .get_token_without_code(client_id.parse()?, &client_secret)
        .await?;
    println!("Token: {:?}", token);

    // 获取用户信息
    let peppy = client
        .users
        .get_user_by_username("peppy", None, None)
        .await?;
    println!("User: {:?}", peppy);

    Ok(())
}

示例二:V1 API - 查询谱面信息

通过谱面哈希值查询谱面详细信息:

// examples/gb.rs - 可运行 cargo run --example gb 查看效果
use osynic_osuapi::error::Result;
use osynic_osuapi::v1::client::request::client::OsynicOsuApiV1Client;
use osynic_osuapi::v1::interface::beatmap::IBeatmap;
use osynic_osuapi::v1::model::beatmap::GetBeatmapsParams;

#[tokio::main]
async fn main() -> Result<()> {
    dotenvy::dotenv().ok();
    let api_key = std::env::var("API_KEY").expect("API_KEY is not set.");
    let client = OsynicOsuApiV1Client::new(api_key);
    
    // 通过哈希值查询谱面
    let params = GetBeatmapsParams::default()
        .hash("69f77b0dfe67d288c1bf748f91ceb133".to_string());

    let beatmaps = client.beatmap.get_beatmaps(params).await?;
    println!("Beatmaps: {:?}", beatmaps);

    Ok(())
}

🎯 更多示例:查看 examples/ 目录获取完整示例,或运行 cargo run --example 示例名 查看实际效果。

🍕 API检查表

可通过 cargo run --example 示例名 来运行API对应示例

V1

本条目基于V1官方文档的API大类进行划分,分类如下

其中接口模块对应可以在 src/v1/interface 中找到,相应实现则在 src/v1/client/request/api 或者 src/v1/client/gloo/api 中可以找到

API支持备注示例名模块名
/get_beatmaps获取谱面gbbeatmap
/get_user获取用户guuser
/get_user_best获取用户最佳成绩gubuser
/get_user_recent获取用户最近成绩guruser
/get_match获取比赛gmmultiplayer
/get_scores获取谱面成绩gssscores
/get_replay获取回放grreplay

V2

本条目基于V2官方文档的API大类进行划分,分类如下

其中接口模块对应可以在 src/v2/interface 中找到,相应实现则在 src/v2/client/request/api 中可以找到,示例代码和相应数据在 src/v2/examples 中可以找到

大类API总数API支持数备注模块名
Authentication44 ✅OAuth与认证oauth
Beatmaps1010 ✅谱面APIbeatmaps
Beatmapsets72 ⚠️403 Forbidden谱面集APIbeatmapsets
Changelog33 ✅变更日志APIchangelog
Chat110 ❌403 Forbidden聊天APIchat
Comments72 ⚠️403 Forbidden评论APIcomments
Events11 ✅事件APIevents
Forum84 ⚠️403 Forbidden论坛APIforum
Home11 ✅首页APIsearch
Matches12 ✅比赛APImatches
Multiplayer42 ⚠️403 Forbidden多人APImultiplayer
News22 ✅新闻APInews
Notifications20 ❌403 Forbidden通知APInotifications
Rankings33 ✅排行榜APIrankings
Scores11 ✅成绩APIscores
Users77 ✅用户APIusers
Wiki11 ✅Wiki APIwiki
Friends22 ✅好友APIfriends

Authentication

API支持备注示例名
/get_token_with_code即Authorization Code Grant的缩写,需要用户在浏览器OAuth授权来拿到code,进而来请求token,不需要client_secretacg
/get_token_without_code即Client Credentials Grant的缩写,直接请求token,不需要用户授权,client_secret需要在环境变量中设置ccg
/refresh_tokenCCG认证下,通过拿到的refresh_token刷新tokenrefresh
/revoke_current_token撤销当前tokenrevoke

Beatmaps

API支持备注示例名
/get_beatmap_packs获取多个谱面包bpsg
/get_beatmap_pack获取谱面包bpg
/lookup_beatmap查阅谱面bl
/get_beatmap获取谱面bg
/get_beatmap_attributes获取谱面属性bga
/get_beatmaps获取多个谱面bgs
/get_scores获取谱面成绩bgss
/get_solo_scores获取谱面成绩(Legacy)bgssn
/get_user_score获取用户成绩bgus
/get_user_scores获取用户多个成绩bguss

Beatmapsets

API支持备注示例名
/get_beatmapsets_discussions_posts🈳(不稳定接口)获取铺面集讨论区发布bsdpg
/get_beatmapsets_discussions_vote🈳(不稳定接口)获取铺面集讨论区投票bsdvg
/get_beatmapsets_discussions🈳(不稳定接口)获取铺面集讨论区bsdg
/search搜索谱面集bss
/lookup🈳(文档不明)查阅谱面集bsl
/get_beatmapset获取谱面集bsg
/download下载谱面集(lazer)bsd

Changelog

API支持备注示例名
/get_changelog_build获取变更日志cbg
/get_changelog_listing获取变更日志列表clg
/lookup_changelog_build查阅变更日志cbl

Chat

API支持备注示例名
/chat_keepalive❌403 Forbidden保持连接chk
/create_new_pm❌403 Forbidden创建新私信chpc
/get_updates❌403 Forbidden获取更新chug
/get_channel_messages❌403 Forbidden获取频道消息chmg
/send_message_to_channel❌403 Forbidden发送消息chms
/join_channel❌403 Forbidden加入频道chj
/leave_channel❌403 Forbidden离开频道chl
/mark_channel_as_read❌403 Forbidden标记频道已读chmr
/get_channel_list❌403 Forbidden获取频道列表chlg
/create_channel❌403 Forbidden创建频道chc
/get_channel❌403 Forbidden获取频道chg

Comments

API支持备注示例名
/get_comments获取多条评论csg
/post_comment❌403 Forbidden发送评论cp
/get_comment获取评论cg
/edit_comment❌403 Forbidden编辑评论ce
/delete_comment❌403 Forbidden删除评论cd
/add_comment_vote❌403 Forbidden投票cva
/remove_comment_vote❌403 Forbidden撤销投票cvr

Events

API支持备注示例名
/get_events获取事件events

Forum

API支持备注示例名
/reply_topic❌401 Unauthorized回帖ftr
/get_topics_listing获取主题列表ftlg
/create_topic❌401 Unauthorized创建主题ftc
/get_topic_and_posts获取主题及其帖子ftpg
/edit_topic❌403 Forbidden编辑主题fte
/edit_post❌403 Forbidden编辑帖子fpe
/get_forum_listing获取论坛列表flg
/get_forum_and_topic获取论坛及其主题ftg

Home

API支持备注示例名
/search获取首页search

Matches

API支持备注示例名
/get_matches_listing获取比赛列表mlg
/get_match获取比赛mg

Multiplayer

API支持备注示例名
/get_user_high_score❌403 Forbidden获取用户高分muhsg
/get_scores获取多个分数mssg
/get_score❌403 Forbidden获取分数msg
/get_multiplayer_rooms获取房间mrg

News

API支持备注示例名
/get_news_listing获取新闻列表nlg
/get_news_post获取新闻npg

Notifications

API支持备注示例名
/get_notifications❌403 Forbidden获取通知ng
/mark_notifications_as_read❌403 Forbidden标为已读nm

Rankings

API支持备注示例名
/get_ranking获取排行榜rg
/get_kudosu_ranking获取Kudosu排行榜rkg
/get_spotlights获取聚光灯rsg

Scores

API支持备注示例名
/get_scores获取最多1000个成绩scores

Users

API支持备注示例名
/get_own_data获取自己的用户信息(CCG)me
/get_user_kudosu获取用户Kudosuukg
/get_user_scores获取用户分数ussg
/get_user_beatmaps, /get_user_beatmaps_most_played获取用户谱面信息ubsg
/get_user_recent_activity获取用户最近活动urag
/get_user, /get_user_by_username获取用户信息ug
/get_users获取多个用户信息usg

Wiki

API支持备注示例名
/get_wiki_page获取Wiki页面wiki

Friends

API支持备注示例名
/get_friends获取好友列表fg
/get_friends_x_api_version获取好友列表(指定API版本)fgx

❤️ 鸣谢

最开始项目本来是打算直接用rosu-v2这个库的,但是由于当时看到rosu-v2已经就大几个月没更新了,并且项目组织和使用方式也不太习惯(可能是rosu-v2至今已经有四年历史的缘故,库里面有很多早期Rust代码,也不是很方便直接修改),所以就另起炉灶决定自己写一个了;

osynic_osuapi的开发过程中,还是参考了rosu-v2的接口设计(但并未沿用)和部分类型(比如u64和u32的选取),感谢rosu-v2的作者们!

rosu-v2项目基于MIT License,项目证书放置在licenses/LICENSE-rosu-v2

⚠️ 特别注意

使用本库时,最常见的问题来源于 osu! API 官方实体结构的变动:

常见问题类型

  • 🔄 实体结构变动:osu! API 的结构可能随时变化,官方文档更新可能不及时
  • 📝 返回字段变动:某些接口的返回字段可能发生变化,尤其是较少使用的端点
  • ❓ 异常空值:某些字段可能在特定情况下返回 null,但文档中未标明为可选

问题反馈

如果您在使用过程中遇到解析错误或类型不匹配等问题,请直接提交 Issue 并附上:

  1. 使用的 API 端点
  2. 请求参数
  3. 错误信息或异常堆栈

我会尽快处理并更新库以适应 API 的变化。本库的大部分模型都是基于实际请求返回结果构建的,但仍可能存在遗漏或错误。您的反馈对完善本库至关重要!

🤝 贡献指南

项目概述

本库主要为 Osynic 应用开发,同时也是一个功能完整的 osu! API Rust 封装库。

当前状态

已完成

  • V1 和 V2 大部分 API 接口(除文档未归类的接口)
  • V1 和 V2 的 WASM 支持

⚠️ 开发中:可能存在 bug 或不完善的地方

如何贡献

欢迎提交 PR 或 Issue!如果您发现任何问题或有改进建议,请遵循以下规则:

代码贡献规范

  • 编码规范:遵循 Rust 官方编码规范
  • 测试要求:新增功能需附带测试用例
  • 代码质量:提交前运行 cargo fmtcargo clippy
  • 文档更新:必要时更新相关文档和示例

Issue 提交指南

  • 描述问题的具体场景
  • 提供复现步骤和错误信息
  • 附上相关的 API 端点和参数信息

📜 开源协议

本项目基于 MIT License 开源,请尊重原作者的著作权。